You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2014/07/07 20:08:05 UTC

[01/19] Move mobilespec into www/ so as to not include non-app files in the app

Repository: cordova-mobile-spec
Updated Branches:
  refs/heads/master e2ddbd366 -> 77ff9a37d


http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/misc/page3A.js
----------------------------------------------------------------------
diff --git a/www/misc/page3A.js b/www/misc/page3A.js
new file mode 100644
index 0000000..8efad58
--- /dev/null
+++ b/www/misc/page3A.js
@@ -0,0 +1,27 @@
+console.log('Changing hash #1.');
+if (location.search.indexOf('hash1') != -1) {
+  location.hash = 'a';
+} else if (location.search.indexOf('hash2') != -1) {
+  location.replace('#replaced');
+}
+var hashCount = 0;
+function changeHash() {
+  hashCount += 1;
+  if (hashCount % 1) {
+    location.hash = hashCount;
+  } else {
+    location.replace('#' + hashCount);
+  }
+}
+if (location.search.indexOf('changeURL') != -1) {
+  history.replaceState(null, null, 'fakepage.html');
+}
+function loadFrame() {
+  var ifr = document.createElement('iframe');
+  ifr.src="data:text/html;base64,PGh0bWw+";
+  document.body.appendChild(ifr);
+}
+function reload() {
+  // Test that iOS CDVWebViewDelegate doesn't ignore changes when URL doesn't change.
+  location.reload();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/network/index.html
----------------------------------------------------------------------
diff --git a/www/network/index.html b/www/network/index.html
new file mode 100644
index 0000000..b750f6c
--- /dev/null
+++ b/www/network/index.html
@@ -0,0 +1,48 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+</script>
+
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Network Events and State</h1>
+    <div id="info">
+        <b>Results:</b><br>
+        <span id="results"></span>
+    </div>
+
+    <h2>Action</h2>
+    <div class="btn large printNetwork">Show Network Connection</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/network/index.js
----------------------------------------------------------------------
diff --git a/www/network/index.js b/www/network/index.js
new file mode 100644
index 0000000..41c2c47
--- /dev/null
+++ b/www/network/index.js
@@ -0,0 +1,38 @@
+function eventOutput(s) {
+    var el = document.getElementById("results");
+    el.innerHTML = el.innerHTML + s + "<br>";
+}
+
+function printNetwork() {
+    eventOutput("navigator.connection.type=" + navigator.connection.type);
+    eventOutput("navigator.network.connection.type=" + navigator.network.connection.type);
+}
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    var deviceReady = false;
+    function onEvent(e) {
+        eventOutput('Event of type: ' + e.type);
+        printNetwork();
+    }
+    document.addEventListener('online', onEvent, false);
+    document.addEventListener('offline', onEvent, false);
+    document.addEventListener("deviceready", function() {
+        deviceReady = true;
+        eventOutput("Device="+device.platform+" "+device.version);
+        printNetwork();
+    }, false);
+    window.setTimeout(function() {
+        if (!deviceReady) {
+            alert("Error: Cordova did not initialize.  Demo will not run correctly.");
+        }
+    }, 1000);
+}
+
+window.onload = function() {
+  addListenerToClass('printNetwork', printNetwork);
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/notification/index.html
----------------------------------------------------------------------
diff --git a/www/notification/index.html b/www/notification/index.html
new file mode 100644
index 0000000..ab648df
--- /dev/null
+++ b/www/notification/index.html
@@ -0,0 +1,51 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Notifications and Dialogs</h1>
+    <div id="info">
+    </div>
+    
+    <h2>Action</h2>
+    <div class="btn large beep">Beep</div>
+    <div class="btn large alertDialog">Alert Dialog</div>
+    <div class="btn large confirmDialogA">Confirm Dialog - Deprecated</div>
+    <div class="btn large confirmDialogB">Confirm Dialog</div>
+    <div class="btn large promptDialog">Prompt Dialog</div>
+    
+    <div class="btn large builtInAlert">Built-in Alert Dialog</div>
+    <div class="btn large builtInConfirm">Built-in Confirm Dialog</div>
+    <div class="btn large builtInPrompt">Built-in Prompt Dialog</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/notification/index.js
----------------------------------------------------------------------
diff --git a/www/notification/index.js b/www/notification/index.js
new file mode 100644
index 0000000..12e672f
--- /dev/null
+++ b/www/notification/index.js
@@ -0,0 +1,100 @@
+var deviceReady = false;
+
+//-------------------------------------------------------------------------
+// Notifications
+//-------------------------------------------------------------------------
+
+var beep = function(){
+    navigator.notification.beep(3);
+};
+
+var alertDialog = function(message, title, button) {
+    console.log("alertDialog()");
+    navigator.notification.alert(message,
+        function(){
+            console.log("Alert dismissed.");
+        },
+        title, button);
+    console.log("After alert");
+};
+
+var confirmDialogA = function(message, title, buttons) {
+    navigator.notification.confirm(message,
+        function(r) {
+            if(r===0){
+                console.log("Dismissed dialog without making a selection.");
+                alert("Dismissed dialog without making a selection.");
+            }else{
+                console.log("You selected " + r);
+                alert("You selected " + (buttons.split(","))[r-1]);
+            }
+        },
+        title,
+        buttons);
+};
+
+var confirmDialogB = function(message, title, buttons) {
+    navigator.notification.confirm(message,
+        function(r) {
+            if(r===0){
+                console.log("Dismissed dialog without making a selection.");
+                alert("Dismissed dialog without making a selection.");
+            }else{
+                console.log("You selected " + r);
+                alert("You selected " + buttons[r-1]);
+            }
+        },
+        title,
+        buttons);
+};
+
+var promptDialog = function(message, title, buttons) {
+    navigator.notification.prompt(message,
+        function(r) {
+            if(r && r.buttonIndex===0){
+                var msg = "Dismissed dialog";
+                if( r.input1 ){
+                    msg+=" with input: " + r.input1
+                }
+                console.log(msg);
+                alert(msg);
+            }else{
+                console.log("You selected " + r.buttonIndex + " and entered: " + r.input1);
+                alert("You selected " + buttons[r.buttonIndex-1] + " and entered: " + r.input1);
+            }
+        },
+        title,
+        buttons);
+};
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+        if (!deviceReady) {
+            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+        }
+    },1000);
+}
+
+window.onload = function() {
+  addListenerToClass('beep', beep);
+  addListenerToClass('alertDialog', alertDialog, 
+      ['You pressed alert.', 'Alert Dialog', 'Continue']);
+  addListenerToClass('confirmDialogA', confirmDialogA, 
+      ['You pressed confirm.', 'Confirm Dialog', 'Yes,No,Maybe']);
+  addListenerToClass('confirmDialogB', confirmDialogB,
+      ['You pressed confirm.', 'Confirm Dialog', ['Yes', 'No', 'Maybe, Not Sure']]);
+  addListenerToClass('promptDialog', promptDialog,
+      ['You pressed prompt.', 'Prompt Dialog', ['Yes', 'No', 'Maybe, Not Sure']]);
+  addListenerToClass('builtInAlert', alert, 'You pressed alert.');
+  addListenerToClass('builtInConfirm', confirm, 'You selected confirm');
+  addListenerToClass('builtInPrompt', prompt, ['This is a prompt.', 'Default value']);
+
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/splashscreen/index.html
----------------------------------------------------------------------
diff --git a/www/splashscreen/index.html b/www/splashscreen/index.html
new file mode 100644
index 0000000..19132a4
--- /dev/null
+++ b/www/splashscreen/index.html
@@ -0,0 +1,48 @@
+<!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 name="viewport" content="width=device-width,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+
+<script type="text/javascript" charset="utf-8">
+  function showFor(duration) {
+      navigator.splashscreen.show();
+      window.setTimeout(function() {
+          navigator.splashscreen.hide();
+      }, 1000 * duration);
+  }
+</script>
+  </head>
+  <body id="stage" class="theme">
+    <h1>Splashscreen</h1>
+    <h2>Action</h2>
+    <div class="btn large" onclick="showFor(1)">Show for 1 second</div>
+    <div class="btn large" onclick="showFor(5)">Show for 5 seconds</div>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/sql/index.html
----------------------------------------------------------------------
diff --git a/www/sql/index.html b/www/sql/index.html
new file mode 100644
index 0000000..da0d809
--- /dev/null
+++ b/www/sql/index.html
@@ -0,0 +1,50 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>HTML5 Database</h1>   
+    <div id="info">
+        <b>Results:</b><br>
+        <span id="database_results"></span>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large callDatabase0">Create, Add, Read Database (Constant name)</div>
+    <div class="btn large readDatabase0">Read Database (Constant name)</div>
+    <div class="btn large increaseQuota0">Increase Quota (Constant name)</div>
+    <div class="btn large callDatabase1">Create, Add, Read Database (Random Name)</div>
+    <div class="btn large readDatabase1">Read Database (Random Name)</div>
+    <div class="btn large increaseQuota1">Increase Quota (Random Name)</div>
+    <div class="btn large reloadPage">Reload Page</div>
+    <h2> </h2><div class="backBtn">Back</div>    
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/sql/index.js
----------------------------------------------------------------------
diff --git a/www/sql/index.js b/www/sql/index.js
new file mode 100644
index 0000000..b5d5653
--- /dev/null
+++ b/www/sql/index.js
@@ -0,0 +1,125 @@
+//-------------------------------------------------------------------------
+// HTML5 Database
+//-------------------------------------------------------------------------
+var dbs = [];
+var quotas = [2000000, 2000000];
+var names = ['mydb', 'rand' + Math.random()];
+function openDb(index) {
+    try {
+        databaseOutput('Openning db with name: ' + names[index]);
+        return openDatabase(names[index], "1.0", "Apache Cordova Demo", quotas[index]);
+    } catch (e) {
+        databaseOutput('Got exception: ' + e);
+    }
+}
+
+var callDatabase = function(index) {
+    var db = dbs[index] = openDb(index);
+    if (!db) {
+        return;
+    }
+    databaseOutput("Database opened.");
+    db.transaction(function (tx) {
+        tx.executeSql('DROP TABLE IF EXISTS DEMO');
+        tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)', [],
+             function(tx,results) { console.log("Created table"); },
+             function(tx,err) { alert("Error creating table: "+err.message); });
+        tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")', [],
+             function(tx,results) { console.log("Insert row1 success"); },
+             function(tx,err) { alert("Error adding 1st row: "+err.message); });
+        tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")', [],
+             function(tx,results) { console.log("Insert row2 success"); },
+             function(tx,err) { alert("Error adding 2nd row: "+err.message); });
+        databaseOutput("Data written to DEMO table.");
+        console.log("Data written to DEMO table.");
+
+        tx.executeSql('SELECT * FROM DEMO', [], function (tx, results) {
+            var len = results.rows.length;
+            var text = "DEMO table: " + len + " rows found.<br>";
+            text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
+            for (var i=0; i<len; i++){
+                text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
+            }
+            text = text + "</table>";
+            databaseOutput(text);
+        }, function(tx, err) {
+            alert("Error processing SELECT * SQL: "+err.message);
+        });
+        tx.executeSql('SELECT ID FROM DEMO', [], function (tx, results) {
+            var len = results.rows.length;
+            var text = "DEMO table: " + len + " rows found.<br>";
+            text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
+            for (var i=0; i<len; i++){
+                text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + "</td></tr>";
+            }
+            text = text + "</table>";
+            databaseOutput(text);
+        }, function(tx, err) {
+            alert("Error processing SELECT ID SQL: "+err.message);
+        });
+        
+    },
+    function(err) {
+        console.log("Transaction failed: " + err.message);
+    });
+
+
+};
+
+var readDatabase = function(index) {
+    var db = dbs[index];
+  if (!db) {
+        db = dbs[index] = openDb(index);
+        if (!db) {
+            return;
+        }
+    }
+    db.transaction(function (tx) {
+        tx.executeSql('SELECT * FROM DEMO WHERE id=2', [], function (tx, results) {
+            var len = results.rows.length;
+            var text = "DEMO table: " + len + " rows found.<br>";
+            text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
+            for (var i=0; i<len; i++){
+                text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
+            }
+            text = text + "</table>";
+            databaseOutput(text);
+        }, function(tx, err) {
+            alert("Error processing SELECT * WHERE id=2 SQL: "+err.message);
+        });
+    });
+}
+
+function increaseQuota(index) {
+    quotas[index] *= 2;
+    databaseOutput('quota ' + index + ' is now ' + quotas[index]);
+}
+
+var databaseOutput = function(s) {
+    var el = document.getElementById("database_results");
+    el.innerHTML = el.innerHTML + s + "<br>";
+    el.scrollByLines(20000);
+};
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+        console.log("Device="+device.platform+" "+device.version);
+    }, false);
+}
+
+window.onload = function() {
+  addListenerToClass('callDatabase0', callDatabase, [0]);
+  addListenerToClass('readDatabase0', readDatabase, [0]);
+  addListenerToClass('increaseQuota0', increaseQuota, [0]);
+  addListenerToClass('callDatabase1', callDatabase, 1);
+  addListenerToClass('readDatabase1', readDatabase, 1);
+  addListenerToClass('increaseQuota1', increaseQuota, 1);
+  addListenerToClass('reloadPage', function() {
+    location = location.href;
+  });
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/storage/index.html
----------------------------------------------------------------------
diff --git a/www/storage/index.html b/www/storage/index.html
new file mode 100644
index 0000000..0b713a2
--- /dev/null
+++ b/www/storage/index.html
@@ -0,0 +1,41 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Local Storage</h1>
+    <div id="info">
+        You have run this app <span id="count">an untold number of</span> time(s).
+    </div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/storage/index.js
----------------------------------------------------------------------
diff --git a/www/storage/index.js b/www/storage/index.js
new file mode 100644
index 0000000..00ae7e1
--- /dev/null
+++ b/www/storage/index.js
@@ -0,0 +1,27 @@
+var deviceReady = false;
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+      if (!deviceReady) {
+        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+      }
+    },1000);
+}
+
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+  init();
+
+  if (!localStorage.pageLoadCount) {
+      localStorage.pageLoadCount = 0;
+  }
+  localStorage.pageLoadCount = parseInt(localStorage.pageLoadCount) + 1;
+  document.getElementById('count').textContent = localStorage.pageLoadCount;
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/vibration/index.html
----------------------------------------------------------------------
diff --git a/www/vibration/index.html b/www/vibration/index.html
new file mode 100644
index 0000000..a24110e
--- /dev/null
+++ b/www/vibration/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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Vibrations</h1>
+    <div id="info">
+    </div>
+    
+    <h2>Action</h2>
+    <div class="btn large vibrate">Vibrate</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/vibration/index.js
----------------------------------------------------------------------
diff --git a/www/vibration/index.js b/www/vibration/index.js
new file mode 100644
index 0000000..0d28902
--- /dev/null
+++ b/www/vibration/index.js
@@ -0,0 +1,31 @@
+var deviceReady = false;
+
+//-------------------------------------------------------------------------
+// Vibrations
+//-------------------------------------------------------------------------
+
+var vibrate = function(){
+  navigator.notification.vibrate(2500);
+};
+
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+        if (!deviceReady) {
+            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+        }
+    },1000);
+}
+
+window.onload = function() {
+  addListenerToClass('vibrate', vibrate);
+  addListenerToClass('backBtn', backHome);
+  init();
+}


[06/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/file.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/file.tests.js b/www/autotest/tests/file.tests.js
new file mode 100644
index 0000000..50c9e8e
--- /dev/null
+++ b/www/autotest/tests/file.tests.js
@@ -0,0 +1,4451 @@
+/*
+ *
+ * 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('File API', function() {
+    // Adding a Jasmine helper matcher, to report errors when comparing to FileError better.
+    var fileErrorMap = {
+        1: 'NOT_FOUND_ERR',
+        2: 'SECURITY_ERR',
+        3: 'ABORT_ERR',
+        4: 'NOT_READABLE_ERR',
+        5: 'ENCODING_ERR',
+        6: 'NO_MODIFICATION_ALLOWED_ERR',
+        7: 'INVALID_STATE_ERR',
+        8: 'SYNTAX_ERR',
+        9: 'INVALID_MODIFICATION_ERR',
+        10:'QUOTA_EXCEEDED_ERR',
+        11:'TYPE_MISMATCH_ERR',
+        12:'PATH_EXISTS_ERR'
+    };
+    beforeEach(function() {
+        this.addMatchers({
+            toBeFileError: function(code) {
+                var error = this.actual;
+                this.message = function(){
+                    return "Expected FileError with code " + fileErrorMap[error.code] + " (" + error.code + ") to be " + fileErrorMap[code] + "(" + code + ")";
+                };
+                return (error.code == code);
+            },
+            toCanonicallyMatch:function(path){
+                this.message = function(){
+                    return "Expected paths to match : " + path + " should be " + this.actual;
+                };
+
+                var a = path.split("/").join("").split("\\").join("");
+                var b = this.actual.split("/").join("").split("\\").join("");
+
+                return a == b;
+            }
+        });
+    });
+
+    // HELPER FUNCTIONS
+
+    // deletes specified file or directory
+    var deleteEntry = function(name, success, error) {
+        // deletes entry, if it exists
+        window.resolveLocalFileSystemURI(root.toURL() + '/' + name,
+            function(entry) {
+                if (entry.isDirectory === true) {
+                    entry.removeRecursively(success, error);
+                } else {
+                    entry.remove(success, error);
+                }
+            }, success);
+    };
+    // deletes file, if it exists, then invokes callback
+    var deleteFile = function(fileName, callback) {
+        root.getFile(fileName, null,
+                // remove file system entry
+                function(entry) {
+                    entry.remove(callback, function() { console.log('[ERROR] deleteFile cleanup method invoked fail callback.'); });
+                },
+                // doesn't exist
+                callback);
+    };
+    // deletes and re-creates the specified file
+    var createFile = function(fileName, success, error) {
+        deleteEntry(fileName, function() {
+            root.getFile(fileName, {create: true}, success, error);
+        }, error);
+    };
+    // deletes and re-creates the specified directory
+    var createDirectory = function(dirName, success, error) {
+        deleteEntry(dirName, function() {
+           root.getDirectory(dirName, {create: true}, success, error);
+        }, error);
+    };
+
+    var createFail = function(module) {
+        return jasmine.createSpy("Fail").andCallFake(function(err) {
+            console.log('[ERROR ' + module + '] ' + JSON.stringify(err));
+        });
+    };
+
+    var joinURL = function(base, extension) {
+        if (base.charAt(base.length-1) !== '/' && extension.charAt(0) !== '/') {
+            return base + '/' + extension;
+        }
+        if (base.charAt(base.length-1) === '/' && extension.charAt(0) === '/') {
+            return base + exension.substring(1);
+        }
+        return base + extension;
+    };
+
+    var createWin = function(module) {
+        return jasmine.createSpy("Win").andCallFake(function() {
+            console.log('[ERROR ' + module + '] Unexpected success callback');
+        });
+    };
+
+    describe('FileError object', function() {
+        it("file.spec.1 should define FileError constants", function() {
+            expect(FileError.NOT_FOUND_ERR).toBe(1);
+            expect(FileError.SECURITY_ERR).toBe(2);
+            expect(FileError.ABORT_ERR).toBe(3);
+            expect(FileError.NOT_READABLE_ERR).toBe(4);
+            expect(FileError.ENCODING_ERR).toBe(5);
+            expect(FileError.NO_MODIFICATION_ALLOWED_ERR).toBe(6);
+            expect(FileError.INVALID_STATE_ERR).toBe(7);
+            expect(FileError.SYNTAX_ERR).toBe(8);
+            expect(FileError.INVALID_MODIFICATION_ERR).toBe(9);
+            expect(FileError.QUOTA_EXCEEDED_ERR).toBe(10);
+            expect(FileError.TYPE_MISMATCH_ERR).toBe(11);
+            expect(FileError.PATH_EXISTS_ERR).toBe(12);
+        });
+    });
+
+    describe('LocalFileSystem', function() {
+
+        it("file.spec.2 should define LocalFileSystem constants", function() {
+            expect(LocalFileSystem.TEMPORARY).toBe(0);
+            expect(LocalFileSystem.PERSISTENT).toBe(1);
+        });
+
+        describe('window.requestFileSystem', function() {
+            it("file.spec.3 should be defined", function() {
+                expect(window.requestFileSystem).toBeDefined();
+            });
+            it("file.spec.4 should be able to retrieve a PERSISTENT file system", function() {
+                var win = jasmine.createSpy().andCallFake(function(fileSystem) {
+                    expect(fileSystem).toBeDefined();
+                    expect(fileSystem.name).toBeDefined();
+                    expect(fileSystem.name).toBe("persistent");
+                    expect(fileSystem.root).toBeDefined();
+                    expect(fileSystem.root.filesystem).toBeDefined();
+                    // Shouldn't use cdvfile by default.
+                    expect(fileSystem.root.toURL()).not.toMatch(/^cdvfile:/);
+                    // All DirectoryEntry URLs should always have a trailing slash.
+                    expect(fileSystem.root.toURL()).toMatch(/\/$/);
+                }),
+                fail = createFail('window.requestFileSystem');
+
+                // retrieve PERSISTENT file system
+                runs(function() {
+                    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, win, fail);
+                });
+
+                waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(fail).not.toHaveBeenCalled();
+                    expect(win).toHaveBeenCalled();
+                });
+            });
+            it("file.spec.5 should be able to retrieve a TEMPORARY file system", function() {
+                var win = jasmine.createSpy().andCallFake(function(fileSystem) {
+                    expect(fileSystem).toBeDefined();
+                    expect(fileSystem.name).toBeDefined();
+                    expect(fileSystem.name).toBe("temporary");
+                    expect(fileSystem.root).toBeDefined();
+                    expect(fileSystem.root.filesystem).toBeDefined();
+                    expect(fileSystem.root.filesystem).toBe(fileSystem);
+                }),
+                fail = createFail('window.requestFileSystem');
+
+                // Request the file system
+                runs(function() {
+                    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, win, fail);
+                });
+
+                waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(fail).not.toHaveBeenCalled();
+                    expect(win).toHaveBeenCalled();
+                });
+            });
+            it("file.spec.6 should error if you request a file system that is too large", function() {
+                var fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.QUOTA_EXCEEDED_ERR);
+                }),
+                win = createWin('window.requestFileSystem');
+
+                // Request the file system
+                runs(function() {
+                    window.requestFileSystem(LocalFileSystem.TEMPORARY, 1000000000000000, win, fail);
+                });
+
+                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(win).not.toHaveBeenCalled();
+                    expect(fail).toHaveBeenCalled();
+                });
+            });
+            it("file.spec.7 should error out if you request a file system that does not exist", function() {
+                var fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.SYNTAX_ERR);
+                }),
+                win = createWin('window.requestFileSystem');
+
+                // Request the file system
+                runs(function() {
+                    window.requestFileSystem(-1, 0, win, fail);
+                });
+
+                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(win).not.toHaveBeenCalled();
+                    expect(fail).toHaveBeenCalled();
+                });
+            });
+        });
+
+        describe('window.resolveLocalFileSystemURI', function() {
+            it("file.spec.3 should be defined", function() {
+                expect(window.resolveLocalFileSystemURI).toBeDefined();
+            });
+            it("file.spec.9 should resolve a valid file name", function() {
+                var createDirectoryFail = createFail('createDirectory');
+                var resolveFail = createFail('resolveLocalFileSystemURI');
+                var fileName = 'file.spec.9';
+                var win = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    expect(fileEntry).toBeDefined();
+                    expect(fileEntry.name).toCanonicallyMatch(fileName);
+                    expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
+                    expect(fileEntry.toURL()).not.toMatch(/\/$/, 'URL should not end with a slash');
+
+                    // cleanup
+                    deleteEntry(fileName);
+                });
+                function gotDirectory(entry) {
+                    // lookup file system entry
+                    window.resolveLocalFileSystemURL(entry.toURL(), win, resolveFail);
+                }
+                createFile(fileName, gotDirectory, createDirectoryFail, createDirectoryFail);
+                waitsForAny(win, resolveFail, createDirectoryFail);
+            });
+            it("file.spec.9.5 should resolve a directory", function() {
+                var createDirectoryFail = createFail('createDirectory');
+                var resolveFail = createFail('resolveLocalFileSystemURI');
+                var fileName = 'file.spec.9.5';
+                var win = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    expect(fileEntry).toBeDefined();
+                    expect(fileEntry.name).toCanonicallyMatch(fileName);
+                    expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
+                    expect(fileEntry.toURL()).toMatch(/\/$/, 'URL end with a slash');
+
+                    // cleanup
+                    deleteEntry(fileName);
+                });
+                function gotDirectory(entry) {
+                    // lookup file system entry
+                    window.resolveLocalFileSystemURL(entry.toURL(), win, resolveFail);
+                }
+                createDirectory(fileName, gotDirectory, createDirectoryFail, createDirectoryFail);
+                waitsForAny(win, resolveFail, createDirectoryFail);
+            });
+            it("file.spec.10 resolve valid file name with parameters", function() {
+                var fileName = "resolve.file.uri.params",
+                win = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    expect(fileEntry).toBeDefined();
+                    if (fileEntry.toURL().toLowerCase().substring(0,10) === "cdvfile://") {
+                        expect(fileEntry.fullPath).toBe("/" + fileName + "?1234567890");
+                    }
+                    expect(fileEntry.name).toBe(fileName);
+
+                    // cleanup
+                    deleteEntry(fileName);
+                }),
+                fail = createFail('window.resolveLocalFileSystemURI');
+                resolveCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    // lookup file system entry
+                    runs(function() {
+                        window.resolveLocalFileSystemURI(entry.toURL() + "?1234567890", win, fail);
+                    });
+
+                    waitsFor(function() { return win.wasCalled; }, "resolveLocalFileSystemURI callback never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(win).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                });
+
+                // create a new file entry
+                runs(function() {
+                    createFile(fileName, resolveCallback, fail);
+                });
+
+                waitsFor(function() { return resolveCallback.wasCalled; }, "createFile callback never called", Tests.TEST_TIMEOUT);
+            });
+            it("file.spec.11 should error (NOT_FOUND_ERR) when resolving (non-existent) invalid file name", function() {
+                var fileName = joinURL(root.toURL(), "this.is.not.a.valid.file.txt");
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                }),
+                win = createWin('window.resolveLocalFileSystemURI');
+
+                // lookup file system entry
+                runs(function() {
+                    window.resolveLocalFileSystemURI(fileName, win, fail);
+                });
+
+                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(fail).toHaveBeenCalled();
+                    expect(win).not.toHaveBeenCalled();
+                });
+            });
+            it("file.spec.12 should error (ENCODING_ERR) when resolving invalid URI with leading /", function() {
+                var fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.ENCODING_ERR);
+                }),
+                win = createWin('window.resolveLocalFileSystemURI');
+
+                // lookup file system entry
+                runs(function() {
+                    window.resolveLocalFileSystemURI("/this.is.not.a.valid.url", win, fail);
+                });
+
+                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(fail).toHaveBeenCalled();
+                    expect(win).not.toHaveBeenCalled();
+                });
+            });
+        });
+    });
+
+    describe('Metadata interface', function() {
+        it("file.spec.13 should exist and have the right properties", function() {
+            var metadata = new Metadata();
+            expect(metadata).toBeDefined();
+            expect(metadata.modificationTime).toBeDefined();
+        });
+    });
+
+    describe('Flags interface', function() {
+        it("file.spec.13 should exist and have the right properties", function() {
+            var flags = new Flags(false, true);
+            expect(flags).toBeDefined();
+            expect(flags.create).toBeDefined();
+            expect(flags.create).toBe(false);
+            expect(flags.exclusive).toBeDefined();
+            expect(flags.exclusive).toBe(true);
+        });
+    });
+
+    describe('FileSystem interface', function() {
+        it("file.spec.15 should have a root that is a DirectoryEntry", function() {
+            var win = jasmine.createSpy().andCallFake(function(entry) {
+                expect(entry).toBeDefined();
+                expect(entry.isFile).toBe(false);
+                expect(entry.isDirectory).toBe(true);
+                expect(entry.name).toBeDefined();
+                expect(entry.fullPath).toBeDefined();
+                expect(entry.getMetadata).toBeDefined();
+                expect(entry.moveTo).toBeDefined();
+                expect(entry.copyTo).toBeDefined();
+                expect(entry.toURL).toBeDefined();
+                expect(entry.remove).toBeDefined();
+                expect(entry.getParent).toBeDefined();
+                expect(entry.createReader).toBeDefined();
+                expect(entry.getFile).toBeDefined();
+                expect(entry.getDirectory).toBeDefined();
+                expect(entry.removeRecursively).toBeDefined();
+            }),
+            fail = createFail('FileSystem');
+
+            runs(function() {
+                window.resolveLocalFileSystemURI(root.toURL(), win, fail);
+            });
+
+            waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(fail).not.toHaveBeenCalled();
+                expect(win).toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe('DirectoryEntry', function() {
+        it("file.spec.16 getFile: get Entry for file that does not exist", function() {
+            var fileName = "de.no.file",
+                filePath = joinURL(root.fullPath, fileName),
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create:false, exclusive:false, file does not exist
+            runs(function() {
+                root.getFile(fileName, {create:false}, win, fail);
+            });
+
+            waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(fail).toHaveBeenCalled();
+                expect(win).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.17 getFile: create new file", function() {
+            var fileName = "de.create.file",
+                filePath = joinURL(root.fullPath, fileName),
+                win = jasmine.createSpy().andCallFake(function(entry) {
+                    expect(entry).toBeDefined();
+                    expect(entry.isFile).toBe(true);
+                    expect(entry.isDirectory).toBe(false);
+                    expect(entry.name).toCanonicallyMatch(fileName);
+                    expect(entry.fullPath).toCanonicallyMatch(filePath);
+                    // cleanup
+                    entry.remove(null, null);
+                }),
+                fail = createFail('DirectoryEntry');
+
+            // create:true, exclusive:false, file does not exist
+            runs(function() {
+                root.getFile(fileName, {create: true}, win, fail);
+            });
+
+            waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(win).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.18 getFile: create new file (exclusive)", function() {
+            var fileName = "de.create.exclusive.file",
+                filePath = joinURL(root.fullPath, fileName),
+                win = jasmine.createSpy().andCallFake(function(entry) {
+                    expect(entry).toBeDefined();
+                    expect(entry.isFile).toBe(true);
+                    expect(entry.isDirectory).toBe(false);
+                    expect(entry.name).toBe(fileName);
+                    expect(entry.fullPath).toCanonicallyMatch(filePath);
+
+                    // cleanup
+                    entry.remove(null, null);
+                }),
+                fail = createFail('DirectoryEntry');
+
+            // create:true, exclusive:true, file does not exist
+            runs(function() {
+                root.getFile(fileName, {create: true, exclusive:true}, win, fail);
+            });
+
+            waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(win).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.19 getFile: create file that already exists", function() {
+            var fileName = "de.create.existing.file",
+                filePath = joinURL(root.fullPath, fileName),
+                getFile = jasmine.createSpy().andCallFake(function(file) {
+                    // create:true, exclusive:false, file exists
+                    runs(function() {
+                        root.getFile(fileName, {create:true}, win, fail);
+                    });
+
+                    waitsFor(function() { return win.wasCalled; }, "win was never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(win).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = createFail('DirectoryEntry'),
+                win = jasmine.createSpy().andCallFake(function(entry) {
+                    expect(entry).toBeDefined();
+                    expect(entry.isFile).toBe(true);
+                    expect(entry.isDirectory).toBe(false);
+                    expect(entry.name).toCanonicallyMatch(fileName);
+                    expect(entry.fullPath).toCanonicallyMatch(filePath);
+
+                    // cleanup
+                    entry.remove(null, fail);
+                });
+            // create file to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, getFile, fail);
+            });
+
+            waitsFor(function() { return getFile.wasCalled; }, "getFile was never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.20 getFile: create file that already exists (exclusive)", function() {
+            var fileName = "de.create.exclusive.existing.file",
+                filePath = joinURL(root.fullPath, fileName),
+                existingFile,
+                getFile = jasmine.createSpy().andCallFake(function(file) {
+                    existingFile = file;
+                    // create:true, exclusive:true, file exists
+                    runs(function() {
+                        root.getFile(fileName, {create:true, exclusive:true}, win, fail);
+                    });
+
+                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(fail).toHaveBeenCalled();
+                        expect(win).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);
+
+                    // cleanup
+                    existingFile.remove(null, fail);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create file to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, getFile, fail);
+            });
+
+            waitsFor(function() { return getFile.wasCalled; }, "getFile never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.21 DirectoryEntry.getFile: get Entry for existing file", function() {
+            var fileName = "de.get.file",
+                filePath = joinURL(root.fullPath, fileName),
+                win = jasmine.createSpy().andCallFake(function(entry) {
+                    expect(entry).toBeDefined();
+                    expect(entry.isFile).toBe(true);
+                    expect(entry.isDirectory).toBe(false);
+                    expect(entry.name).toCanonicallyMatch(fileName);
+                    expect(entry.fullPath).toCanonicallyMatch(filePath);
+                    expect(entry.filesystem).toBeDefined();
+                    expect(entry.filesystem).toBe(root.filesystem);
+                    entry.remove(null, fail); //clean up
+                }),
+                fail = createFail('DirectoryEntry'),
+                getFile = jasmine.createSpy().andCallFake(function(file) {
+                    // create:false, exclusive:false, file exists
+                    runs(function() {
+                        root.getFile(fileName, {create:false}, win, fail);
+                    });
+
+                    waitsFor(function() { return win.wasCalled; }, "getFile success callback", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(win).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                });
+
+            // create file to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, getFile, fail);
+            });
+
+            waitsFor(function() { return getFile.wasCalled; }, "file creation", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.22 DirectoryEntry.getFile: get FileEntry for invalid path", function() {
+            var fileName = "de:invalid:path",
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.ENCODING_ERR);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create:false, exclusive:false, invalid path
+            runs(function() {
+                root.getFile(fileName, {create:false}, win, fail);
+            });
+
+            waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(fail).toHaveBeenCalled();
+                expect(win).not.toHaveBeenCalled();
+            });
+
+        });
+        it("file.spec.23 DirectoryEntry.getDirectory: get Entry for directory that does not exist", function() {
+            var dirName = "de.no.dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create:false, exclusive:false, directory does not exist
+            runs(function() {
+                root.getDirectory(dirName, {create:false}, win, fail);
+            });
+
+            waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(fail).toHaveBeenCalled();
+                expect(win).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.24 DirectoryEntry.getDirectory: create new dir with space then resolveFileSystemURI", function() {
+            var dirName = "de create dir",
+                dirPath = joinURL(root.fullPath, encodeURIComponent(dirName)),
+                getDir = jasmine.createSpy().andCallFake(function(dirEntry) {
+                    expect(dirEntry.filesystem).toBeDefined();
+                    expect(dirEntry.filesystem).toBe(root.filesystem);
+                    var dirURI = dirEntry.toURL();
+                    // now encode URI and try to resolve
+                    window.resolveLocalFileSystemURI(dirURI, win, fail);
+                }),
+                win = jasmine.createSpy().andCallFake(function(directory) {
+
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.name).toCanonicallyMatch(dirName);
+                    expect(directory.fullPath).toCanonicallyMatch(joinURL(root.fullPath, dirName));
+
+                    // cleanup
+                    directory.remove(null, fail);
+                }),
+                fail = createFail('DirectoryEntry');
+
+            // create:true, exclusive:false, directory does not exist
+            root.getDirectory(dirName, {create: true}, getDir, fail);
+
+            waitsForAny(fail, win);
+        });
+
+        // This test is excluded, and should probably be removed. Filesystem
+        // should always be properly encoded URLs, and *not* raw paths, and it
+        // doesn't make sense to double-encode the URLs and expect that to be
+        // handled by the implementation.
+        // If a particular platform uses paths internally rather than URLs,
+        // then that platform should careful to pass them correctly to its
+        // backend.
+        xit("file.spec.25 DirectoryEntry.getDirectory: create new dir with space resolveFileSystemURI with encoded URI", function() {
+            var dirName = "de create dir2",
+                dirPath = joinURL(root.fullPath, dirName),
+                getDir = jasmine.createSpy().andCallFake(function(dirEntry) {
+                    var dirURI = dirEntry.toURL();
+                    // now encode URI and try to resolve
+                    runs(function() {
+                        window.resolveLocalFileSystemURI(encodeURI(dirURI), win, fail);
+                    });
+
+                    waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(win).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                win = jasmine.createSpy().andCallFake(function(directory) {
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.name).toCanonicallyMatch(dirName);
+                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
+                    // cleanup
+                    directory.remove(null, fail);
+                }),
+                fail = createFail('DirectoryEntry');
+
+            // create:true, exclusive:false, directory does not exist
+            runs(function() {
+                root.getDirectory(dirName, {create: true}, getDir, fail);
+            });
+
+            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
+        });
+
+        it("file.spec.26 DirectoryEntry.getDirectory: create new directory", function() {
+            var dirName = "de.create.dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                win = jasmine.createSpy().andCallFake(function(directory) {
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.name).toCanonicallyMatch(dirName);
+                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
+                    expect(directory.filesystem).toBeDefined();
+                    expect(directory.filesystem).toBe(root.filesystem);
+
+                    // cleanup
+                    directory.remove(null, fail);
+                }),
+                fail = createFail('DirectoryEntry');
+
+            // create:true, exclusive:false, directory does not exist
+            runs(function() {
+                root.getDirectory(dirName, {create: true}, win, fail);
+            });
+
+            waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(win).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+
+        it("file.spec.27 DirectoryEntry.getDirectory: create new directory (exclusive)", function() {
+            var dirName = "de.create.exclusive.dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                win = jasmine.createSpy().andCallFake(function(directory) {
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.name).toCanonicallyMatch(dirName);
+                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
+                    expect(directory.filesystem).toBeDefined();
+                    expect(directory.filesystem).toBe(root.filesystem);
+
+                    // cleanup
+                    directory.remove(null, fail);
+                }),
+                fail = createFail('DirectoryEntry');
+            // create:true, exclusive:true, directory does not exist
+            runs(function() {
+                root.getDirectory(dirName, {create: true, exclusive:true}, win, fail);
+            });
+
+            waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(win).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.28 DirectoryEntry.getDirectory: create directory that already exists", function() {
+            var dirName = "de.create.existing.dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                getDir = jasmine.createSpy().andCallFake(function(directory) {
+                    // create:true, exclusive:false, directory exists
+                    runs(function() {
+                        root.getDirectory(dirName, {create:true}, win, fail);
+                    });
+
+                    waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(win).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                win = jasmine.createSpy().andCallFake(function(directory) {
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.name).toCanonicallyMatch(dirName);
+                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
+
+                    // cleanup
+                    directory.remove(null, fail);
+                }),
+                fail = createFail('DirectoryEntry');
+
+            // create directory to kick off it
+            runs(function() {
+                root.getDirectory(dirName, {create:true}, getDir, this.fail);
+            });
+
+            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.29 DirectoryEntry.getDirectory: create directory that already exists (exclusive)", function() {
+            var dirName = "de.create.exclusive.existing.dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                existingDir,
+                getDir = jasmine.createSpy().andCallFake(function(directory) {
+                    existingDir = directory;
+                    // create:true, exclusive:true, directory exists
+                    runs(function() {
+                        root.getDirectory(dirName, {create:true, exclusive:true}, win, fail);
+                    });
+
+                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(fail).toHaveBeenCalled();
+                        expect(win).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);
+
+                    // cleanup
+                    existingDir.remove(null, fail);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create directory to kick off it
+            runs(function() {
+                root.getDirectory(dirName, {create:true}, getDir, fail);
+            });
+
+            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.30 DirectoryEntry.getDirectory: get Entry for existing directory", function() {
+            var dirName = "de.get.dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                getDir = jasmine.createSpy().andCallFake(function(directory) {
+                    // create:false, exclusive:false, directory exists
+                    runs(function() {
+                        root.getDirectory(dirName, {create:false}, win, fail);
+                    });
+
+                    waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(win).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                win = jasmine.createSpy().andCallFake(function(directory) {
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.name).toCanonicallyMatch(dirName);
+
+                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
+
+                    // cleanup
+                    directory.remove(null, fail);
+                }),
+                fail = createFail('DirectoryEntry');
+
+            // create directory to kick it off
+            runs(function() {
+                root.getDirectory(dirName, {create:true}, getDir, fail);
+            });
+            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.31 DirectoryEntry.getDirectory: get DirectoryEntry for invalid path", function() {
+            var dirName = "de:invalid:path",
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.ENCODING_ERR);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create:false, exclusive:false, invalid path
+            runs(function() {
+                root.getDirectory(dirName, {create:false}, win, fail);
+            });
+
+            waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(fail).toHaveBeenCalled();
+                expect(win).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.32 DirectoryEntry.getDirectory: get DirectoryEntry for existing file", function() {
+            var fileName = "de.existing.file",
+                existingFile,
+                filePath = joinURL(root.fullPath, fileName),
+                getDir = jasmine.createSpy().andCallFake(function(file) {
+                    existingFile = file;
+                    // create:false, exclusive:false, existing file
+                    runs(function() {
+                        root.getDirectory(fileName, {create:false}, win, fail);
+                    });
+
+                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(fail).toHaveBeenCalled();
+                        expect(win).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);
+
+                    // cleanup
+                    existingFile.remove(null, null);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create file to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, getDir, fail);
+            });
+
+            waitsFor(function() { return getDir.wasCalled; }, "getDir was never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.33 DirectoryEntry.getFile: get FileEntry for existing directory", function() {
+            var dirName = "de.existing.dir",
+                existingDir,
+                dirPath = joinURL(root.fullPath, dirName),
+                getFile = jasmine.createSpy().andCallFake(function(directory) {
+                    existingDir = directory;
+                    // create:false, exclusive:false, existing directory
+                    runs(function() {
+                        root.getFile(dirName, {create:false}, win, fail);
+                    });
+
+                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(fail).toHaveBeenCalled();
+                        expect(win).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);
+
+                    // cleanup
+                    existingDir.remove(null, null);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // create directory to kick off it
+            runs(function() {
+                root.getDirectory(dirName, {create:true}, getFile, fail);
+            });
+
+            waitsFor(function() { return getFile.wasCalled; }, "getFile never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.34 DirectoryEntry.removeRecursively on directory", function() {
+            var dirName = "de.removeRecursively",
+                subDirName = "dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                subDirPath = joinURL(dirPath, subDirName),
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    // delete directory
+                    var deleteDirectory = jasmine.createSpy().andCallFake(function(directory) {
+                        runs(function() {
+                            entry.removeRecursively(remove, fail);
+                        });
+
+                        waitsFor(function() { return remove.wasCalled; }, "remove never called", Tests.TEST_TIMEOUT);
+                    });
+                    // create a sub-directory within directory
+                    runs(function() {
+                        entry.getDirectory(subDirName, {create: true}, deleteDirectory, fail);
+                    });
+
+                    waitsFor(function() { return deleteDirectory.wasCalled; }, "deleteDirectory never called", Tests.TEST_TIMEOUT);
+                }),
+                remove = jasmine.createSpy().andCallFake(function() {
+                    // it that removed directory no longer exists
+                    runs(function() {
+                        root.getDirectory(dirName, {create:false}, win, dirExists);
+                    });
+
+                    waitsFor(function() { return dirExists.wasCalled; }, "dirExists never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(dirExists).toHaveBeenCalled();
+                        expect(win).not.toHaveBeenCalled();
+                    });
+                }),
+                dirExists = jasmine.createSpy().andCallFake(function(error){
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                }),
+                fail = createFail('DirectoryEntry'),
+                win = createWin('DirectoryEntry');
+
+            // create a new directory entry to kick off it
+            runs(function() {
+                root.getDirectory(dirName, {create:true}, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.35 createReader: create reader on existing directory", function() {
+            // create reader for root directory
+            var reader = root.createReader();
+            expect(reader).toBeDefined();
+            expect(typeof reader.readEntries).toBe('function');
+        });
+        it("file.spec.36 removeRecursively on root file system", function() {
+            var remove = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);
+                }),
+                win = createWin('DirectoryEntry');
+
+            // remove root file system
+            runs(function() {
+                root.removeRecursively(win, remove);
+            });
+
+            waitsFor(function() { return remove.wasCalled; }, "remove never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(win).not.toHaveBeenCalled();
+                expect(remove).toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe('DirectoryReader interface', function() {
+        describe("readEntries", function() {
+            it("file.spec.37 should read contents of existing directory", function() {
+                var reader,
+                    win = jasmine.createSpy().andCallFake(function(entries) {
+                        expect(entries).toBeDefined();
+                        expect(entries instanceof Array).toBe(true);
+                    }),
+                    fail = createFail('DirectoryReader');
+
+                // create reader for root directory
+                reader = root.createReader();
+                // read entries
+                runs(function() {
+                    reader.readEntries(win, fail);
+                });
+
+                waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(win).toHaveBeenCalled();
+                    expect(fail).not.toHaveBeenCalled();
+                });
+            });
+            it("file.spec.37.1 should read contents of existing directory", function(done) {
+                var fail = createFail('DirectoryReader', done),
+                    dirName = 'readEntries.dir',
+                    fileName = 'readeEntries.file';
+                root.getDirectory(dirName, {create: true}, function(directory) {
+                    directory.getFile(fileName, {create: true}, function(fileEntry) {
+                        var reader = directory.createReader();
+                        reader.readEntries(function(entries) {
+                            expect(entries).toBeDefined();
+                            expect(entries instanceof Array).toBe(true);
+                            expect(entries.length).toBe(1);
+                            expect(entries[0].fullPath).toCanonicallyMatch(fileEntry.fullPath);
+                            expect(entries[0].filesystem).not.toBe(null)
+                            expect(entries[0].filesystem instanceof FileSystem).toBe(true)
+
+                            // cleanup
+                            directory.removeRecursively(done, fail);
+                        }, fail);
+                    }, fail);
+                }, fail);
+            });
+            it("file.spec.109 should return an empty entry list on the second call", function() {
+                var reader,
+                    firstWin = jasmine.createSpy().andCallFake(function(entries) {
+                        expect(entries).toBeDefined();
+                        expect(entries instanceof Array).toBe(true);
+                        expect(entries.length).not.toBe(0);
+                        reader.readEntries(secondWin, fail);
+                    }),
+                    secondWin = jasmine.createSpy().andCallFake(function(entries) {
+                        expect(entries).toBeDefined();
+                        expect(entries instanceof Array).toBe(true);
+                        expect(entries.length).toBe(0);
+                    }),
+                    fail = createFail('DirectoryReader');
+
+                runs(function() {
+                    // Add a file to ensure the root directory is non-empty and then read the contents of the directory.
+                    root.getFile('test109.txt', { create: true }, function() {
+                        reader = root.createReader();
+                        reader.readEntries(firstWin, fail);
+                    }, fail);
+                });
+
+                waitsFor(function() { return secondWin.wasCalled; }, "secondWin never called", Tests.TEST_TIMEOUT);
+
+                runs(function() {
+                    expect(firstWin).toHaveBeenCalled();
+                    expect(secondWin).toHaveBeenCalled();
+                    expect(fail).not.toHaveBeenCalled();
+
+                    // Remove the test file.
+                    root.getFile('test109.txt', { create: false }, function(fileEntry) {
+                        fileEntry.remove();
+                    }, fail);
+                });
+            });
+            it("file.spec.38 should read contents of directory that has been removed", function() {
+                var dirName = "de.createReader.notfound",
+	                dirPath = joinURL(root.fullPath, dirName),
+                    entryCallback = jasmine.createSpy().andCallFake(function(directory) {
+                        // read entries
+                        var readEntries = jasmine.createSpy().andCallFake(function() {
+                            var reader = directory.createReader();
+
+                            runs(function() {
+                                reader.readEntries(win, itReader);
+                            });
+
+                            waitsFor(function() { return itReader.wasCalled; }, "itReader never called", Tests.TEST_TIMEOUT);
+                        });
+                        // delete directory
+                        runs(function() {
+                            directory.removeRecursively(readEntries, fail);
+                        });
+
+                        waitsFor(function() { return readEntries.wasCalled; }, "readEntries never called", Tests.TEST_TIMEOUT);
+                    }),
+                    itReader = jasmine.createSpy().andCallFake(function(error) {
+                        var itDirectoryExists = jasmine.createSpy().andCallFake(function(error) {
+                            expect(error).toBeDefined();
+                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                        });
+
+                        expect(error).toBeDefined();
+                        expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+
+                        runs(function() {
+                            root.getDirectory(dirName, {create:false}, win, itDirectoryExists);
+                        });
+
+                        waitsFor(function() { return itDirectoryExists.wasCalled; }, "itDirectoryExists never called", Tests.TEST_TIMEOUT);
+
+                        runs(function() {
+                            expect(itDirectoryExists).toHaveBeenCalled();
+                            expect(win).not.toHaveBeenCalled();
+                        });
+                    }),
+                    fail = createFail('DirectoryReader'),
+                    win = createWin('DirectoryReader');
+
+                // create a new directory entry to kick off it
+                runs(function() {
+                    root.getDirectory(dirName, {create:true}, entryCallback, fail);
+                });
+
+                waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+            });
+        });
+    });
+
+    describe('File', function() {
+        it("file.spec.39 constructor should be defined", function() {
+            expect(File).toBeDefined();
+            expect(typeof File).toBe('function');
+        });
+        it("file.spec.40 should be define File attributes", function() {
+            var file = new File();
+            expect(file.name).toBeDefined();
+            expect(file.type).toBeDefined();
+            expect(file.lastModifiedDate).toBeDefined();
+            expect(file.size).toBeDefined();
+        });
+    });
+
+    describe('FileEntry', function() {
+        it("file.spec.41 should be define FileEntry methods", function() {
+            var fileName = "fe.methods",
+                itFileEntry = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    expect(fileEntry).toBeDefined();
+                    expect(typeof fileEntry.createWriter).toBe('function');
+                    expect(typeof fileEntry.file).toBe('function');
+
+                    // cleanup
+                    fileEntry.remove(null, fail);
+                }),
+                fail = createFail('FileEntry');
+
+            // create a new file entry to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, itFileEntry, fail);
+            });
+
+            waitsFor(function() { return itFileEntry.wasCalled; }, "itFileEntry never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(itFileEntry).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.42 createWriter should return a FileWriter object", function() {
+            var fileName = "fe.createWriter",
+                itFile,
+                entryCallback = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    itFile = fileEntry;
+
+                    runs(function() {
+                        fileEntry.createWriter(itWriter, fail);
+                    });
+
+                    waitsFor(function() { return itWriter.wasCalled; }, "itWriter", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(itWriter).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                itWriter = jasmine.createSpy().andCallFake(function(writer) {
+                    expect(writer).toBeDefined();
+                    expect(writer instanceof FileWriter).toBe(true);
+
+                    // cleanup
+                    itFile.remove(null, fail);
+                }),
+                fail = createFail('FileEntry');
+
+            // create a new file entry to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.43 file should return a File object", function() {
+            var fileName = "fe.file",
+                newFile,
+                entryCallback = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    newFile = fileEntry;
+
+                    runs(function() {
+                        fileEntry.file(itFile, fail);
+                    });
+
+                    waitsFor(function() { return itFile.wasCalled; }, "itFile never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(itFile).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                itFile = jasmine.createSpy().andCallFake(function(file) {
+                    expect(file).toBeDefined();
+                    expect(file instanceof File).toBe(true);
+
+                    // cleanup
+                    newFile.remove(null, fail);
+                }),
+                fail = createFail('FileEntry');
+
+            // create a new file entry to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.44 file: on File that has been removed", function() {
+            var fileName = "fe.no.file",
+                entryCallback = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    // create File object
+                    var getFile = jasmine.createSpy().andCallFake(function() {
+                        runs(function() {
+                            fileEntry.file(win, itFile);
+                        });
+
+                        waitsFor(function() { return itFile.wasCalled; }, "itFile never called", Tests.TEST_TIMEOUT);
+
+                        runs(function() {
+                            expect(itFile).toHaveBeenCalled();
+                            expect(win).not.toHaveBeenCalled();
+                        });
+                    });
+                    // delete file
+                    runs(function() {
+                        fileEntry.remove(getFile, fail);
+                    });
+
+                    waitsFor(function() { return getFile.wasCalled; }, "getFile never called", Tests.TEST_TIMEOUT);
+                }),
+                itFile = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                }),
+                fail = createFail('FileEntry'),
+                win = createWin('FileEntry');
+
+            // create a new file entry to kick off it
+            runs(function() {
+                root.getFile(fileName, {create:true}, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+    });
+    describe('Entry', function() {
+        it("file.spec.45 Entry object", function() {
+            var fileName = "entry",
+                fullPath = joinURL(root.fullPath, fileName),
+                fail = createFail('Entry'),
+                itEntry = jasmine.createSpy().andCallFake(function(entry) {
+                    expect(entry).toBeDefined();
+                    expect(entry.isFile).toBe(true);
+                    expect(entry.isDirectory).toBe(false);
+                    expect(entry.name).toCanonicallyMatch(fileName);
+                    expect(entry.fullPath).toCanonicallyMatch(fullPath);
+                    expect(typeof entry.getMetadata).toBe('function');
+                    expect(typeof entry.setMetadata).toBe('function');
+                    expect(typeof entry.moveTo).toBe('function');
+                    expect(typeof entry.copyTo).toBe('function');
+                    expect(typeof entry.toURL).toBe('function');
+                    expect(typeof entry.remove).toBe('function');
+                    expect(typeof entry.getParent).toBe('function');
+                    expect(typeof entry.createWriter).toBe('function');
+                    expect(typeof entry.file).toBe('function');
+
+                    // cleanup
+                    deleteEntry(fileName);
+                });
+
+            // create a new file entry
+            runs(function() {
+                createFile(fileName, itEntry, fail);
+            });
+
+            waitsFor(function() { return itEntry.wasCalled; }, "itEntry", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(itEntry).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.46 Entry.getMetadata on file", function() {
+            var fileName = "entry.metadata.file",
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    runs(function() {
+                        entry.getMetadata(itMetadata, fail);
+                    });
+
+                    waitsFor(function() { return itMetadata.wasCalled; }, "itMetadata never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(itMetadata).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = createFail('Entry'),
+                itMetadata = jasmine.createSpy().andCallFake(function(metadata) {
+                    expect(metadata).toBeDefined();
+                    expect(metadata.modificationTime instanceof Date).toBe(true);
+                    expect(isNaN(metadata.modificationTime.getTime())).toBe(false);
+                    expect(typeof metadata.size).toBe("number");
+
+                    // cleanup
+                    deleteEntry(fileName);
+                });
+
+            // create a new file entry
+            runs(function() {
+                createFile(fileName, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, 'entryCallback never called', Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.47 Entry.getMetadata on directory", function() {
+            var dirName = "entry.metadata.dir",
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    runs(function() {
+                        entry.getMetadata(itMetadata, fail);
+                    });
+
+                    waitsFor(function() { return itMetadata.wasCalled; }, "itMetadata never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(itMetadata).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = createFail('Entry'),
+                itMetadata = jasmine.createSpy().andCallFake(function(metadata) {
+                    expect(metadata).toBeDefined();
+                    expect(metadata.modificationTime instanceof Date).toBe(true);
+                    expect(isNaN(metadata.modificationTime.getTime())).toBe(false);
+                    expect(typeof metadata.size).toBe("number");
+                    expect(metadata.size).toBe(0);
+
+                    // cleanup
+                    deleteEntry(dirName);
+                });
+
+            // create a new directory entry
+            runs(function() {
+                createDirectory(dirName, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.48 Entry.getParent on file in root file system", function() {
+            var fileName = "entry.parent.file",
+                rootPath = root.fullPath,
+                fail = createFail('Entry'),
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    runs(function() {
+                        entry.getParent(itParent, fail);
+                    });
+
+                    waitsFor(function() { return itParent.wasCalled; }, "itCalled never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(itParent).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                itParent = jasmine.createSpy().andCallFake(function(parent) {
+                    expect(parent).toBeDefined();
+                    expect(parent.fullPath).toCanonicallyMatch(rootPath);
+
+                    // cleanup
+                    deleteEntry(fileName);
+                });
+
+            // create a new file entry
+            runs(function() {
+                createFile(fileName, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.49 Entry.getParent on directory in root file system", function() {
+            var dirName = "entry.parent.dir",
+                rootPath = root.fullPath,
+                fail = createFail('Entry'),
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    runs(function() {
+                        entry.getParent(itParent, fail);
+                    });
+
+                    waitsFor(function() { return itParent.wasCalled; }, "itParent never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(itParent).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                    });
+                }),
+                itParent = jasmine.createSpy().andCallFake(function(parent) {
+                    expect(parent).toBeDefined();
+                    expect(parent.fullPath).toCanonicallyMatch(rootPath);
+
+                    // cleanup
+                    deleteEntry(dirName);
+                });
+
+            // create a new directory entry
+            runs(function() {
+                createDirectory(dirName, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.50 Entry.getParent on root file system", function() {
+            var rootPath = root.fullPath,
+                itParent = jasmine.createSpy().andCallFake(function(parent) {
+                    expect(parent).toBeDefined();
+                    expect(parent.fullPath).toCanonicallyMatch(rootPath);
+                }),
+                fail = createFail('Entry');
+
+            // create a new directory entry
+            runs(function() {
+                root.getParent(itParent, fail);
+            });
+
+            waitsFor(function() { return itParent.wasCalled; }, "itParent never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(itParent).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.51 Entry.toURL on file", function() {
+            var fileName = "entry.uri.file",
+                rootPath = root.fullPath,
+                itURI = jasmine.createSpy().andCallFake(function(entry) {
+                    var uri = entry.toURL();
+                    expect(uri).toBeDefined();
+                    expect(uri.indexOf(rootPath)).not.toBe(-1);
+
+                    // cleanup
+                    deleteEntry(fileName);
+                }),
+                fail = createFail('Entry');
+
+            // create a new file entry
+            runs(function() {
+                createFile(fileName, itURI, fail);
+            });
+
+            waitsFor(function() { return itURI.wasCalled; }, "itURI never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(itURI).toHaveBeenCalled();
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("file.spec.52 Entry.toURL on directory", function() {
+            var dirName1 = "num 1",
+                dirName2 = "num 2",
+                rootPath = root.fullPath,
+                fail = createFail('Entry');
+
+            createDirectory(dirName1, createNext, fail);
+            function createNext(e1) {
+                e1.getDirectory(dirName2, {create: true}, check, fail);
+            }
+            var check = jasmine.createSpy().andCallFake(function(entry) {
+                var uri = entry.toURL();
+                expect(uri).toBeDefined();
+                expect(uri).toContain('/num%201/num%202/');
+                expect(uri.indexOf(rootPath)).not.toBe(-1);
+                // cleanup
+                deleteEntry(dirName1);
+            });
+            waitsForAny(check, fail);
+        });
+        it("file.spec.53 Entry.remove on file", function() {
+            var fileName = "entr .rm.file",
+                fullPath = joinURL(root.fullPath, fileName),
+                win = createWin('Entry'),
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    var checkRemove = jasmine.createSpy().andCallFake(function() {
+                        runs(function() {
+                            root.getFile(fileName, null, win, itRemove);
+                        });
+
+                        waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
+
+                        runs(function() {
+                            expect(win).not.toHaveBeenCalled();
+                            expect(fail).not.toHaveBeenCalled();
+                            expect(itRemove).toHaveBeenCalled();
+                        });
+                    });
+                    expect(entry).toBeDefined();
+
+                    runs(function() {
+                        entry.remove(checkRemove, fail);
+                    });
+
+                    waitsFor(function() { return checkRemove.wasCalled; }, "checkRemove never called", Tests.TEST_TIMEOUT);
+                }),
+                itRemove = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                    // cleanup
+                    deleteEntry(fileName);
+                }),
+                fail = createFail('Entry');
+
+            // create a new file entry
+            runs(function() {
+                createFile(fileName, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.54 remove on empty directory", function() {
+            var dirName = "entry.rm.dir",
+                dirPath = joinURL(root.fullPath, dirName),
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    var checkRemove = jasmine.createSpy().andCallFake(function() {
+                        runs(function() {
+                            root.getDirectory(dirName, null, win, itRemove);
+                        });
+
+                        waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
+
+                        runs(function() {
+                            expect(itRemove).toHaveBeenCalled();
+                            expect(win).not.toHaveBeenCalled();
+                            expect(fail).not.toHaveBeenCalled();
+                        });
+                    });
+
+                    expect(entry).toBeDefined();
+
+                    runs(function() {
+                        entry.remove(checkRemove, fail);
+                    });
+
+                    waitsFor(function() { return checkRemove.wasCalled; }, "checkRemove never called", Tests.TEST_TIMEOUT);
+                }),
+                itRemove = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
+                    // cleanup
+                    deleteEntry(dirName);
+                }),
+                win = createWin('Entry'),
+                fail = createFail('Entry');
+
+            // create a new directory entry
+            runs(function() {
+                createDirectory(dirName, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.55 remove on non-empty directory", function() {
+            var dirName = "ent y.rm.dir.not.empty",
+                fileName = "re ove.txt",
+                fullPath = joinURL(root.fullPath, dirName),
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    var checkFile = jasmine.createSpy().andCallFake(function(error) {
+                        expect(error).toBeDefined();
+                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
+                        // verify that dir still exists
+                        runs(function() {
+                            root.getDirectory(dirName, null, itRemove, fail);
+                        });
+
+                        waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
+
+                        runs(function() {
+                            expect(win).not.toHaveBeenCalled();
+                            expect(fail).not.toHaveBeenCalled();
+                            expect(itRemove).toHaveBeenCalled();
+                        });
+                    });
+                    // delete directory
+                    var deleteDirectory = jasmine.createSpy().andCallFake(function(fileEntry) {
+                        runs(function() {
+                            entry.remove(win, checkFile);
+                        });
+
+                        waitsFor(function() { return checkFile.wasCalled; }, "checkFile never called", Tests.TEST_TIMEOUT);
+                    });
+                    // create a file within directory, then try to delete directory
+                    runs(function() {
+                        entry.getFile(fileName, {create: true}, deleteDirectory, fail);
+                    });
+
+                    waitsFor(function() { return deleteDirectory.wasCalled; }, "deleteDirectory never called", Tests.TEST_TIMEOUT);
+                }),
+                itRemove = jasmine.createSpy().andCallFake(function(entry) {
+                    expect(entry).toBeDefined();
+                    expect(entry.fullPath).toCanonicallyMatch(fullPath);
+                    // cleanup
+                    deleteEntry(dirName);
+                }),
+                win = createWin('Entry'),
+                fail = createFail('Entry');
+
+            // create a new directory entry
+            runs(function() {
+                createDirectory(dirName, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.56 remove on root file system", function() {
+            var itRemove = jasmine.createSpy().andCallFake(function(error) {
+                expect(error).toBeDefined();
+                expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);
+            }),
+            win = createWin('Entry');
+
+            // remove entry that doesn't exist
+            runs(function() {
+                root.remove(win, itRemove);
+            });
+
+            waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                expect(win).not.toHaveBeenCalled();
+                expect(itRemove).toHaveBeenCalled();
+            });
+        });
+        it("file.spec.57 copyTo: file", function() {
+            var file1 = "entry copy.file1",
+                file2 = "entry copy.file2",
+                fullPath = joinURL(root.fullPath, file2),
+                fail = createFail('Entry'),
+                entryCallback = function(entry) {
+                    // copy file1 to file2
+                    entry.copyTo(root, file2, itCopy, fail);
+                },
+                itCopy = function(entry) {
+                    expect(entry).toBeDefined();
+                    expect(entry.isFile).toBe(true);
+                    expect(entry.isDirectory).toBe(false);
+                    expect(entry.fullPath).toCanonicallyMatch(fullPath);
+                    expect(entry.name).toCanonicallyMatch(file2);
+
+                    root.getFile(file2, {create:false}, itFileExists, fail);
+                },
+                itFileExists = jasmine.createSpy().andCallFake(function(entry2) {
+                    // a bit redundant since copy returned this entry already
+                    expect(entry2).toBeDefined();
+                    expect(entry2.isFile).toBe(true);
+                    expect(entry2.isDirectory).toBe(false);
+                    expect(entry2.fullPath).toCanonicallyMatch(fullPath);
+                    expect(entry2.name).toCanonicallyMatch(file2);
+
+                    // cleanup
+                    deleteEntry(file1);
+                    deleteEntry(file2);
+                });
+
+            // create a new file entry to kick off it
+            deleteEntry(file2, function() {
+                createFile(file1, entryCallback, fail);
+            }, fail);
+
+            waitsForAny(itFileExists, fail);
+        });
+        it("file.spec.58 copyTo: file onto itself", function() {
+            var file1 = "entry.copy.fos.file1",
+                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
+                    // copy file1 onto itself
+                    runs(function() {
+                        entry.copyTo(root, null, win, itCopy);
+                    });
+
+                    waitsFor(function() { return itCopy.wasCalled; }, "itCopy never called", Tests.TEST_TIMEOUT);
+
+                    runs(function() {
+                        expect(itCopy).toHaveBeenCalled();
+                        expect(fail).not.toHaveBeenCalled();
+                        expect(win).not.toHaveBeenCalled();
+                    });
+                }),
+                fail = createFail('Entry'),
+                win = createWin('Entry'),
+                itCopy = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
+
+                    // cleanup
+                    deleteEntry(file1);
+                });
+
+            // create a new file entry to kick off it
+            runs(function() {
+                createFile(file1, entryCallback, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.59 copyTo: directory", function() {
+            var file1 = "file1",
+                srcDir = "entry.copy.srcDir",
+                dstDir = "entry.copy.dstDir",
+                dstPath = joinURL(root.fullPath, dstDir),
+                filePath = joinURL(dstPath, file1),
+                entryCallback = jasmine.createSpy().andCallFake(function(directory) {
+                    var copyDir = jasmine.createSpy().andCallFake(function(fileEntry) {
+                        // copy srcDir to dstDir
+                        runs(function() {
+                            directory.copyTo(root, dstDir, itCopy, fail);
+                        });
+
+                        waitsFor(function() { return itCopy.wasCalled; }, "itCopy never called", Tests.TEST_TIMEOUT);
+                    });
+
+                    // create a file within new directory
+                    runs(function() {
+                        directory.getFile(file1, {create: true}, copyDir, fail);
+                    });
+
+                    waitsFor(function() { return copyDir.wasCalled; }, "copyDir never called", Tests.TEST_TIMEOUT);
+                }),
+                itCopy = jasmine.createSpy().andCallFake(function(directory) {
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.fullPath).toCanonicallyMatch(dstPath);
+                    expect(directory.name).toCanonicallyMatch(dstDir);
+
+                    runs(function() {
+                        root.getDirectory(dstDir, {create:false}, itDirExists, fail);
+                    });
+
+                    waitsFor(function() { return itDirExists.wasCalled; }, "itDirExists never called", Tests.TEST_TIMEOUT);
+                }),
+                itDirExists = jasmine.createSpy().andCallFake(function(dirEntry) {
+                     expect(dirEntry).toBeDefined();
+                     expect(dirEntry.isFile).toBe(false);
+                     expect(dirEntry.isDirectory).toBe(true);
+                     expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
+                     expect(dirEntry.name).toCanonicallyMatch(dstDir);
+
+                     runs(function() {
+                         dirEntry.getFile(file1, {create:false}, itFileExists, fail);
+                     });
+
+                     waitsFor(function() { return itFileExists.wasCalled; }, "itFileExists never called", Tests.TEST_TIMEOUT);
+
+                     runs(function() {
+                         expect(itFileExists).toHaveBeenCalled();
+                         expect(fail).not.toHaveBeenCalled();
+                     });
+                }),
+                itFileExists = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    expect(fileEntry).toBeDefined();
+                    expect(fileEntry.isFile).toBe(true);
+                    expect(fileEntry.isDirectory).toBe(false);
+                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
+                    expect(fileEntry.name).toCanonicallyMatch(file1);
+
+                    // cleanup
+                    deleteEntry(srcDir);
+                    deleteEntry(dstDir);
+                }),
+                fail = createFail('Entry');
+
+            // create a new directory entry to kick off it
+            runs(function() {
+                deleteEntry(dstDir, function() {
+                    createDirectory(srcDir, entryCallback, fail);
+                }, fail);
+            });
+
+            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
+        });
+        it("file.spec.60 copyTo: directory to backup at same root directory", function() {
+            var file1 = "file1",
+                srcDir = "entry.copy srcDirSame",
+                dstDir = "entry.copy srcDirSame-backup",
+                dstPath = joinURL(root.fullPath, dstDir),
+                filePath = joinURL(dstPath, file1),
+                fail = createFail('Entry copyTo: directory to backup at same root'),
+                entryCallback = function(directory) {
+                    var copyDir = function(fileEntry) {
+                        // copy srcDir to dstDir
+                        directory.copyTo(root, dstDir, itCopy, fail);
+                    };
+                    // create a file within new directory
+                    directory.getFile(file1, {create: true}, copyDir, fail);
+                },
+                itCopy = function(directory) {
+                    expect(directory).toBeDefined();
+                    expect(directory.isFile).toBe(false);
+                    expect(directory.isDirectory).toBe(true);
+                    expect(directory.fullPath).toCanonicallyMatch(dstPath);
+                    expect(directory.name).toCanonicallyMatch(dstDir);
+
+                    root.getDirectory(dstDir, {create:false}, itDirExists, fail);
+                },
+                itDirExists = function(dirEntry) {
+                     expect(dirEntry).toBeDefined();
+                     expect(dirEntry.isFile).toBe(false);
+                     expect(dirEntry.isDirectory).toBe(true);
+                     expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
+                     expect(dirEntry.name).toCanonicallyMatch(dstDir);
+
+                     dirEntry.getFile(file1, {create:false}, itFileExists, fail);
+                },
+                itFileExists = jasmine.createSpy().andCallFake(function(fileEntry) {
+                    var cleanSrc = jasmine.createSpy();
+                    var cleanDst = jasmine.createSpy();
+                    expect(fileEntry).toBeDefined();
+                    expect(fileEntry.isFile).toBe(true);
+                    expect(fileEntry.isDirectory).toBe(false);
+                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
+                    expect(fileEntry.name).toCanonicallyMatch(file1);
+                    expect(fail).not.toHaveBeenCalled();
+
+                    // cleanup
+                    deleteEntry(srcDir, cleanSrc);
+                    deleteEntry(dstDir, cleanDst);
+                });
+
+            // create a new directory entry to kick off it
+            deleteEntry(dstDir, function() {
+                createDirectory(srcDir, entryCallback, fail);
+            }, fail);
+
+            waitsForAny(itFileExists, fail);
+        });
+        it("file.spec.61 copyTo: directory onto itself", function() {
+            var file1 = "file1",
+                srcDir = "entry.copy.dos.srcDir",
+                srcPath = joinURL(root.fullPath, srcDir),
+                filePath = joinURL(srcPath, file1),
+                win = createWin('Entry'),
+                fail = createFail('Entry copyTo: directory onto itself'),
+                entryCallback = jasmine.createSpy().andCallFake(function(directory) {
+                    var copyDir = jasmine.createSpy().andCallFake(function(fileEntry) {
+                        // copy srcDir onto itself
+                        runs(function() {
+                            directory.copyTo(root, null, win, itCopy);
+                        });
+
+                        waitsFor(function() { return itCopy.wasCalled; }, "itCopy never called", Tests.TEST_TIMEOUT);
+                    });
+                    // create a file within new directory
+                    runs(function() {
+                        directory.getFile(file1, {create: true}, copyDir, fail);
+                    });
+
+                    waitsFor(function() { return copyDir.wasCalled; }, "copyDir never called", Tests.TEST_TIMEOUT);
+                }),
+                itCopy = jasmine.createSpy().andCallFake(function(error) {
+                    expect(error).toBeDefined();
+                    expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
+
+                    runs(function() {
+                        root.getDirectory(srcDir, {create:false}, itDirect

<TRUNCATED>

[10/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/misc/page3A.js
----------------------------------------------------------------------
diff --git a/misc/page3A.js b/misc/page3A.js
deleted file mode 100644
index 8efad58..0000000
--- a/misc/page3A.js
+++ /dev/null
@@ -1,27 +0,0 @@
-console.log('Changing hash #1.');
-if (location.search.indexOf('hash1') != -1) {
-  location.hash = 'a';
-} else if (location.search.indexOf('hash2') != -1) {
-  location.replace('#replaced');
-}
-var hashCount = 0;
-function changeHash() {
-  hashCount += 1;
-  if (hashCount % 1) {
-    location.hash = hashCount;
-  } else {
-    location.replace('#' + hashCount);
-  }
-}
-if (location.search.indexOf('changeURL') != -1) {
-  history.replaceState(null, null, 'fakepage.html');
-}
-function loadFrame() {
-  var ifr = document.createElement('iframe');
-  ifr.src="data:text/html;base64,PGh0bWw+";
-  document.body.appendChild(ifr);
-}
-function reload() {
-  // Test that iOS CDVWebViewDelegate doesn't ignore changes when URL doesn't change.
-  location.reload();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/network/index.html
----------------------------------------------------------------------
diff --git a/network/index.html b/network/index.html
deleted file mode 100644
index b750f6c..0000000
--- a/network/index.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-</script>
-
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Network Events and State</h1>
-    <div id="info">
-        <b>Results:</b><br>
-        <span id="results"></span>
-    </div>
-
-    <h2>Action</h2>
-    <div class="btn large printNetwork">Show Network Connection</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/network/index.js
----------------------------------------------------------------------
diff --git a/network/index.js b/network/index.js
deleted file mode 100644
index 41c2c47..0000000
--- a/network/index.js
+++ /dev/null
@@ -1,38 +0,0 @@
-function eventOutput(s) {
-    var el = document.getElementById("results");
-    el.innerHTML = el.innerHTML + s + "<br>";
-}
-
-function printNetwork() {
-    eventOutput("navigator.connection.type=" + navigator.connection.type);
-    eventOutput("navigator.network.connection.type=" + navigator.network.connection.type);
-}
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    var deviceReady = false;
-    function onEvent(e) {
-        eventOutput('Event of type: ' + e.type);
-        printNetwork();
-    }
-    document.addEventListener('online', onEvent, false);
-    document.addEventListener('offline', onEvent, false);
-    document.addEventListener("deviceready", function() {
-        deviceReady = true;
-        eventOutput("Device="+device.platform+" "+device.version);
-        printNetwork();
-    }, false);
-    window.setTimeout(function() {
-        if (!deviceReady) {
-            alert("Error: Cordova did not initialize.  Demo will not run correctly.");
-        }
-    }, 1000);
-}
-
-window.onload = function() {
-  addListenerToClass('printNetwork', printNetwork);
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/notification/index.html
----------------------------------------------------------------------
diff --git a/notification/index.html b/notification/index.html
deleted file mode 100644
index ab648df..0000000
--- a/notification/index.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Notifications and Dialogs</h1>
-    <div id="info">
-    </div>
-    
-    <h2>Action</h2>
-    <div class="btn large beep">Beep</div>
-    <div class="btn large alertDialog">Alert Dialog</div>
-    <div class="btn large confirmDialogA">Confirm Dialog - Deprecated</div>
-    <div class="btn large confirmDialogB">Confirm Dialog</div>
-    <div class="btn large promptDialog">Prompt Dialog</div>
-    
-    <div class="btn large builtInAlert">Built-in Alert Dialog</div>
-    <div class="btn large builtInConfirm">Built-in Confirm Dialog</div>
-    <div class="btn large builtInPrompt">Built-in Prompt Dialog</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/notification/index.js
----------------------------------------------------------------------
diff --git a/notification/index.js b/notification/index.js
deleted file mode 100644
index 12e672f..0000000
--- a/notification/index.js
+++ /dev/null
@@ -1,100 +0,0 @@
-var deviceReady = false;
-
-//-------------------------------------------------------------------------
-// Notifications
-//-------------------------------------------------------------------------
-
-var beep = function(){
-    navigator.notification.beep(3);
-};
-
-var alertDialog = function(message, title, button) {
-    console.log("alertDialog()");
-    navigator.notification.alert(message,
-        function(){
-            console.log("Alert dismissed.");
-        },
-        title, button);
-    console.log("After alert");
-};
-
-var confirmDialogA = function(message, title, buttons) {
-    navigator.notification.confirm(message,
-        function(r) {
-            if(r===0){
-                console.log("Dismissed dialog without making a selection.");
-                alert("Dismissed dialog without making a selection.");
-            }else{
-                console.log("You selected " + r);
-                alert("You selected " + (buttons.split(","))[r-1]);
-            }
-        },
-        title,
-        buttons);
-};
-
-var confirmDialogB = function(message, title, buttons) {
-    navigator.notification.confirm(message,
-        function(r) {
-            if(r===0){
-                console.log("Dismissed dialog without making a selection.");
-                alert("Dismissed dialog without making a selection.");
-            }else{
-                console.log("You selected " + r);
-                alert("You selected " + buttons[r-1]);
-            }
-        },
-        title,
-        buttons);
-};
-
-var promptDialog = function(message, title, buttons) {
-    navigator.notification.prompt(message,
-        function(r) {
-            if(r && r.buttonIndex===0){
-                var msg = "Dismissed dialog";
-                if( r.input1 ){
-                    msg+=" with input: " + r.input1
-                }
-                console.log(msg);
-                alert(msg);
-            }else{
-                console.log("You selected " + r.buttonIndex + " and entered: " + r.input1);
-                alert("You selected " + buttons[r.buttonIndex-1] + " and entered: " + r.input1);
-            }
-        },
-        title,
-        buttons);
-};
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-        if (!deviceReady) {
-            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-        }
-    },1000);
-}
-
-window.onload = function() {
-  addListenerToClass('beep', beep);
-  addListenerToClass('alertDialog', alertDialog, 
-      ['You pressed alert.', 'Alert Dialog', 'Continue']);
-  addListenerToClass('confirmDialogA', confirmDialogA, 
-      ['You pressed confirm.', 'Confirm Dialog', 'Yes,No,Maybe']);
-  addListenerToClass('confirmDialogB', confirmDialogB,
-      ['You pressed confirm.', 'Confirm Dialog', ['Yes', 'No', 'Maybe, Not Sure']]);
-  addListenerToClass('promptDialog', promptDialog,
-      ['You pressed prompt.', 'Prompt Dialog', ['Yes', 'No', 'Maybe, Not Sure']]);
-  addListenerToClass('builtInAlert', alert, 'You pressed alert.');
-  addListenerToClass('builtInConfirm', confirm, 'You selected confirm');
-  addListenerToClass('builtInPrompt', prompt, ['This is a prompt.', 'Default value']);
-
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/splashscreen/index.html
----------------------------------------------------------------------
diff --git a/splashscreen/index.html b/splashscreen/index.html
deleted file mode 100644
index 19132a4..0000000
--- a/splashscreen/index.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!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 name="viewport" content="width=device-width,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-
-<script type="text/javascript" charset="utf-8">
-  function showFor(duration) {
-      navigator.splashscreen.show();
-      window.setTimeout(function() {
-          navigator.splashscreen.hide();
-      }, 1000 * duration);
-  }
-</script>
-  </head>
-  <body id="stage" class="theme">
-    <h1>Splashscreen</h1>
-    <h2>Action</h2>
-    <div class="btn large" onclick="showFor(1)">Show for 1 second</div>
-    <div class="btn large" onclick="showFor(5)">Show for 5 seconds</div>
-    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/sql/index.html
----------------------------------------------------------------------
diff --git a/sql/index.html b/sql/index.html
deleted file mode 100644
index da0d809..0000000
--- a/sql/index.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>HTML5 Database</h1>   
-    <div id="info">
-        <b>Results:</b><br>
-        <span id="database_results"></span>
-    </div>
-    <h2>Action</h2>
-    <div class="btn large callDatabase0">Create, Add, Read Database (Constant name)</div>
-    <div class="btn large readDatabase0">Read Database (Constant name)</div>
-    <div class="btn large increaseQuota0">Increase Quota (Constant name)</div>
-    <div class="btn large callDatabase1">Create, Add, Read Database (Random Name)</div>
-    <div class="btn large readDatabase1">Read Database (Random Name)</div>
-    <div class="btn large increaseQuota1">Increase Quota (Random Name)</div>
-    <div class="btn large reloadPage">Reload Page</div>
-    <h2> </h2><div class="backBtn">Back</div>    
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/sql/index.js
----------------------------------------------------------------------
diff --git a/sql/index.js b/sql/index.js
deleted file mode 100644
index b5d5653..0000000
--- a/sql/index.js
+++ /dev/null
@@ -1,125 +0,0 @@
-//-------------------------------------------------------------------------
-// HTML5 Database
-//-------------------------------------------------------------------------
-var dbs = [];
-var quotas = [2000000, 2000000];
-var names = ['mydb', 'rand' + Math.random()];
-function openDb(index) {
-    try {
-        databaseOutput('Openning db with name: ' + names[index]);
-        return openDatabase(names[index], "1.0", "Apache Cordova Demo", quotas[index]);
-    } catch (e) {
-        databaseOutput('Got exception: ' + e);
-    }
-}
-
-var callDatabase = function(index) {
-    var db = dbs[index] = openDb(index);
-    if (!db) {
-        return;
-    }
-    databaseOutput("Database opened.");
-    db.transaction(function (tx) {
-        tx.executeSql('DROP TABLE IF EXISTS DEMO');
-        tx.executeSql('CREATE TABLE IF NOT EXISTS DEMO (id unique, data)', [],
-             function(tx,results) { console.log("Created table"); },
-             function(tx,err) { alert("Error creating table: "+err.message); });
-        tx.executeSql('INSERT INTO DEMO (id, data) VALUES (1, "First row")', [],
-             function(tx,results) { console.log("Insert row1 success"); },
-             function(tx,err) { alert("Error adding 1st row: "+err.message); });
-        tx.executeSql('INSERT INTO DEMO (id, data) VALUES (2, "Second row")', [],
-             function(tx,results) { console.log("Insert row2 success"); },
-             function(tx,err) { alert("Error adding 2nd row: "+err.message); });
-        databaseOutput("Data written to DEMO table.");
-        console.log("Data written to DEMO table.");
-
-        tx.executeSql('SELECT * FROM DEMO', [], function (tx, results) {
-            var len = results.rows.length;
-            var text = "DEMO table: " + len + " rows found.<br>";
-            text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
-            for (var i=0; i<len; i++){
-                text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
-            }
-            text = text + "</table>";
-            databaseOutput(text);
-        }, function(tx, err) {
-            alert("Error processing SELECT * SQL: "+err.message);
-        });
-        tx.executeSql('SELECT ID FROM DEMO', [], function (tx, results) {
-            var len = results.rows.length;
-            var text = "DEMO table: " + len + " rows found.<br>";
-            text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
-            for (var i=0; i<len; i++){
-                text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + "</td></tr>";
-            }
-            text = text + "</table>";
-            databaseOutput(text);
-        }, function(tx, err) {
-            alert("Error processing SELECT ID SQL: "+err.message);
-        });
-        
-    },
-    function(err) {
-        console.log("Transaction failed: " + err.message);
-    });
-
-
-};
-
-var readDatabase = function(index) {
-    var db = dbs[index];
-  if (!db) {
-        db = dbs[index] = openDb(index);
-        if (!db) {
-            return;
-        }
-    }
-    db.transaction(function (tx) {
-        tx.executeSql('SELECT * FROM DEMO WHERE id=2', [], function (tx, results) {
-            var len = results.rows.length;
-            var text = "DEMO table: " + len + " rows found.<br>";
-            text = text + "<table border='1'><tr><td>Row</td><td>Data</td></tr>";
-            for (var i=0; i<len; i++){
-                text = text + "<tr><td>" + i + "</td><td>" + results.rows.item(i).id + ", " + results.rows.item(i).data + "</td></tr>";
-            }
-            text = text + "</table>";
-            databaseOutput(text);
-        }, function(tx, err) {
-            alert("Error processing SELECT * WHERE id=2 SQL: "+err.message);
-        });
-    });
-}
-
-function increaseQuota(index) {
-    quotas[index] *= 2;
-    databaseOutput('quota ' + index + ' is now ' + quotas[index]);
-}
-
-var databaseOutput = function(s) {
-    var el = document.getElementById("database_results");
-    el.innerHTML = el.innerHTML + s + "<br>";
-    el.scrollByLines(20000);
-};
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-        console.log("Device="+device.platform+" "+device.version);
-    }, false);
-}
-
-window.onload = function() {
-  addListenerToClass('callDatabase0', callDatabase, [0]);
-  addListenerToClass('readDatabase0', readDatabase, [0]);
-  addListenerToClass('increaseQuota0', increaseQuota, [0]);
-  addListenerToClass('callDatabase1', callDatabase, 1);
-  addListenerToClass('readDatabase1', readDatabase, 1);
-  addListenerToClass('increaseQuota1', increaseQuota, 1);
-  addListenerToClass('reloadPage', function() {
-    location = location.href;
-  });
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/storage/index.html
----------------------------------------------------------------------
diff --git a/storage/index.html b/storage/index.html
deleted file mode 100644
index 0b713a2..0000000
--- a/storage/index.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Local Storage</h1>
-    <div id="info">
-        You have run this app <span id="count">an untold number of</span> time(s).
-    </div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/storage/index.js
----------------------------------------------------------------------
diff --git a/storage/index.js b/storage/index.js
deleted file mode 100644
index 00ae7e1..0000000
--- a/storage/index.js
+++ /dev/null
@@ -1,27 +0,0 @@
-var deviceReady = false;
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-      if (!deviceReady) {
-        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-      }
-    },1000);
-}
-
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-  init();
-
-  if (!localStorage.pageLoadCount) {
-      localStorage.pageLoadCount = 0;
-  }
-  localStorage.pageLoadCount = parseInt(localStorage.pageLoadCount) + 1;
-  document.getElementById('count').textContent = localStorage.pageLoadCount;
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/vibration/index.html
----------------------------------------------------------------------
diff --git a/vibration/index.html b/vibration/index.html
deleted file mode 100644
index a24110e..0000000
--- a/vibration/index.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Vibrations</h1>
-    <div id="info">
-    </div>
-    
-    <h2>Action</h2>
-    <div class="btn large vibrate">Vibrate</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/vibration/index.js
----------------------------------------------------------------------
diff --git a/vibration/index.js b/vibration/index.js
deleted file mode 100644
index 0d28902..0000000
--- a/vibration/index.js
+++ /dev/null
@@ -1,31 +0,0 @@
-var deviceReady = false;
-
-//-------------------------------------------------------------------------
-// Vibrations
-//-------------------------------------------------------------------------
-
-var vibrate = function(){
-  navigator.notification.vibrate(2500);
-};
-
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-        if (!deviceReady) {
-            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-        }
-    },1000);
-}
-
-window.onload = function() {
-  addListenerToClass('vibrate', vibrate);
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/accelerometer/index.html
----------------------------------------------------------------------
diff --git a/www/accelerometer/index.html b/www/accelerometer/index.html
new file mode 100644
index 0000000..71000b8
--- /dev/null
+++ b/www/accelerometer/index.html
@@ -0,0 +1,51 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Acceleration</h1>
+    <div id="info">
+        <div id="accel_status">Stopped</div>
+        <div ><table width="100%">
+            <tr><td width="20%">X:</td><td id="x"> </td></tr>
+            <tr><td width="20%">Y:</td><td id="y"> </td></tr>
+            <tr><td width="20%">Z:</td><td id="z"> </td></tr>
+        </table></div>
+    </div>
+
+    <h2>Action</h2>
+    <div class="btn large getAccel">Get Acceleration</div>
+    <div class="btn large watchAccel">Start Watch</div>
+    <div class="btn large stopAccel">Clear Watch</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/accelerometer/index.js
----------------------------------------------------------------------
diff --git a/www/accelerometer/index.js b/www/accelerometer/index.js
new file mode 100644
index 0000000..946cfe2
--- /dev/null
+++ b/www/accelerometer/index.js
@@ -0,0 +1,111 @@
+var deviceReady = false;
+
+function roundNumber(num) {
+    var dec = 3;
+    var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
+    return result;
+}
+
+//-------------------------------------------------------------------------
+// Acceleration
+//-------------------------------------------------------------------------
+var watchAccelId = null;
+
+/**
+ * Start watching acceleration
+ */
+var watchAccel = function() {
+    console.log("watchAccel()");
+
+    // Success callback
+    var success = function(a){
+        document.getElementById('x').innerHTML = roundNumber(a.x);
+        document.getElementById('y').innerHTML = roundNumber(a.y);
+        document.getElementById('z').innerHTML = roundNumber(a.z);
+        console.log("watchAccel success callback");
+    };
+
+    // Fail callback
+    var fail = function(e){
+        console.log("watchAccel fail callback with error code "+e);
+        stopAccel();
+        setAccelStatus(Accelerometer.ERROR_MSG[e]);
+    };
+
+    // Update acceleration every 1 sec
+    var opt = {};
+    opt.frequency = 1000;
+    watchAccelId = navigator.accelerometer.watchAcceleration(success, fail, opt);
+
+    setAccelStatus("Running");
+};
+
+/**
+ * Stop watching the acceleration
+ */
+var stopAccel = function() {
+	console.log("stopAccel()");
+    setAccelStatus("Stopped");
+    if (watchAccelId) {
+        navigator.accelerometer.clearWatch(watchAccelId);
+        watchAccelId = null;
+    }
+};
+
+/**
+ * Get current acceleration
+ */
+var getAccel = function() {
+    console.log("getAccel()");
+
+    // Stop accel if running
+    stopAccel();
+
+    // Success callback
+    var success = function(a){
+        document.getElementById('x').innerHTML = roundNumber(a.x);
+        document.getElementById('y').innerHTML = roundNumber(a.y);
+        document.getElementById('z').innerHTML = roundNumber(a.z);
+    };
+
+    // Fail callback
+    var fail = function(e){
+        console.log("getAccel fail callback with error code "+e);
+        setAccelStatus(Accelerometer.ERROR_MSG[e]);
+    };
+
+    // Make call
+    var opt = {};
+    navigator.accelerometer.getCurrentAcceleration(success, fail, opt);
+};
+
+/**
+ * Set accelerometer status
+ */
+var setAccelStatus = function(status) {
+    document.getElementById('accel_status').innerHTML = status;
+};
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    console.log("accelerometer.init()");
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+    	if (!deviceReady) {
+    		alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+    	}
+    },1000);
+}
+
+window.onload = function() {
+  addListenerToClass('getAccel', getAccel);
+  addListenerToClass('watchAccel', watchAccel);
+  addListenerToClass('stopAccel', stopAccel);
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/audio/index.html
----------------------------------------------------------------------
diff --git a/www/audio/index.html b/www/audio/index.html
new file mode 100644
index 0000000..a05ea04
--- /dev/null
+++ b/www/audio/index.html
@@ -0,0 +1,88 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Audio Tests</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Audio</h1>  
+    <div id="info">
+        <table width="100%">
+        <tr><td><b>Status:</b></td><td id="audio_status"> </td></tr>
+        <tr><td><b>Duration:</b></td><td id="audio_duration"></td></tr>
+        <tr><td><b>Position:</b></td><td id="audio_position"></td></tr>
+        </table>
+    </div>
+    <h2>Action</h2>
+    <table style="width:80%;">
+        <tr>
+            <th colspan=3>Play Sample Audio</th>
+        </tr>
+        <tr>
+            <td><div class="btn wide playAudio">Play</div></td>
+            <td><div class="btn wide pauseAudio">Pause</div></td>
+        </tr>
+        <tr>
+            <td><div class="btn wide stopAudio">Stop</div></td>
+            <td><div class="btn wide releaseAudio">Release</div></td>
+        </tr>
+    </table>
+    
+    <table style="width:80%;">
+        <tr>
+            <td><div class="btn wide seekAudioBy">Seek By</div></td>
+            <td><div class="btn wide seekAudioTo">Seek To</div></td>
+            <td>
+                <div>
+                    <input class="input numeric" type="number" id="seekinput" value="in seconds">
+                </div>
+            </td>
+        </tr>
+    </table>
+    
+    <table style="width:80%;">
+        <tr>
+            <th colspan=3><br><br>Record Audio</th>
+        </tr>
+        <tr>
+            <td colspan=3><div class="btn wide recordAudio">Record Audio for 10 sec</a></td>
+        </tr>
+        <tr>
+            <td><div class="btn wide playRecording">Play</div></td>
+            <td><div class="btn wide pauseAudio">Pause</div></td>
+            <td><div class="btn wide stopAudio">Stop</div></td>
+        </tr>
+    </table>
+    
+    <h2> </h2><div class="backBtn">Back</div>
+    
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/audio/index.js
----------------------------------------------------------------------
diff --git a/www/audio/index.js b/www/audio/index.js
new file mode 100644
index 0000000..e7ca9b6
--- /dev/null
+++ b/www/audio/index.js
@@ -0,0 +1,356 @@
+var defaultaudio = "http://cordova.apache.org/downloads/BlueZedEx.mp3";
+var deviceReady = false;
+
+//-------------------------------------------------------------------------
+// Audio player
+//-------------------------------------------------------------------------
+var media1 = null;
+var media1Timer = null;
+var audioSrc = null;
+var recordSrc = "myRecording.mp3";
+
+/**
+ * Play audio
+ */
+function playAudio(url) {
+    console.log("playAudio()");
+    console.log(" -- media="+media1);
+
+  var src = defaultaudio;
+    
+    if (url) {
+        src = url;
+    }
+
+    // Stop playing if src is different from currently playing source
+    if (src != audioSrc) {
+        if (media1 != null) {
+            stopAudio();
+            media1 = null;
+        }
+    }
+
+    if (media1 == null) {
+
+
+        // TEST STREAMING AUDIO PLAYBACK
+        //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3";   // works
+        //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
+        //var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
+        //var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
+        //var src = "MusicSearch/mp3/train.mp3";    // works
+        //var src = "bryce.mp3";  // works
+        //var src = "/android_asset/www/bryce.mp3"; // works
+
+        media1 = new Media(src,
+            function() {
+                console.log("playAudio():Audio Success");
+            },
+            function(err) {
+                console.log("playAudio():Audio Error: "+err.code);
+                setAudioStatus("Error: " + err.code);
+            },
+            function(status) {
+                console.log("playAudio():Audio Status: "+status);
+                setAudioStatus(Media.MEDIA_MSG[status]);
+
+                // If stopped, then stop getting current position
+                if (Media.MEDIA_STOPPED == status) {
+                    clearInterval(media1Timer);
+                    media1Timer = null;
+                    setAudioPosition("0 sec");
+                }
+            });
+    }
+    audioSrc = src;
+    document.getElementById('audio_duration').innerHTML = "";
+    // Play audio
+    media1.play();
+    if (media1Timer == null && media1.getCurrentPosition) {
+        media1Timer = setInterval(
+            function() {
+                media1.getCurrentPosition(
+                    function(position) {
+                        console.log("Pos="+position);
+                        if (position >= 0.0) {
+                            setAudioPosition(position+" sec");
+                        }
+                    },
+                    function(e) {
+                        console.log("Error getting pos="+e);
+                        setAudioPosition("Error: "+e);
+                    }
+                );
+            },
+            1000
+        );
+    }
+
+    // Get duration
+    var counter = 0;
+    var timerDur = setInterval(
+        function() {
+            counter = counter + 100;
+            if (counter > 2000) {
+                clearInterval(timerDur);
+            }
+            var dur = media1.getDuration();
+            if (dur > 0) {
+                clearInterval(timerDur);
+                document.getElementById('audio_duration').innerHTML = dur + " sec";
+            }
+        }, 100);
+}
+
+/**
+ * Pause audio playback
+ */
+function pauseAudio() {
+    console.log("pauseAudio()");
+    if (media1) {
+        media1.pause();
+    }
+}
+
+/**
+ * Stop audio
+ */
+function stopAudio() {
+    console.log("stopAudio()");
+    if (media1) {
+        media1.stop();
+    }
+    clearInterval(media1Timer);
+    media1Timer = null;
+}
+
+/**
+ * Release audio
+ */
+function releaseAudio() {
+  console.log("releaseAudio()");
+  if (media1) {
+  	media1.stop(); //imlied stop of playback, resets timer
+  	media1.release();
+  }
+}
+
+
+/**
+ * Set audio status
+ */
+function setAudioStatus(status) {
+    document.getElementById('audio_status').innerHTML = status;
+};
+
+/**
+ * Set audio position
+ */
+function setAudioPosition(position) {
+    document.getElementById('audio_position').innerHTML = position;
+};
+
+//-------------------------------------------------------------------------
+// Audio recorder
+//-------------------------------------------------------------------------
+var mediaRec = null;
+var recTime = 0;
+
+/**
+ * Record audio
+ */
+function recordAudio() {
+    console.log("recordAudio()");
+    console.log(" -- media="+mediaRec);
+    if (mediaRec == null) {
+
+        var src = recordSrc;
+        mediaRec = new Media(src,
+                function() {
+                    console.log("recordAudio():Audio Success");
+                },
+                function(err) {
+                    console.log("recordAudio():Audio Error: "+err.code);
+                    setAudioStatus("Error: " + err.code);
+                },
+                function(status) {
+                    console.log("recordAudio():Audio Status: "+status);
+                    setAudioStatus(Media.MEDIA_MSG[status]);
+                }
+            );
+    }
+
+    navigator.notification.beep(1);
+
+    // Record audio
+    mediaRec.startRecord();
+
+    // Stop recording after 10 sec
+    recTime = 0;
+    var recInterval = setInterval(function() {
+        recTime = recTime + 1;
+        setAudioPosition(recTime+" sec");
+        if (recTime >= 10) {
+            clearInterval(recInterval);
+            if (mediaRec.stopAudioRecord){
+                mediaRec.stopAudioRecord();
+            } else {
+                mediaRec.stopRecord();
+            }
+            console.log("recordAudio(): stop");
+            navigator.notification.beep(1);
+        }
+    }, 1000);
+}
+
+/**
+ * Play back recorded audio
+ */
+function playRecording() {
+    playAudio(recordSrc);
+}
+
+/**
+ * Function to create a file for iOS recording
+ */
+function getRecordSrc() {
+    var fsFail = function(error) {
+        console.log("error creating file for iOS recording");
+    };
+    var gotFile = function(file) {
+        recordSrc = file.fullPath;
+        //console.log("recording Src: " + recordSrc);
+    };
+    var gotFS = function(fileSystem) {
+        fileSystem.root.getFile("iOSRecording.wav", {create: true}, gotFile, fsFail);
+    };
+    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
+}
+
+/**
+ * Function to create a file for BB recording
+ */
+function getRecordSrcBB() {
+    var fsFail = function(error) {
+        console.log("error creating file for BB recording");
+    };
+    var gotFile = function(file) {
+        recordSrc = file.fullPath;
+    };
+    var gotFS = function(fileSystem) {
+        fileSystem.root.getFile("BBRecording.amr", {create: true}, gotFile, fsFail);
+    };
+    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
+}
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            if (device.platform.indexOf("iOS") !=-1)
+            {
+                 getRecordSrc();
+            } else if (typeof blackberry !== 'undefined') {
+                getRecordSrcBB();
+            }
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+    	if (!deviceReady) {
+    		alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+    	}
+    },1000);
+}
+
+/**
+ * for forced updates of position after a successful seek
+ */
+function updatePosition() {
+    media1.getCurrentPosition(
+        function(position) {
+            console.log("Pos="+position);
+            if (position >= 0.0) {
+                setAudioPosition(position+" sec");
+            }
+        },
+        function(e) {
+            console.log("Error getting pos="+e);
+            setAudioPosition("Error: "+e);
+        });
+}
+
+/**
+ *
+ */
+function seekAudio(mode) {
+    var time = document.getElementById("seekinput").value;
+    if (time == "") {
+        time = 5000;
+    } else {
+        time = time * 1000; //we expect the input to be in seconds
+    }
+    if (media1 == null) {
+        console.log("seekTo requested while media1 is null");
+        if (audioSrc == null) {
+            audioSrc = defaultaudio;
+        }
+        media1 = new Media(audioSrc,
+            function() {
+                console.log("seekToAudio():Audio Success");
+            },
+            function(err) {
+                console.log("seekAudio():Audio Error: "+err.code);
+                setAudioStatus("Error: " + err.code);
+            },
+            function(status) {
+                console.log("seekAudio():Audio Status: "+status);
+                setAudioStatus(Media.MEDIA_MSG[status]);
+
+                // If stopped, then stop getting current position
+                if (Media.MEDIA_STOPPED == status) {
+                    clearInterval(media1Timer);
+                    media1Timer = null;
+                    setAudioPosition("0 sec");
+                }
+            });
+    }
+    
+    media1.getCurrentPosition(
+        function (position) {
+            var deltat = time;
+            if (mode == "by") {
+                deltat = time + position * 1000;   
+            }
+            media1.seekTo(deltat,
+                function () {
+                    console.log("seekAudioTo():Audio Success");
+                    //force an update on the position display
+                    updatePosition();
+                },
+                function (err) {
+                    console.log("seekAudioTo():Audio Error: " + err.code);
+                });
+        },
+        function(e) {
+            console.log("Error getting pos="+e);
+            setAudioPosition("Error: "+e);
+        });
+}
+
+window.onload = function() {
+  addListenerToClass('playAudio', function () {
+    playAudio();
+  });
+  addListenerToClass('pauseAudio', pauseAudio);
+  addListenerToClass('stopAudio', stopAudio);
+  addListenerToClass('releaseAudio', releaseAudio);
+  addListenerToClass('seekAudioBy', seekAudio, 'by');
+  addListenerToClass('seekAudioTo', seekAudio, 'to');
+  addListenerToClass('recordAudio', recordAudio);
+  addListenerToClass('playRecording', playRecording);
+
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/html/HtmlReporter.js
----------------------------------------------------------------------
diff --git a/www/autotest/html/HtmlReporter.js b/www/autotest/html/HtmlReporter.js
new file mode 100644
index 0000000..7d9d924
--- /dev/null
+++ b/www/autotest/html/HtmlReporter.js
@@ -0,0 +1,101 @@
+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);

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/html/HtmlReporterHelpers.js
----------------------------------------------------------------------
diff --git a/www/autotest/html/HtmlReporterHelpers.js b/www/autotest/html/HtmlReporterHelpers.js
new file mode 100644
index 0000000..745e1e0
--- /dev/null
+++ b/www/autotest/html/HtmlReporterHelpers.js
@@ -0,0 +1,60 @@
+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];
+  }
+};
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/html/ReporterView.js
----------------------------------------------------------------------
diff --git a/www/autotest/html/ReporterView.js b/www/autotest/html/ReporterView.js
new file mode 100644
index 0000000..6a6d005
--- /dev/null
+++ b/www/autotest/html/ReporterView.js
@@ -0,0 +1,164 @@
+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);
+
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/html/SpecView.js
----------------------------------------------------------------------
diff --git a/www/autotest/html/SpecView.js b/www/autotest/html/SpecView.js
new file mode 100644
index 0000000..e8a3c23
--- /dev/null
+++ b/www/autotest/html/SpecView.js
@@ -0,0 +1,79 @@
+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);

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/html/SuiteView.js
----------------------------------------------------------------------
diff --git a/www/autotest/html/SuiteView.js b/www/autotest/html/SuiteView.js
new file mode 100644
index 0000000..19a1efa
--- /dev/null
+++ b/www/autotest/html/SuiteView.js
@@ -0,0 +1,22 @@
+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);
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/html/TrivialReporter.js
----------------------------------------------------------------------
diff --git a/www/autotest/html/TrivialReporter.js b/www/autotest/html/TrivialReporter.js
new file mode 100644
index 0000000..167ac50
--- /dev/null
+++ b/www/autotest/html/TrivialReporter.js
@@ -0,0 +1,192 @@
+/* @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-mobile-spec/blob/77ff9a37/www/autotest/index.html
----------------------------------------------------------------------
diff --git a/www/autotest/index.html b/www/autotest/index.html
new file mode 100644
index 0000000..3a41d78
--- /dev/null
+++ b/www/autotest/index.html
@@ -0,0 +1,63 @@
+<!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 http-equiv="Content-Type" content="text/html;charset=UTF-8" />
+    <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+
+    <title>Cordova API Specs</title>
+
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+    <h1>Cordova API Specs</h1>
+
+    <a href="pages/all.html" class="btn large" style="width:100%;">Run All Tests</a>
+    <a href="pages/accelerometer.html" class="btn large" style="width:100%;">Run Accelerometer Tests</a>
+    <a href="pages/battery.html" class="btn large" style="width:100%;">Run Battery Tests</a>
+    <a href="pages/camera.html" class="btn large" style="width:100%;">Run Camera Tests</a>
+    <a href="pages/capture.html" class="btn large" style="width:100%;">Run Capture Tests</a>
+    <a href="pages/compass.html" class="btn large" style="width:100%;">Run Compass Tests</a>
+    <a href="pages/contacts.html" class="btn large" style="width:100%;">Run Contacts Tests</a>
+    <a href="pages/datauri.html" class="btn large" style="width:100%;">Run Data URI Tests</a>
+    <a href="pages/device.html" class="btn large" style="width:100%;">Run Device Tests</a>
+    <a href="pages/file.html" class="btn large" style="width:100%;">Run File Tests</a>
+    <a href="pages/filetransfer.html" class="btn large" style="width:100%;">Run FileTransfer Tests</a>
+    <a href="pages/geolocation.html" class="btn large" style="width:100%;">Run Geolocation Tests</a>
+    <a href="pages/globalization.html" class="btn large" style="width:100%;">Run Globalization Tests</a>
+    <a href="pages/media.html" class="btn large" style="width:100%;">Run Media Tests</a>
+    <a href="pages/network.html" class="btn large" style="width:100%;">Run Network Tests</a>
+    <a href="pages/notification.html" class="btn large" style="width:100%;">Run Notification Tests</a>
+    <a href="pages/platform.html" class="btn large" style="width:100%;">Run Platform Tests</a>
+    <a href="pages/storage.html" class="btn large" style="width:100%;">Run Storage Tests</a>
+    <a href="pages/bridge.html" class="btn large" style="width:100%;">Run Bridge Tests</a>
+    <a href="pages/splashscreen.html" class="btn large" style="width:100%;">Run Splashscreen Tests</a>
+    <a href="pages/whitelist.html" class="btn large" style="width:100%;">Run Whitelist Tests</a>
+    <a href="pages/localXHR.html" class="btn large" style="width:100%;">Run local XHR Tests</a>
+    <a href="pages/vibration.html" class="btn large" style="width:100%;">Run Vibration Tests</a>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/index.js
----------------------------------------------------------------------
diff --git a/www/autotest/index.js b/www/autotest/index.js
new file mode 100644
index 0000000..aec19b4
--- /dev/null
+++ b/www/autotest/index.js
@@ -0,0 +1,4 @@
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/jasmine.css
----------------------------------------------------------------------
diff --git a/www/autotest/jasmine.css b/www/autotest/jasmine.css
new file mode 100644
index 0000000..826e575
--- /dev/null
+++ b/www/autotest/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; }


[02/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/file/index.html
----------------------------------------------------------------------
diff --git a/www/file/index.html b/www/file/index.html
new file mode 100644
index 0000000..8f00e86
--- /dev/null
+++ b/www/file/index.html
@@ -0,0 +1,72 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+
+    <h1>File and File Transfer</h1>
+    <h2>File</h2>
+    <div class="btn large" id="downloadImgCDV">Download and display img (cdvfile)</div>
+    <div class="btn large" id="downloadImgNative">Download and display img (native)</div>
+    <div class="btn large" id="downloadVideoCDV">Download and play video (cdvfile)</div>
+    <div class="btn large" id="downloadVideoNative">Download and play video (native)</div>
+
+    <div class="ios platform">
+        <h2>iOS Special URL handling</h2>
+        <div class="btn large" id="testPrivateURL">Test /private/ URL (iOS)</div>
+
+        <h2>iOS Extra File Systems</h2>
+        <div class="btn large resolveFs" data-fsname="library">Resolve library FS</div>
+        <div class="btn large resolveFs" data-fsname="library-nosync">Resolve library-nosync FS</div>
+        <div class="btn large resolveFs" data-fsname="documents">Resolve documents FS</div>
+        <div class="btn large resolveFs" data-fsname="documents-nosync">Resolve documents-nosync FS</div>
+        <div class="btn large resolveFs" data-fsname="cache">Resolve cache FS</div>
+        <div class="btn large resolveFs" data-fsname="bundle">Resolve bundle FS</div>
+        <div class="btn large resolveFs" data-fsname="root">Resolve root FS</div>
+    </div>
+
+    <div class="android platform">
+        <h2>Android Extra File Systems</h2>
+        <div class="btn large resolveFs" data-fsname="files">Resolve files FS</div>
+        <div class="btn large resolveFs" data-fsname="files-external">Resolve files-external FS</div>
+        <div class="btn large resolveFs" data-fsname="documents">Resolve documents FS</div>
+        <div class="btn large resolveFs" data-fsname="sdcard">Resolve sdcard FS</div>
+        <div class="btn large resolveFs" data-fsname="cache">Resolve cache FS</div>
+        <div class="btn large resolveFs" data-fsname="cache-external">Resolve cache-external FS</div>
+        <div class="btn large resolveFs" data-fsname="root">Resolve root FS</div>
+    </div>
+
+    <div id="log"></div>
+    <div id="output"></div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/file/index.js
----------------------------------------------------------------------
diff --git a/www/file/index.js b/www/file/index.js
new file mode 100644
index 0000000..1f570dd
--- /dev/null
+++ b/www/file/index.js
@@ -0,0 +1,153 @@
+var deviceReady = false;
+
+var imageURL = "http://apache.org/images/feather-small.gif";
+var videoURL = "http://techslides.com/demos/sample-videos/small.mp4";
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+            bindEvents();
+            document.body.classList.add(device.platform.toLowerCase() + "-platform");
+        }, false);
+    window.setTimeout(function() {
+        if (!deviceReady) {
+            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+        }
+    },1000);
+}
+
+function bindEvents() {
+    document.getElementById('downloadImgCDV').addEventListener('click', downloadImgCDV, false);
+    document.getElementById('downloadImgNative').addEventListener('click', downloadImgNative, false);
+    document.getElementById('downloadVideoCDV').addEventListener('click', downloadVideoCDV, false);
+    document.getElementById('downloadVideoNative').addEventListener('click', downloadVideoNative, false);
+    document.getElementById('testPrivateURL').addEventListener('click', testPrivateURL, false);
+    var fsButtons = document.querySelectorAll('.resolveFs');
+    for (var i=0; i < fsButtons.length; ++i) {
+        fsButtons[i].addEventListener('click', resolveFs, false);
+    }
+}
+
+function clearLog() {
+    var log = document.getElementById("log");
+    log.innerHTML = "";
+}
+
+function logMessage(message, color) {
+    var log = document.getElementById("log");
+    var logLine = document.createElement('div');
+    if (color) {
+        logLine.style.color = color;
+    }
+    logLine.innerHTML = message;
+    log.appendChild(logLine);
+}
+
+function logError(serviceName) {
+    return function(err) {
+        logMessage("ERROR: " + serviceName + " " + JSON.stringify(err), "red");
+    };
+}
+
+function downloadImgCDV(ev) {
+    ev.preventDefault();
+    ev.stopPropagation();
+    downloadImg(imageURL, function(entry) { return entry.toURL(); }, new Image());
+}
+
+function downloadImgNative(ev) {
+    ev.preventDefault();
+    ev.stopPropagation();
+    downloadImg(imageURL, function(entry) { return entry.toNativeURL(); }, new Image);
+}
+
+function downloadVideoCDV(ev) {
+    ev.preventDefault();
+    ev.stopPropagation();
+    var videoElement = document.createElement('video');
+    videoElement.controls = "controls";
+    downloadImg(videoURL, function(entry) { return entry.toURL(); }, videoElement);
+}
+
+function downloadVideoNative(ev) {
+    ev.preventDefault();
+    ev.stopPropagation();
+    var videoElement = document.createElement('video');
+    videoElement.controls = "controls";
+    downloadImg(videoURL, function(entry) { return entry.toNativeURL(); }, videoElement);
+}
+
+function downloadImg(source, urlFn, element) {
+    var filename = source.substring(source.lastIndexOf("/")+1);
+    function download(fileSystem) {
+        var ft = new FileTransfer();
+        logMessage("Starting download");
+        ft.download(source, fileSystem.root.toURL() + filename, function(entry) {
+            logMessage("Download complete")
+            element.src = urlFn(entry)
+            logMessage("Src URL is " + element.src, "green");
+            logMessage("Inserting element");
+            document.getElementById("output").appendChild(element);
+        }, logError("ft.download"));
+    }
+    clearLog();
+    logMessage("Requesting filesystem");
+    requestFileSystem(TEMPORARY, 0, function(fileSystem) {
+        logMessage("Checking for existing file");
+        fileSystem.root.getFile(filename, {create: false}, function(entry) {
+            logMessage("Removing existing file");
+            entry.remove(function() {
+                download(fileSystem);
+            }, logError("entry.remove"));
+        }, function() {
+            download(fileSystem);
+        });
+    }, logError("requestFileSystem"));
+}
+
+function testPrivateURL(ev) {
+    ev.preventDefault();
+    ev.stopPropagation();
+    requestFileSystem(TEMPORARY, 0, function(fileSystem) {
+        logMessage("Temporary root is at " + fileSystem.root.toNativeURL());
+        fileSystem.root.getFile("testfile", {create: true}, function(entry) {
+            logMessage("Temporary file is at " + entry.toNativeURL());
+            if (entry.toNativeURL().substring(0,12) == "file:///var/") {
+                logMessage("File starts with /var/, trying /private/var");
+                var newURL = "file://localhost/private/var/" + entry.toNativeURL().substring(12) + "?and=another_thing";
+                //var newURL = entry.toNativeURL();
+                logMessage(newURL, 'blue');
+                resolveLocalFileSystemURL(newURL, function(newEntry) {
+                    logMessage("Successfully resolved.", 'green');
+                    logMessage(newEntry.toURL(), 'blue');
+                    logMessage(newEntry.toNativeURL(), 'blue');
+                }, logError("resolveLocalFileSystemURL"));
+            }
+        }, logError("getFile"));
+    }, logError("requestFileSystem"));
+}
+
+function resolveFs(ev) {
+    var fsURL = "cdvfile://localhost/" + ev.target.getAttribute('data-fsname') + "/";
+    logMessage("Resolving URL: " + fsURL);
+    resolveLocalFileSystemURL(fsURL, function(entry) {
+        logMessage("Success", 'green');
+        logMessage(entry.toURL(), 'blue');
+        logMessage(entry.toInternalURL(), 'blue');
+        logMessage("Resolving URL: " + entry.toURL());
+        resolveLocalFileSystemURL(entry.toURL(), function(entry2) {
+            logMessage("Success", 'green');
+            logMessage(entry2.toURL(), 'blue');
+            logMessage(entry2.toInternalURL(), 'blue');
+        }, logError("resolveLocalFileSystemURL"));
+    }, logError("resolveLocalFileSystemURL"));
+}
+
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/index.html
----------------------------------------------------------------------
diff --git a/www/inappbrowser/index.html b/www/inappbrowser/index.html
new file mode 100644
index 0000000..b06ed11
--- /dev/null
+++ b/www/inappbrowser/index.html
@@ -0,0 +1,236 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>InAppBrowser</h1>
+    <div id="info">
+        Make sure http://www.google.com is white listed. </br>
+        Make sure http://www.apple.com is not in the white list.</br>  In iOS, starred <span style="vertical-align:super">*</span> tests will put the app in a state with no way to return.  </br>
+        <h4>User-Agent: <span id="user-agent"> </span></h4>
+    </div>
+    <div class="btn small backBtn">Back</div>
+
+    <h1>Local URL</h1>
+    <div class="btn large openLocal">target = Default</div>
+    Expected result: opens successfully in CordovaWebView.
+
+    <p/>
+    <div class="btn large openLocalSelf">target=_self</div>
+    Expected result: opens successfully in CordovaWebView.
+
+    <p/>
+    <div class="btn large openLocalSystem">target=_system</div>
+    Expected result: fails to open.
+
+    <p/>
+    <div class="btn large openLocalBlank">target=_blank</div>
+    Expected result: opens successfully in InAppBrowser with locationBar at top.
+
+    <p/>
+    <div class="btn large openLocalRandomNoLocation">target=Random, location=no,disallowoverscroll=yes</div>
+    Expected result: opens successfully in InAppBrowser without locationBar.
+
+    <p/>
+    <div class="btn large openLocalRandomToolBarBottom">target=Random, toolbarposition=bottom</div>
+    Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the bottom.
+
+    <p/>
+    <div class="btn large openLocalRandomToolBarTop">target=Random, toolbarposition=top</div>
+    Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the top.
+
+    <p/>
+    <div class="btn large openLocalRandomToolBarTopNoLocation">target=Random, toolbarposition=top,location=no</div>
+    Expected result: opens successfully in InAppBrowser with no locationBar. On iOS the toolbar is at the top.
+
+    <h1>White Listed URL</h1>
+
+    <div class="btn large openWhiteListed">target=Default<span style="vertical-align:super">*</span></div>
+    Expected result: open successfully in CordovaWebView to www.google.com.
+
+    <p/>
+    <div class="btn large openWhiteListedSelf">target=_self<span style="vertical-align:super">*</span></div>
+    Expected result: open successfully in CordovaWebView to www.google.com.
+
+    <p/>
+    <div class="btn large openWhiteListedSystem">target=_system</div>
+    Expected result: open successfully in system browser to www.google.com.
+
+    <p/>
+    <div class="btn large openWhiteListedBlank">target=_blank</div>
+    Expected result: open successfully in InAppBrowser to www.google.com.
+
+    <p/>
+    <div class="btn large openWhiteListedRandom">target=Random</div>
+    Expected result: open successfully in InAppBrowser to www.google.com.
+
+    <p/>
+    <div class="btn large openWhiteListedRandomNoLocation">target=Random, no location bar<span style="vertical-align:super">*</span></div>
+    Expected result: open successfully in InAppBrowser to www.google.com with no location bar.
+
+    <h1>Non White Listed URL</h1>
+
+    <div class="btn large openNonWhiteListed">target=Default</div>
+    Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).
+
+    <p/>
+    <div class="btn larg openNonWhiteListedSelf">target=_self</div>
+    Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).
+
+    <p/>
+    <div class="btn large openNonWhiteListedSystem">target=_system</div>
+    Expected result: open successfully in system browser to apple.com.
+
+    <p/>
+    <div class="btn large openNonWhiteListedBlank">target=_blank</div>
+    Expected result: open successfully in InAppBrowser to apple.com.
+
+    <p/>
+    <div class="btn large openNonWhiteListedRandom">target=Random</div>
+    Expected result: open successfully in InAppBrowser to apple.com.
+
+    <p/>
+    <div class="btn large openNonWhiteListedRandomNoLocation">target=Random, no location bar<span style="vertical-align:super">*</span></div>
+    Expected result: open successfully in InAppBrowser to apple.com without locationBar.
+
+    <h1>Page with redirect</h1>
+
+    <div class="btn large openRedirect301">http://google.com</div>
+    Expected result: should 301 and open successfully in InAppBrowser to www.google.com.
+
+    <p/>
+    <div class="btn large openRedirect302">http://goo.gl/pUFqg</div>
+    Expected result: should 302 and open successfully in InAppBrowser to www.zhihu.com/answer/16714076.
+
+    <h1>PDF URL</h1>
+
+    <div class="btn large openPDF">Remote URL</div>
+    Expected result: InAppBrowser opens. PDF should render on iOS.
+
+    <p/>
+    <div class="btn large openPDFBlank">Local URL</div>
+    Expected result: InAppBrowser opens. PDF should render on iOS.
+
+    <h1>Invalid URL</h1>
+
+    <div class="btn large openInvalidScheme">Invalid Scheme</div>
+    Expected result: fail to load in InAppBrowser.
+
+    <p/>
+    <div class="btn large openInvalidHost">Invalid Host</div>
+    Expected result: fail to load in InAppBrowser.
+
+    <p/>
+    <div class="btn large openInvalidMissing">Missing Local File</div>
+    Expected result: fail to load in InAppBrowser (404).
+
+    <h1>CSS / JS Injection</h1>
+
+    <div class="btn large openOriginalDocument">Original Document</div>
+    Expected result: open successfully in InAppBrowser without text "Style updated from..."
+
+    <p/> 
+    <div class="btn large openCSSInjection">CSS File Injection</div>
+    Expected result: open successfully in InAppBrowser with "Style updated from file".
+
+    <p/>
+    <div class="btn large openCSSInjectionCallback">CSS File Injection (callback)</div>
+    Expected result: open successfully in InAppBrowser with "Style updated from file", and alert dialog with text "Results verified".
+
+    <p/>
+    <div class="btn large openCSSLiteralInjection">CSS Literal Injection</div>
+    Expected result: open successfully in InAppBrowser with "Style updated from literal".
+
+    <p/>
+    <div class="btn large openCSSLiteralInjectionCallback">CSS Literal Injection (callback)</div>
+    Expected result: open successfully in InAppBrowser with "Style updated from literal", and alert dialog with text "Results verified".
+
+    <p/>
+    <div class="btn large openScriptInjection">Script File Injection</div>
+    Expected result: open successfully in InAppBrowser with text "Script file successfully injected".
+
+    <p/>
+    <div class="btn large openScriptInjectionCallback">Script File Injection (callback)</div>
+    Expected result: open successfully in InAppBrowser with text "Script file successfully injected" and alert dialog with the text "Results verified".
+
+    <p/>
+    <div class="btn large openScriptLiteralInjection">Script Literal Injection</div>
+    Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" .
+
+    <p/>
+    <div class="btn large openScriptLiteralInjectionCallback">Script Literal Injection (callback)</div>
+    Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" and alert dialog with the text "Results verified".
+
+    <h1>Open Hidden </h1>
+    <div class="btn large openHidden">create hidden</div>
+    Expected result: no additional browser window. Alert appears with the text "background window loaded".
+
+    <p/>
+    <div class="btn large showHidden">show hidden</div>
+    Expected result: after first clicking on previous test "create hidden", open successfully in InAppBrowser to google.com.
+
+    <p/>
+    <div class="btn large closeHidden">close hidden</div>
+    Expected result: no output. But click on "show hidden" again and nothing should be shown.
+
+    <p/>
+    <div class="btn large openHiddenShow">google.com not hidden</div>
+    Expected result: open successfully in InAppBrowser to www.google.com
+
+    <h1>Clearing Cache</h1>
+
+    <div class="btn large openClearCache">Clear Browser Cache</div>
+    Expected result: ?
+
+    <p/>
+    <div class="btn large openClearSessionCache">Clear Session Cache</div>
+    Expected result: ?
+
+    <h1>Video tag</h1>
+
+    <div class="btn large openRemoteVideo">remote video</div>
+    Expected result: open successfully in InAppBrowser with an embedded video that works after clicking the "play" button.
+
+    <h1>Local with anchor tag</h1>
+
+    <div class="btn large openAnchor1">Anchor1</div>
+    Expected result: open successfully in InAppBrowser to the local page, scrolled to the top.
+
+    <p/>
+    <div class="btn large openAnchor2">Anchor2</div>
+    Expected result: open successfully in InAppBrowser to the local page, scrolled to the beginning of the tall div with border.
+    
+    <p/>
+    <div class="backBtn">Back</div>
+
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/index.js
----------------------------------------------------------------------
diff --git a/www/inappbrowser/index.js b/www/inappbrowser/index.js
new file mode 100644
index 0000000..a08c30d
--- /dev/null
+++ b/www/inappbrowser/index.js
@@ -0,0 +1,242 @@
+var deviceReady = false;
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    function updateUserAgent() {
+        document.getElementById("user-agent").textContent = navigator.userAgent;
+    }
+    updateUserAgent();
+    window.setInterval(updateUserAgent, 1500);
+    window.setTimeout(function() {
+      if (!deviceReady) {
+        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+      }
+    },1000);
+}
+
+function doOpen(url, target, params, numExpectedRedirects) {
+    numExpectedRedirects = numExpectedRedirects || 0;
+    var iab = window.open(url, target, params);
+    if (!iab) {
+        alert('window.open returned ' + iab);
+        return;
+    }
+    var counts;
+    var lastLoadStartURL;
+    var wasReset = false;
+    function reset()  {
+        counts = {
+            'loaderror': 0,
+            'loadstart': 0,
+            'loadstop': 0,
+            'exit': 0
+        };
+        lastLoadStartURL = '';
+    }
+    reset();
+
+    function logEvent(e) {
+        console.log('IAB event=' + JSON.stringify(e));
+        counts[e.type]++;
+        // Verify that event.url gets updated on redirects.
+        if (e.type == 'loadstart') {
+            if (e.url == lastLoadStartURL) {
+                alert('Unexpected: loadstart fired multiple times for the same URL.');
+            }
+            lastLoadStartURL = e.url;
+        }
+        // Verify the right number of loadstart events were fired.
+        if (e.type == 'loadstop' || e.type == 'loaderror') {
+            if (e.url != lastLoadStartURL) {
+                alert('Unexpected: ' + e.type + ' event.url != loadstart\'s event.url');
+            }
+            if (numExpectedRedirects === 0 && counts['loadstart'] !== 1) {
+                // Do allow a loaderror without a loadstart (e.g. in the case of an invalid URL).
+                if (!(e.type == 'loaderror' && counts['loadstart'] === 0)) {
+                    alert('Unexpected: got multiple loadstart events. (' + counts['loadstart'] + ')');
+                }
+            } else if (numExpectedRedirects > 0 && counts['loadstart'] < (numExpectedRedirects+1)) {
+                alert('Unexpected: should have got at least ' + (numExpectedRedirects+1) + ' loadstart events, but got ' + counts['loadstart']);
+            }
+            wasReset = true;
+            numExpectedRedirects = 0;
+            reset();
+        }
+        // Verify that loadend / loaderror was called.
+        if (e.type == 'exit') {
+            var numStopEvents = counts['loadstop'] + counts['loaderror'];
+            if (numStopEvents === 0 && !wasReset) {
+                alert('Unexpected: browser closed without a loadstop or loaderror.')
+            } else if (numStopEvents > 1) {
+                alert('Unexpected: got multiple loadstop/loaderror events.');
+            }
+        }
+    }
+    iab.addEventListener('loaderror', logEvent);
+    iab.addEventListener('loadstart', logEvent);
+    iab.addEventListener('loadstop', logEvent);
+    iab.addEventListener('exit', logEvent);
+
+    return iab;
+}
+
+function openWithStyle(url, cssUrl, useCallback) {
+    var iab = doOpen(url, '_blank', 'location=yes');
+    var callback = function(results) {
+        if (results && results.length === 0) {
+            alert('Results verified');
+        } else {
+            console.log(results);
+            alert('Got: ' + typeof(results) + '\n' + JSON.stringify(results));
+        }
+    };
+    if (cssUrl) {
+        iab.addEventListener('loadstop', function(event) {
+            iab.insertCSS({file: cssUrl}, useCallback && callback);
+        });
+    } else {
+        iab.addEventListener('loadstop', function(event) {
+            iab.insertCSS({code:'#style-update-literal { \ndisplay: block !important; \n}'},
+                          useCallback && callback);
+        });
+    }
+}
+
+function openWithScript(url, jsUrl, useCallback) {
+    var iab = doOpen(url, '_blank', 'location=yes');
+    if (jsUrl) {
+        iab.addEventListener('loadstop', function(event) {
+            iab.executeScript({file: jsUrl}, useCallback && function(results) {
+                if (results && results.length === 0) {
+                    alert('Results verified');
+                } else {
+                    console.log(results);
+                    alert('Got: ' + typeof(results) + '\n' + JSON.stringify(results));
+                }
+            });
+        });
+    } else {
+        iab.addEventListener('loadstop', function(event) {
+            var code = '(function(){\n' +
+              '    var header = document.getElementById("header");\n' +
+              '    header.innerHTML = "Script literal successfully injected";\n' +
+              '    return "abc";\n' +
+              '})()';
+            iab.executeScript({code:code}, useCallback && function(results) {
+                if (results && results.length === 1 && results[0] === 'abc') {
+                    alert('Results verified');
+                } else {
+                    console.log(results);
+                    alert('Got: ' + typeof(results) + '\n' + JSON.stringify(results));
+                }
+            });
+        });
+    }
+}
+var hiddenwnd=null;
+var loadlistener = function(event) { alert('background window loaded ' ); };
+function openHidden(url, startHidden) {
+    var shopt =(startHidden) ? 'hidden=yes' : '';
+    hiddenwnd = window.open(url,'random_string',shopt);
+    if (!hiddenwnd) {
+        alert('window.open returned ' + hiddenwnd);
+        return;
+    }
+    if(startHidden) hiddenwnd.addEventListener('loadstop', loadlistener);
+}
+function showHidden() {
+    if(!!hiddenwnd ) {
+        hiddenwnd.show();
+    }
+}
+function closeHidden() {
+   if(!!hiddenwnd ) {
+       hiddenwnd.removeEventListener('loadstop',loadlistener);
+       hiddenwnd.close();
+       hiddenwnd=null;
+   }
+}
+
+window.onload = function() {
+  addListenerToClass('openLocal', doOpen, 'local.html');
+  addListenerToClass('openLocalSelf', doOpen, ['local.html', '_self']);
+  addListenerToClass('openLocalSystem', doOpen, ['local.html', '_system']);
+  addListenerToClass('openLocalBlank', doOpen, ['local.html', '_blank']);
+  addListenerToClass('openLocalRandomNoLocation', doOpen, 
+      ['local.html', 'random_string', 'location=no,disallowoverscroll=yes']);
+  addListenerToClass('openLocalRandomToolBarBottom', doOpen,
+      ['local.html', 'random_string', 'toolbarposition=bottom']);
+  addListenerToClass('openLocalRandomToolBarTop', doOpen, 
+      ['local.html', 'random_string', 'toolbarposition=top']);
+  addListenerToClass('openLocalRandomToolBarTopNoLocation', doOpen, 
+      ['local.html', 'random_string', 'toolbarposition=top,location=no']);
+  addListenerToClass('openWhiteListed', doOpen, 'http://www.google.com');
+  addListenerToClass('openWhiteListedSelf', doOpen, 
+      ['http://www.google.com', '_self']);
+  addListenerToClass('openWhiteListedSystem', doOpen,
+      ['http://www.google.com', '_system']);
+  addListenerToClass('openWhiteListedBlank', doOpen, 
+      ['http://www.google.com', '_blank']);
+  addListenerToClass('openWhiteListedRandom', doOpen,
+      ['http://www.google.com', 'random_string']);
+  addListenerToClass('openWhiteListedRandomNoLocation', doOpen,
+      ['http://www.google.com', 'random_string', 'location=no']);
+  addListenerToClass('openNonWhiteListed', doOpen, 'http://www.apple.com');
+  addListenerToClass('openNonWhiteListedSelf', doOpen, 
+      ['http://www.apple.com', '_self']);
+  addListenerToClass('openNonWhiteListedSystem', doOpen, 
+      ['http://www.apple.com', '_system']);
+  addListenerToClass('openNonWhiteListedBlank', doOpen, 
+      ['http://www.apple.com', '_blank']);
+  addListenerToClass('openNonWhiteListedRandom', doOpen,
+      ['http://www.apple.com', 'random_string']);
+  addListenerToClass('openNonWhiteListedRandomNoLocation', doOpen, 
+      ['http://www.apple.com', 'random_string', 'location=no']);
+  addListenerToClass('openRedirect301', doOpen, 
+      ['http://google.com', 'random_string', '', 1]);
+  addListenerToClass('openRedirect302', doOpen, 
+      ['http://goo.gl/pUFqg', 'random_string', '', 2]);
+  addListenerToClass('openPDF', doOpen, 'http://www.stluciadance.com/prospectus_file/sample.pdf');
+  addListenerToClass('openPDFBlank', doOpen, ['local.pdf', '_blank']);
+  addListenerToClass('openInvalidScheme', doOpen, 
+      ['x-ttp://www.invalid.com/', '_blank']);
+  addListenerToClass('openInvalidHost', doOpen, 
+      ['http://www.inv;alid.com/', '_blank']);
+  addListenerToClass('openInvalidMissing', doOpen, ['nonexistent.html', '_blank']);
+  addListenerToClass('openOriginalDocument', doOpen, ['inject.html', '_blank']);
+  addListenerToClass('openCSSInjection', openWithStyle, 
+      ['inject.html','inject.css']);
+  addListenerToClass('openCSSInjectionCallback', openWithStyle, 
+      ['inject.html','inject.css', true]);
+  addListenerToClass('openCSSLiteralInjection', openWithStyle, 'inject.html');
+  addListenerToClass('openCSSLiteralInjectionCallback', openWithStyle, 
+    ['inject.html', null, true]);
+  addListenerToClass('openScriptInjection', openWithScript, 
+    ['inject.html', 'inject.js']);
+  addListenerToClass('openScriptInjectionCallback', openWithScript, 
+    ['inject.html', 'inject.js', true]);
+  addListenerToClass('openScriptLiteralInjection', openWithScript, 'inject.html');
+  addListenerToClass('openScriptLiteralInjectionCallback', openWithScript, 
+    ['inject.html', null, true]);
+  addListenerToClass('openHidden', openHidden, ['http://google.com', true]);
+  addListenerToClass('showHidden', showHidden);
+  addListenerToClass('closeHidden', closeHidden);
+  addListenerToClass('openHiddenShow', openHidden, ['http://google.com', false]);
+  addListenerToClass('openClearCache', doOpen, 
+    ['http://www.google.com', '_blank', 'clearcache=yes']);
+  addListenerToClass('openClearSessionCache', doOpen, 
+    ['http://www.google.com', '_blank', 'clearsessioncache=yes']);
+  addListenerToClass('openRemoteVideo', doOpen, ['video.html', '_blank']);
+  addListenerToClass('openAnchor1', doOpen, ['local.html#anchor1', '_blank']);
+  addListenerToClass('openAnchor2', doOpen, ['local.html#anchor2', '_blank']);
+
+
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/inject.css
----------------------------------------------------------------------
diff --git a/www/inappbrowser/inject.css b/www/inappbrowser/inject.css
new file mode 100644
index 0000000..3f6e41c
--- /dev/null
+++ b/www/inappbrowser/inject.css
@@ -0,0 +1,21 @@
+/*
+ * 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.
+*/
+#style-update-file {
+    display: block !important;
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/inject.html
----------------------------------------------------------------------
diff --git a/www/inappbrowser/inject.html b/www/inappbrowser/inject.html
new file mode 100644
index 0000000..0f1efdd
--- /dev/null
+++ b/www/inappbrowser/inject.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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+  </head>
+  <body id="stage" class="theme">
+    <h1 id="header">InAppBrowser - Script / Style Injection Test</h1>
+    <h2 id="style-update-file" style="display:none">Style updated from file</h2>
+    <h2 id="style-update-literal" style="display:none">Style updated from literal</h2>
+  </body>
+  <script>
+      function updateUserAgent() {
+          document.getElementById("u-a").textContent = navigator.userAgent;
+      }
+      updateUserAgent();
+      window.setInterval(updateUserAgent, 1500);
+  </script>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/inject.js
----------------------------------------------------------------------
diff --git a/www/inappbrowser/inject.js b/www/inappbrowser/inject.js
new file mode 100644
index 0000000..6f25493
--- /dev/null
+++ b/www/inappbrowser/inject.js
@@ -0,0 +1,20 @@
+/*
+ * 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 d = document.getElementById("header")
+d.innerHTML = "Script file successfully injected";

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/local.html
----------------------------------------------------------------------
diff --git a/www/inappbrowser/local.html b/www/inappbrowser/local.html
new file mode 100644
index 0000000..5e33800
--- /dev/null
+++ b/www/inappbrowser/local.html
@@ -0,0 +1,64 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>IAB test page</title>
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8">
+      function onDeviceReady() {
+          document.getElementById("hint").textContent = "Running CordovaWebView, deviceVersion=" + device.version + ", no toolbar should be present, Back link should work, logcat should NOT have failed 'gap:' calls.";
+      }
+      document.addEventListener("deviceready", onDeviceReady, false);
+    </script>
+  </head>
+  <body id="stage" class="theme">
+    <h1>Local URL</h1>
+    <div id="info">
+        You have successfully loaded a local URL:
+        <script>document.write(location.href)</script>
+    </div>
+    <hr />
+    <div>User-Agent = <span id="u-a"></span></div>
+    <hr />
+    <div id="hint">Likely running inAppBrowser: Device version from Cordova=not found, Back link should not work, toolbar may be present, logcat should show failed 'gap:' calls.</div>
+    <hr />
+    <div><a href="http://www.google.com">Visit Google</a> (whitelisted)</div>
+    <div><a href="http://www.yahoo.com">Visit Yahoo</a> (not whitelisted)</div>
+    <div><a href="http://www.stluciadance.com/prospectus_file/sample.pdf">Check out my remote PDF</a></div>
+    <div><a href="local.pdf">Check out my local PDF</a></div>
+    <p /><a href="javascript:;" onclick="history.back();">Back</a>
+    <p />
+    <a name="anchor2"></a>
+    <div style="height: 1000px;border:1px solid red;">tall div with border</div>
+  </body>
+  <script>
+      function updateUserAgent() {
+          document.getElementById("u-a").textContent = navigator.userAgent;
+      }
+      updateUserAgent();
+      window.setInterval(updateUserAgent, 1500);
+  </script>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/local.pdf
----------------------------------------------------------------------
diff --git a/www/inappbrowser/local.pdf b/www/inappbrowser/local.pdf
new file mode 100644
index 0000000..b54f1b7
Binary files /dev/null and b/www/inappbrowser/local.pdf differ

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/inappbrowser/video.html
----------------------------------------------------------------------
diff --git a/www/inappbrowser/video.html b/www/inappbrowser/video.html
new file mode 100644
index 0000000..64ea3d1
--- /dev/null
+++ b/www/inappbrowser/video.html
@@ -0,0 +1,42 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+
+  </head>
+  <body>
+    <video width=100% height=100% id="player">
+      <source src="http://m.comptoir-info.com/app/beta/sample.mp4">
+      <meta property="og:video:secure_url" content="http://m.comptoir-info.com/app/beta/sample.mp4">
+      <meta property="og:video:type" content="video/mp4">
+    </video>
+    <div>
+      <button onclick="document.getElementById('player').play()"> play </button>
+      <button onclick="document.getElementById('player').pause()"> pause </button>
+    </div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/index.html
----------------------------------------------------------------------
diff --git a/www/index.html b/www/index.html
new file mode 100644
index 0000000..86b1173
--- /dev/null
+++ b/www/index.html
@@ -0,0 +1,69 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>Cordova Mobile Spec</title>
+	  <link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+	  <script type="text/javascript" charset="utf-8" src="cordova-incl.js"></script>
+	  <script type="text/javascript" charset="utf-8" src="main.js"></script>
+
+  </head>
+  <body id="stage" class="theme">
+    <h1>Apache Cordova Tests</h1>
+    <div id="info">
+        <h4>cordova.version: <span id="cordova"> </span></h4>
+        <h4>Platform: <span id="platform">  </span></h4>
+        <h4>Version: <span id="version"> </span></h4>
+        <h4>UUID: <span id="uuid">  </span></h4>
+        <h4>Model: <span id="model"> </span></h4>
+        <h4>Width: <span id="width">  </span>,   Height: <span id="height">
+                   </span>, Color Depth: <span id="colorDepth"></span></h4>
+        <h4>User-Agent: <span id="user-agent"> </span></h4>
+     </div>
+    <a href="autotest/index.html" class="btn large">Automatic Test</a>
+    <a href="accelerometer/index.html" class="btn large">Accelerometer</a>
+    <a href="audio/index.html" class="btn large">Audio Play/Record</a>
+    <a href="battery/index.html" class="btn large">Battery</a>
+    <a href="camera/index.html" class="btn large">Camera</a>
+    <a href="capture/index.html" class="btn large">Capture</a>
+    <a href="compass/index.html" class="btn large">Compass</a>
+    <a href="contacts/index.html" class="btn large">Contacts</a>
+    <a href="events/index.html" class="btn large">Events</a>
+    <a href="location/index.html" class="btn large">Location</a>
+    <a href="lazyloadjs/index.html" class="btn large">Lazy Loading of cordova-incl.js</a>
+    <a href="misc/index.html" class="btn large">Misc Content</a>
+    <a href="network/index.html" class="btn large">Network</a>
+    <a href="notification/index.html" class="btn large">Notification</a>
+    <a href="splashscreen/index.html" class="btn large">Splashscreen</a>
+    <a href="sql/index.html" class="btn large">Web SQL</a>
+    <a href="storage/index.html" class="btn large">Local Storage</a>
+    <a href="benchmarks/index.html" class="btn large">Benchmarks</a>
+    <a href="inappbrowser/index.html" class="btn large">In App Browser</a>
+    <a href="keyboard/index.html" class="btn large">Keyboard</a>
+    <a href="vibration/index.html" class="btn large">Vibration</a>
+    <a href="file/index.html" class="btn large">File &amp; File Transfer</a>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/keyboard/index.html
----------------------------------------------------------------------
diff --git a/www/keyboard/index.html b/www/keyboard/index.html
new file mode 100644
index 0000000..9a66add
--- /dev/null
+++ b/www/keyboard/index.html
@@ -0,0 +1,175 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <style>
+    table {
+      width: 100%;
+      border: 1px solid white;
+    }
+
+    th, td {
+      width: 25%;
+      text-align: center;
+      vertical-align: top;
+      border: 1px solid gray;
+    }
+    
+    .highlight-w {
+        color: white;
+    }
+    
+    #stage.theme .small{
+        width:50px;
+        padding:1.2em 0;
+    }
+    
+    input[type=text] {
+        width: 70%;
+        height: 30px;
+    }
+    
+    .btn-dismiss {
+        width: 20%;
+        height: 30px;
+    }
+    
+    #error {
+        color: red;
+    }
+
+    </style>
+    <script type="text/javascript" charset="utf-8" src="./window-onerror.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Keyboard (iOS)</h1>
+
+    <br />
+    <div>
+        <input type="text" placeholder="touch to see keyboard" /><button class="btn-dismiss">dismiss</button>
+    </div>
+
+    <h1>isVisible</h1>
+    <br />
+    <div class="btn large keyboardIsVisible">Keyboard.isVisible</div>
+    
+    <h1>API Tests</h1>
+    <br />
+    <div>
+    The current state is highlighted below in the list. Touch a test <span class="highlight-w">"#" button</span> in the table, then touch a textfield (available at the top and bottom of the page) to see the results.
+    </div>
+    <ul>
+        <li>shrinkView(<span id="shrinkView-arg" class="highlight-w">false</span>)</li>
+        <li>hideFormAccessoryBar(<span id="hideFormAccessoryBar-arg" class="highlight-w">false</span>)</li>
+        <li>disableScrollingInShrinkView(<span id="disableScrollingInShrinkView-arg" class="highlight-w">false</span>)</li>
+    </ul>
+    <!-- &#x2717; is X, &#10004; is check-mark -->
+    <table>
+        <tr>
+            <th>Test #</th>
+            <th>shrinkView</th>
+            <th>hideForm&hellip;</th>
+            <th>disableScrolling&hellip;</th>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_1">1</div>
+            </td>
+            <td>&#x2717;</td>
+            <td>&#x2717;</td>
+            <td>&#x2717;</td>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_2">2</div>
+            </td>
+            <td>&#x2717;</td>
+            <td>&#x2717;</td>
+            <td class="highlight-w">&#10004;</td>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_3">3</div>
+            </td>
+            <td>&#x2717;</td>
+            <td class="highlight-w">&#10004;</td>
+            <td class="highlight-w">&#10004;</td>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_4">4</div>
+            </td>
+            <td>&#x2717;</td>
+            <td class="highlight-w">&#10004;</td>
+            <td>&#x2717;</td>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_5">5</div>
+            </td>
+            <td class="highlight-w">&#10004;</td>
+            <td>&#x2717;</td>
+            <td>&#x2717;</td>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_6">6</div>
+            </td>
+            <td class="highlight-w">&#10004;</td>
+            <td>&#x2717;</td>
+            <td class="highlight-w">&#10004;</td>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_7">7</div>
+            </td>
+            <td class="highlight-w">&#10004;</td>
+            <td class="highlight-w">&#10004;</td>
+            <td class="highlight-w">&#10004;</td>
+        </tr>
+        <tr>
+            <td class="highlight-w">
+                <div class="btn small set_8">8</div>
+            </td>
+            <td class="highlight-w">&#10004;</td>
+            <td class="highlight-w">&#10004;</td>
+            <td>&#x2717;</td>
+        </tr>
+    </table>
+    <br />
+    <div>
+        <input type="text" placeholder="touch to see keyboard" /><button class="btn-dismiss">dismiss</button>
+    </div>
+    <br />
+    <div class="backBtn">Back</div>
+    
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/keyboard/index.js
----------------------------------------------------------------------
diff --git a/www/keyboard/index.js b/www/keyboard/index.js
new file mode 100644
index 0000000..2302f31
--- /dev/null
+++ b/www/keyboard/index.js
@@ -0,0 +1,69 @@
+
+var deviceReady = false;
+var keyboardPlugin = null;
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            keyboardPlugin = window.Keyboard; // for now, before plugin re-factor
+                              
+            if (keyboardPlugin == null) {
+                var msg = 'The plugin org.apache.cordova.keyboard was not found. Check that you have it installed.';
+                alert(msg);
+            }
+
+        }, false);
+    window.setTimeout(function() {
+      if (!deviceReady) {
+            var msg = 'Error: Apache Cordova did not initialize.  Demo will not run correctly.';
+            alert(msg);
+      }
+    },1000);
+}
+
+function setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(shrinkView, hideFormAccessoryBar, disableScrollingInShrinkView)
+{
+    keyboardPlugin.shrinkView(shrinkView);
+    document.getElementById("shrinkView-arg").innerHTML = shrinkView;
+    
+    keyboardPlugin.hideFormAccessoryBar(hideFormAccessoryBar);
+    document.getElementById("hideFormAccessoryBar-arg").innerHTML = hideFormAccessoryBar;
+
+    keyboardPlugin.disableScrollingInShrinkView(disableScrollingInShrinkView);
+    document.getElementById("disableScrollingInShrinkView-arg").innerHTML = disableScrollingInShrinkView;
+}
+
+window.onload = function() {
+  addListenerToClass('keyboardIsVisible', function() {
+    alert('Keyboard.isVisible: ' + Keyboard.isVisible);
+  });
+  addListenerToClass('set_1', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, false, false)
+  });
+  addListenerToClass('set_2', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, false, true)
+  });
+  addListenerToClass('set_3', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, true, true)
+  });
+  addListenerToClass('set_4', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, true, false)
+  });
+  addListenerToClass('set_5', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, false, false)
+  });
+  addListenerToClass('set_6', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, false, true)
+  });
+  addListenerToClass('set_7', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, true, true)
+  });
+  addListenerToClass('set_8', function() {
+    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, true, false)
+  });
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/keyboard/window-onerror.js
----------------------------------------------------------------------
diff --git a/www/keyboard/window-onerror.js b/www/keyboard/window-onerror.js
new file mode 100644
index 0000000..f833882
--- /dev/null
+++ b/www/keyboard/window-onerror.js
@@ -0,0 +1 @@
+window.onerror = function(err,fn,ln) {alert("ERROR:" + err + ", " + fn + ":" + ln);};

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/lazyloadjs/do-not-write-cordova-script.js
----------------------------------------------------------------------
diff --git a/www/lazyloadjs/do-not-write-cordova-script.js b/www/lazyloadjs/do-not-write-cordova-script.js
new file mode 100644
index 0000000..0f20c76
--- /dev/null
+++ b/www/lazyloadjs/do-not-write-cordova-script.js
@@ -0,0 +1 @@
+_doNotWriteCordovaScript = true;

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/lazyloadjs/index.html
----------------------------------------------------------------------
diff --git a/www/lazyloadjs/index.html b/www/lazyloadjs/index.html
new file mode 100644
index 0000000..5816349
--- /dev/null
+++ b/www/lazyloadjs/index.html
@@ -0,0 +1,41 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Lazy-Loading of cordova-incl.js test</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
+    <script type="text/javascript" charset="utf-8" src="./do-not-write-cordova-script.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+    <h1>Lazy-Loading of cordova-incl.js</h1>
+    <div id="info">
+      onDeviceReady has not yet fired.
+    </div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/lazyloadjs/index.js
----------------------------------------------------------------------
diff --git a/www/lazyloadjs/index.js b/www/lazyloadjs/index.js
new file mode 100644
index 0000000..6559319
--- /dev/null
+++ b/www/lazyloadjs/index.js
@@ -0,0 +1,16 @@
+function init() {
+    document.addEventListener("deviceready", function() {
+        console.log("Device="+device.platform+" "+device.version);
+        document.getElementById('info').innerHTML = 'Cordova loaded just fine.';
+    }, false);
+    window.setTimeout(function() {
+        var s = document.createElement('script');
+        s.src = cordovaPath;
+        document.body.appendChild(s);
+    }, 0);
+}
+
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/location/index.html
----------------------------------------------------------------------
diff --git a/www/location/index.html b/www/location/index.html
new file mode 100644
index 0000000..f0cc7de
--- /dev/null
+++ b/www/location/index.html
@@ -0,0 +1,98 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Location</h1>
+    <div id="info">
+        <b>Status:</b> <span id="location_status">Stopped</span>
+        <table width="100%">
+            <tr>
+                <td><b>Latitude:</b></td>
+                <td id="latitude">&nbsp;</td>
+                <td>(decimal degrees) geographic coordinate [<a href="http://dev.w3.org/geo/api/spec-source.html#lat">#ref]</a></td>
+            </tr>
+            <tr>
+                <td><b>Longitude:</b></td>
+                <td id="longitude">&nbsp;</td>
+                <td>(decimal degrees) geographic coordinate [<a href="http://dev.w3.org/geo/api/spec-source.html#lat">#ref]</a></td>
+            </tr>
+            <tr>
+                <td><b>Altitude:</b></td>
+                <td id="altitude">&nbsp;</td>
+                <td>null if not supported;<br>
+                    (meters) height above the [<a href="http://dev.w3.org/geo/api/spec-source.html#ref-wgs">WGS84</a>] ellipsoid. [<a href="http://dev.w3.org/geo/api/spec-source.html#altitude">#ref]</a></td>
+            </tr>
+            <tr>
+                <td><b>Accuracy:</b></td>
+                <td id="accuracy">&nbsp;</td>
+                <td>(meters; non-negative; 95% confidence level) the accuracy level of the latitude and longitude coordinates. [<a href="http://dev.w3.org/geo/api/spec-source.html#accuracy">#ref]</a></td>
+            </tr>
+            <tr>
+                <td><b>Heading:</b></td>
+                <td id="heading">&nbsp;</td>
+                <td>null if not supported;<br>
+                    NaN if speed == 0;<br>
+                    (degrees; 0° ≤ heading < 360°) direction of travel of the hosting device- counting clockwise relative to the true north. [<a href="http://dev.w3.org/geo/api/spec-source.html#heading">#ref]</a></td>
+            </tr>
+            <tr>
+                <td><b>Speed:</b></td>
+                <td id="speed">&nbsp;</td>
+                <td>null if not supported;<br>
+                    (meters per second; non-negative) magnitude of the horizontal component of the hosting device's current velocity. [<a href="http://dev.w3.org/geo/api/spec-source.html#speed">#ref]</a></td>
+            </tr>
+            <tr>
+                <td><b>Altitude Accuracy:</b></td>
+                <td id="altitude_accuracy">&nbsp;</td>
+                <td>null if not supported;<br>(meters; non-negative; 95% confidence level) the accuracy level of the altitude. [<a href="http://dev.w3.org/geo/api/spec-source.html#altitude-accuracy">#ref]</a></td>
+            </tr>
+            <tr>
+                <td><b>Time:</b></td>
+                <td id="timestamp">&nbsp;</td>
+                <td>(DOMTimeStamp) when the position was acquired [<a href="http://dev.w3.org/geo/api/spec-source.html#timestamp">#ref]</a></td>
+            </tr>
+        </table>
+    </div>
+    <h2>Action</h2>
+    <h3>Use Built-in WebView navigator.geolocation</h3>
+    <a href="javascript:" class="btn large getWebViewLocation">Get Location</a>
+    <a href="javascript:" class="btn large watchWebViewLocation">Start Watching Location</a>
+    <a href="javascript:" class="btn large stopWebViewLocation">Stop Watching Location</a>
+    <a href="javascript:" class="btn large getWebViewLocation30">Get Location Up to 30 Seconds Old</a>
+    <h3>Use Cordova Geolocation Plugin</h3>
+    <a href="javascript:" class="btn large getLocation">Get Location</a>
+    <a href="javascript:" class="btn large watchLocation">Start Watching Location</a>
+    <a href="javascript:" class="btn large stopLocation">Stop Watching Location</a>
+    <a href="javascript:" class="btn large getLocation30">Get Location Up to 30 Seconds Old</a>
+    <h2>&nbsp;</h2><a href="javascript:" class="backBtn"">Back</a>    
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/location/index.js
----------------------------------------------------------------------
diff --git a/www/location/index.js b/www/location/index.js
new file mode 100644
index 0000000..242919d
--- /dev/null
+++ b/www/location/index.js
@@ -0,0 +1,128 @@
+var origGeolocation = null;
+var newGeolocation = null;
+
+//-------------------------------------------------------------------------
+// Location
+//-------------------------------------------------------------------------
+var watchLocationId = null;
+
+/**
+ * Start watching location
+ */
+var watchLocation = function(usePlugin) {
+    var geo = usePlugin ? newGeolocation : origGeolocation;
+    if (!geo) {
+        alert('geolocation object is missing. usePlugin = ' + usePlugin);
+        return;
+    }
+
+    // Success callback
+    var success = function(p){
+          console.log('watch location success');
+          setLocationDetails(p);
+    };
+
+    // Fail callback
+    var fail = function(e){
+        console.log("watchLocation fail callback with error code "+e);
+        stopLocation(geo);
+    };
+
+    // Get location
+    watchLocationId = geo.watchPosition(success, fail, {enableHighAccuracy: true});
+    setLocationStatus("Running");
+};
+
+/**
+ * Stop watching the location
+ */
+var stopLocation = function(usePlugin) {
+    var geo = usePlugin ? newGeolocation : origGeolocation;
+    if (!geo) {
+        alert('geolocation object is missing. usePlugin = ' + usePlugin);
+        return;
+    }
+    setLocationStatus("Stopped");
+    if (watchLocationId) {
+        geo.clearWatch(watchLocationId);
+        watchLocationId = null;
+    }
+};
+
+/**
+ * Get current location
+ */
+var getLocation = function(usePlugin, opts) {
+    var geo = usePlugin ? newGeolocation : origGeolocation;
+    if (!geo) {
+        alert('geolocation object is missing. usePlugin = ' + usePlugin);
+        return;
+    }
+
+    // Stop location if running
+    stopLocation(geo);
+
+    // Success callback
+    var success = function(p){
+        console.log('get location success');
+        setLocationDetails(p);
+        setLocationStatus("Done");
+    };
+
+    // Fail callback
+    var fail = function(e){
+        console.log("getLocation fail callback with error code "+e.code);
+        setLocationStatus("Error: "+e.code);
+    };
+
+    setLocationStatus("Retrieving location...");
+
+    // Get location
+    geo.getCurrentPosition(success, fail, opts || {enableHighAccuracy: true}); //, {timeout: 10000});
+
+};
+
+/**
+ * Set location status
+ */
+var setLocationStatus = function(status) {
+    document.getElementById('location_status').innerHTML = status;
+};
+var setLocationDetails = function(p) {
+var date = (new Date(p.timestamp));
+        document.getElementById('latitude').innerHTML = p.coords.latitude;
+        document.getElementById('longitude').innerHTML = p.coords.longitude;
+        document.getElementById('altitude').innerHTML = p.coords.altitude;
+        document.getElementById('accuracy').innerHTML = p.coords.accuracy;
+        document.getElementById('heading').innerHTML = p.coords.heading;
+        document.getElementById('speed').innerHTML = p.coords.speed;
+        document.getElementById('altitude_accuracy').innerHTML = p.coords.altitudeAccuracy;
+        document.getElementById('timestamp').innerHTML =  date.toDateString() + " " + date.toTimeString();
+}
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+        newGeolocation = navigator.geolocation;
+        origGeolocation = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
+        if (!origGeolocation) {
+            origGeolocation = newGeolocation;
+            newGeolocation = null;
+        }
+    }, false);
+}
+
+window.onload = function() {
+  addListenerToClass('getWebViewLocation', getLocation, [false]);
+  addListenerToClass('watchWebViewLocation', watchLocation, [false]);
+  addListenerToClass('stopWebViewLocation', stopLocation, [false]);
+  addListenerToClass('getWebViewLocation30', getLocation, [false, {maximumAge:30000}]);
+  addListenerToClass('getLocation', getLocation, [true]);
+  addListenerToClass('watchLocation', watchLocation, [true]);
+  addListenerToClass('stopLocation', stopLocation, [true]);
+  addListenerToClass('getLocation30', getLocation, [true, {maximumAge:30000}]);
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/main.js
----------------------------------------------------------------------
diff --git a/www/main.js b/www/main.js
new file mode 100644
index 0000000..42e9edd
--- /dev/null
+++ b/www/main.js
@@ -0,0 +1,165 @@
+/*
+ *
+ * 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 deviceInfo = function() {
+    document.getElementById("cordova").innerHTML = cordova.version;
+    document.getElementById("platform").innerHTML = device.platform;
+    document.getElementById("version").innerHTML = device.version;
+    document.getElementById("uuid").innerHTML = device.uuid;
+    document.getElementById("model").innerHTML = device.model;
+    document.getElementById("width").innerHTML = screen.width;
+    document.getElementById("height").innerHTML = screen.height;
+    document.getElementById("colorDepth").innerHTML = screen.colorDepth;
+};
+
+var getLocation = function() {
+    var suc = function(p) {
+        alert(p.coords.latitude + " " + p.coords.longitude);
+    };
+    var locFail = function() {
+    };
+    navigator.geolocation.getCurrentPosition(suc, locFail);
+};
+
+var beep = function() {
+    navigator.notification.beep(2);
+};
+
+var vibrate = function() {
+    navigator.notification.vibrate(0);
+};
+
+function roundNumber(num) {
+    var dec = 3;
+    var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
+    return result;
+}
+
+var accelerationWatch = null;
+
+function updateAcceleration(a) {
+    document.getElementById('x').innerHTML = roundNumber(a.x);
+    document.getElementById('y').innerHTML = roundNumber(a.y);
+    document.getElementById('z').innerHTML = roundNumber(a.z);
+}
+
+var toggleAccel = function() {
+    if (accelerationWatch !== null) {
+        navigator.accelerometer.clearWatch(accelerationWatch);
+        updateAcceleration({
+            x : "",
+            y : "",
+            z : ""
+        });
+        accelerationWatch = null;
+    } else {
+        var options = {};
+        options.frequency = 1000;
+        accelerationWatch = navigator.accelerometer.watchAcceleration(
+                updateAcceleration, function(ex) {
+                    alert("accel fail (" + ex.name + ": " + ex.message + ")");
+                }, options);
+    }
+};
+
+var preventBehavior = function(e) {
+    e.preventDefault();
+};
+
+function dump_pic(data) {
+    var viewport = document.getElementById('viewport');
+    console.log(data);
+    viewport.style.display = "";
+    viewport.style.position = "absolute";
+    viewport.style.top = "10px";
+    viewport.style.left = "10px";
+    document.getElementById("test_img").src = "data:image/jpeg;base64," + data;
+}
+
+function fail(msg) {
+    alert(msg);
+}
+
+function show_pic() {
+    navigator.camera.getPicture(dump_pic, fail, {
+        quality : 50
+    });
+}
+
+function close() {
+    var viewport = document.getElementById('viewport');
+    viewport.style.position = "relative";
+    viewport.style.display = "none";
+}
+
+// This is just to do this.
+function readFile() {
+    navigator.file.read('/sdcard/cordova.txt', fail, fail);
+}
+
+function writeFile() {
+    navigator.file.write('foo.txt', "This is a test of writing to a file",
+            fail, fail);
+}
+
+function contacts_success(contacts) {
+    alert(contacts.length
+            + ' contacts returned.'
+            + (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted)
+                    : ''));
+}
+
+function get_contacts() {
+    var obj = new ContactFindOptions();
+    obj.filter = "";
+    obj.multiple = true;
+    obj.limit = 5;
+    navigator.service.contacts.find(
+            [ "displayName", "name" ], contacts_success,
+            fail, obj);
+}
+
+var networkReachableCallback = function(reachability) {
+    // There is no consistency on the format of reachability
+    var networkState = reachability.code || reachability;
+
+    var currentState = {};
+    currentState[NetworkStatus.NOT_REACHABLE] = 'No network connection';
+    currentState[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
+    currentState[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection';
+
+    confirm("Connection type:\n" + currentState[networkState]);
+};
+
+function check_network() {
+    navigator.network.isReachable("www.mobiledevelopersolutions.com",
+            networkReachableCallback, {});
+}
+
+function init() {
+    // the next line makes it impossible to see Contacts on the HTC Evo since it
+    // doesn't have a scroll button
+    // document.addEventListener("touchmove", preventBehavior, false);
+    document.addEventListener("deviceready", deviceInfo, true);
+    document.getElementById("user-agent").textContent = navigator.userAgent;
+}
+
+window.onload = init;

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/master.css
----------------------------------------------------------------------
diff --git a/www/master.css b/www/master.css
new file mode 100644
index 0000000..8c2b232
--- /dev/null
+++ b/www/master.css
@@ -0,0 +1,182 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+  body {
+    background:#222 none repeat scroll 0 0;
+    color:#666;
+    font-family:Helvetica;
+    font-size:72%;
+    line-height:1.5em;
+    margin:0;
+    border-top:1px solid #393939;
+  }
+
+  #info{
+    background:#ffa;
+    border: 1px solid #ffd324;
+    -webkit-border-radius: 5px;
+    border-radius: 5px;
+    clear:both;
+    margin:15px 6px 0;
+    min-width:295px;
+    max-width:97%;
+    padding:4px 0px 2px 10px;
+    word-wrap:break-word;
+    margin-bottom:10px;
+    display:inline-block;
+    min-height: 160px;
+    max-height: 300px;
+    overflow: auto;
+    -webkit-overflow-scrolling: touch;
+  }
+  
+  #info > h4{
+    font-size:.95em;
+    margin:5px 0;
+  }
+ 	
+  #stage.theme{
+    padding-top:3px;
+  }
+
+  /* Definition List */
+  #stage.theme > dl{
+  	padding-top:10px;
+  	clear:both;
+  	margin:0;
+  	list-style-type:none;
+  	padding-left:10px;
+  	overflow:auto;
+  }
+
+  #stage.theme > dl > dt{
+  	font-weight:bold;
+  	float:left;
+  	margin-left:5px;
+  }
+
+  #stage.theme > dl > dd{
+  	width:45px;
+  	float:left;
+  	color:#a87;
+  	font-weight:bold;
+  }
+
+  /* Content Styling */
+  #stage.theme > h1, #stage.theme > h2, #stage.theme > p{
+    margin:1em 0 .5em 13px;
+  }
+
+  #stage.theme > h1{
+    color:#eee;
+    font-size:1.6em;
+    text-align:center;
+    margin:0;
+    margin-top:15px;
+    padding:0;
+  }
+
+  #stage.theme > h2{
+  	clear:both;
+    margin:0;
+    padding:3px;
+    font-size:1em;
+    text-align:center;
+  }
+
+  /* Stage Buttons */
+  #stage.theme .btn{
+  	border: 1px solid #555;
+  	-webkit-border-radius: 5px;
+  	border-radius: 5px;
+  	text-align:center;
+  	display:inline-block;
+  	background:#444;
+  	width:150px;
+  	color:#9ab;
+  	font-size:1.1em;
+  	text-decoration:none;
+  	padding:1.2em 0;
+  	margin:3px 0px 3px 5px;
+  }
+  
+  #stage.theme .large{
+  	width:308px;
+  	padding:1.2em 0;
+  }
+  
+  #stage.theme .wide{
+    width:100%;
+    padding:1.2em 0;
+  }
+  
+  #stage.theme .backBtn{
+   border: 1px solid #555;
+   -webkit-border-radius: 5px;
+   border-radius: 5px;
+   text-align:center;
+   display:block;
+   float:right;
+   background:#666;
+   width:75px;
+   color:#9ab;
+   font-size:1.1em;
+   text-decoration:none;
+   padding:1.2em 0;
+   margin:3px 5px 3px 5px;
+  }
+  
+  #stage.theme .input{
+   border: 1px solid #555;
+   -webkit-border-radius: 5px;
+   border-radius: 5px;
+   text-align:center;
+   display:block;
+   float:light;
+   background:#888;
+   color:#9cd;
+   font-size:1.1em;
+   text-decoration:none;
+   padding:1.2em 0;
+   margin:3px 0px 3px 5px;    
+ }
+  
+  #stage.theme .numeric{
+   width:100%;
+  }
+
+/* Selectively hide and show items by platform */
+.platform {
+  display: none;
+}
+
+body.amazon-fireos-platform .platform.amazon-fireos,
+body.android-platform .platform.android,
+body.blackberry10-platform .platform.blackberry10,
+body.browser-platform .platform.browser,
+body.firefoxos-platform .platform.firefoxos,
+body.ios-platform .platform.ios,
+body.osx-platform .platform.ios,
+body.ubuntu-platform .platform.ubuntu,
+body.windows8-platform .platform.windows8,
+body.windowsphone-platform .platform.windowsphone {
+  display: block;
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/misc/index.html
----------------------------------------------------------------------
diff --git a/www/misc/index.html b/www/misc/index.html
new file mode 100644
index 0000000..0ebb217
--- /dev/null
+++ b/www/misc/index.html
@@ -0,0 +1,60 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Display Other Content</h1>
+    <div id="info">
+    </div>
+    <h2>Action</h2>
+    <div class="btn large telLocation">Call 411</div>
+    <a href="mailto:bob@abc.org?subject=My Subject&body=This is the body.%0D%0ANew line." class="btn large">Send Mail</a>
+    <a href="sms:5125551234?body=The SMS message." class="btn large">Send SMS</a>
+    <a href="http://www.google.com" class="btn large">Load Web Site</a>
+    <!--  Need new URL -->
+    <!-- a href="http://handle.library.cornell.edu/control/authBasic/authTest/" class="btn large">Basic Auth: test/this</a -->
+    <a href="page2.html" class="btn large">Load a page with iframes</a>
+    <a href="page2.html?me=test" class="btn large">Load page with query param</a>
+    <a href="page3.html#foo" class="btn large">Page with hash</a>
+    <a href="page3.html?hash1#gah" class="btn large">Page with hash change on load</a>
+    <a href="page3.html?hash2#gah" class="btn large">Page with hash replace on load</a>
+    <a href="page3.html?hash1&changeURL#gah" class="btn large">Page with replaceState & hash change</a>
+    <a href="page3.html?iframe#gah" class="btn large">Page iframe hash change</a>
+    <h2>Android Only</h2>
+    <a href="geo:0,0?q=11400 Burnet Rd, Austin, TX" class="btn large">Map IBM</a>
+    <a href="market://search?q=google" class="btn large">Search Android market</a>
+    <a href="content://media/external/images/media" class="btn large">View image app</a>
+
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/misc/index.js
----------------------------------------------------------------------
diff --git a/www/misc/index.js b/www/misc/index.js
new file mode 100644
index 0000000..e38ade7
--- /dev/null
+++ b/www/misc/index.js
@@ -0,0 +1,30 @@
+var deviceReady = false;
+
+function roundNumber(num) {
+    var dec = 3;
+    var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
+    return result;
+}
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+      if (!deviceReady) {
+        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+      }
+    },1000);
+}
+
+window.onload = function() {
+  addListenerToClass('telLocation', function() {
+    document.location='tel:5551212';
+  });
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/misc/page2.html
----------------------------------------------------------------------
diff --git a/www/misc/page2.html b/www/misc/page2.html
new file mode 100644
index 0000000..1d370a9
--- /dev/null
+++ b/www/misc/page2.html
@@ -0,0 +1,64 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="../main.js"></script>
+    <script type="text/javascript" charset="utf-8" src="./page2.js"></script>      
+    <style>
+      iframe, .iframe_container {
+        height:100px;
+        overflow:scroll;
+      }
+    </style>
+  </head>
+  <body id="stage" class="theme">
+    <h1>Page2 App</h1>
+    <h2>This is page 2 of a Apache Cordova app</h2>
+    <div id="info">
+      loading...
+     </div>
+     about:blank
+     <div class="iframe_container">
+       <iframe src="about:blank"></iframe>
+     </div>
+     invalid URL
+     <div class="iframe_container">
+       <iframe src="x-ttp://www.invalid.com/"></iframe>
+     </div>
+     whatheaders.com
+     <div class="iframe_container">
+       <iframe src="http://whatheaders.com"></iframe>
+     </div>
+     apache.org
+     <div class="iframe_container">
+       <iframe src="" id="apacheiframe"></iframe>
+     </div>
+     <div><button class="backBtn">Back</button></div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/misc/page2.js
----------------------------------------------------------------------
diff --git a/www/misc/page2.js b/www/misc/page2.js
new file mode 100644
index 0000000..1f489c2
--- /dev/null
+++ b/www/misc/page2.js
@@ -0,0 +1,12 @@
+setTimeout(function() {
+    console.log('loading iframe after timeout.');
+    document.querySelector('#apacheiframe').src = 'http://apache.org';
+}, 2000);
+document.addEventListener("deviceready", function() {
+    document.getElementById('info').textContent += '\nDevice is ready.';
+}, false);
+
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/misc/page3.html
----------------------------------------------------------------------
diff --git a/www/misc/page3.html b/www/misc/page3.html
new file mode 100644
index 0000000..6677677
--- /dev/null
+++ b/www/misc/page3.html
@@ -0,0 +1,84 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="./page3A.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="../main.js"></script>
+  </head>
+  <body onload="init();" id="stage" class="theme">
+    <h1>Page2 App</h1>
+    <h2>This is page 2 of a Apache Cordova app</h2>
+    <div id="info">
+      loading...
+     </div>
+    <div id="info2">
+     </div>
+     <script>
+      if (location.search.indexOf('iframe') != -1) {
+        document.write('<iframe src="' + location.href.replace('iframe','hash1') + '"></iframe>');
+      }
+     </script>
+     <div><button onclick="changeHash()">changeHash()</button></div>
+     <div><button onclick="loadFrame()">loadFrame()</button></div>
+     <div><button onclick="reload()">reload()</button></div>
+     <div><button class="backBtn" onclick="backHome();">Back</button></div>
+  </body>
+  <script>
+    setInterval(function() {
+      document.getElementById('info2').textContent = location.href;
+    }, 300);
+
+    document.addEventListener("deviceready", function() {
+        document.getElementById('info').innerHTML += '<br>Device is ready.';
+        console.log('device ready');
+    }, false);
+    window.onload = function() {
+        document.getElementById('info').innerHTML += '<br>got load event.';
+        console.log('got onload');
+    }
+  </script>
+  <script>
+    document.getElementById('info').innerHTML += '<br>Changing hash #2.';
+    console.log('Changing hash #2');
+    if (location.search.indexOf('hash1') != -1) {
+      location.hash = 'b';
+    } else if (location.search.indexOf('hash2') != -1) {
+      location.replace('#replaced2');
+    }
+    var hashCount = 0;
+    function changeHash() {
+      hashCount += 1;
+      if (hashCount % 1) {
+        location.hash = hashCount;
+      } else {
+        location.replace('#' + hashCount);
+      }
+    }
+  </script>
+</html>


[12/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/battery/index.js
----------------------------------------------------------------------
diff --git a/battery/index.js b/battery/index.js
deleted file mode 100644
index 1a0d488..0000000
--- a/battery/index.js
+++ /dev/null
@@ -1,72 +0,0 @@
-var deviceReady = false;
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-        if (!deviceReady) {
-            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-        }
-    },1000);
-}
-
-/* Battery */
-function updateInfo(info) {
-    document.getElementById('level').innerText = info.level;
-    document.getElementById('isPlugged').innerText = info.isPlugged;
-    if (info.level > 5) {
-        document.getElementById('crit').innerText = "false";
-    }
-    if (info.level > 20) {
-        document.getElementById('low').innerText = "false";
-    }
-}
-
-function batteryLow(info) {
-    document.getElementById('low').innerText = "true";
-}
-
-function batteryCritical(info) {
-    document.getElementById('crit').innerText = "true";
-}
-
-function addBattery() {
-    window.addEventListener("batterystatus", updateInfo, false);
-}
-
-function removeBattery() {
-    window.removeEventListener("batterystatus", updateInfo, false);
-}
-
-function addLow() {
-    window.addEventListener("batterylow", batteryLow, false);
-}
-
-function removeLow() {
-    window.removeEventListener("batterylow", batteryLow, false);
-}
-
-function addCritical() {
-    window.addEventListener("batterycritical", batteryCritical, false);
-}
-
-function removeCritical() {
-    window.removeEventListener("batterycritical", batteryCritical, false);
-}
-
-window.onload = function() {
-  addListenerToClass('addBattery', addBattery);
-  addListenerToClass('removeBattery', removeBattery);
-  addListenerToClass('addLow', addLow);
-  addListenerToClass('removeLow', removeLow);
-  addListenerToClass('addCritical', addCritical);
-  addListenerToClass('removeCritical', removeCritical);
-  
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/beep.wav
----------------------------------------------------------------------
diff --git a/beep.wav b/beep.wav
deleted file mode 100644
index 05f5997..0000000
Binary files a/beep.wav and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/benchmarks/arraybuffer.html
----------------------------------------------------------------------
diff --git a/benchmarks/arraybuffer.html b/benchmarks/arraybuffer.html
deleted file mode 100644
index 5686f75..0000000
--- a/benchmarks/arraybuffer.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-
-<script>
-    var exec = cordova.require('cordova/exec'),
-        deviceReady = false;
-
-    function appLog(message) {
-        if (window.console) {
-            console.log(message);
-        }
-        if (typeof message != 'string') {
-            message = JSON.stringify(message);
-        }
-        document.getElementById('app-logs').innerText += message + '\n';
-    }
-
-    function benchExec() {
-        var echo = cordova.echo,
-            startTime = +new Date,
-            callCount = 0,
-            durationMs = parseInt(document.getElementById('test-duration').value, 10) * 1000,
-            payloadSize = (+document.getElementById('payload-size').value),
-            payload = new ArrayBuffer(payloadSize);
-
-        var payloadView = new Uint8Array(payload);
-        for (var i=0; i<payloadView.length; i++) {
-            payloadView[i] = i;
-        }
-
-        function compareArrayBuffers(arr1, arr2) {
-            arr1 = new Uint8Array(arr1);
-            arr2 = new Uint8Array(arr2);
-            if (arr1.length != arr2.length)
-                return false;
-            for (var i = 0; i < arr1.length; ++i) {
-                if (arr1[i] != arr2[i]) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        function win(result) {
-            callCount++;
-            if (!compareArrayBuffers(result, payload)) {
-                appLog('Wrong echo data!');
-                return;
-            }
-            var elapsedMs = new Date - startTime;
-            if (elapsedMs >= durationMs) {
-                var callsPerSecond = callCount * 1000 / elapsedMs;
-                appLog('Calls per second: ' + callsPerSecond);
-                return;
-            }
-            echoMessage();
-        }
-        function fail() {
-            appLog('Call failed!');
-        }
-        function echoMessage() {
-            setTimeout(function() {
-                echo(win, fail, payload);
-            });
-        }
-
-        appLog('Started exec benchmark with payload length: ' + payloadView.length);
-        echoMessage();
-        setTimeout(function() {
-            if (!callCount) {
-                alert('Echo plugin did not respond');
-            }
-        }, 500);
-    }
-
-    document.addEventListener("deviceready", function() {
-        deviceReady = true;
-        appLog("Device = " + device.platform + " " + device.version);
-    }, false);
-
-    window.onload = function() {
-        window.setTimeout(function() {
-            if (!deviceReady) {
-                alert("Error: Cordova did not initialize.  Demo will not run correctly.");
-            }
-        }, 1000);
-    };
-
-</script>
-
-  </head>
-  <body id="stage" class="theme">
-    <h1>ArrayBuffer Benchmark</h1>
-    <fieldset>
-        <legend>Settings</legend>
-        <label>Test Duration: <select id="test-duration"><option>1 Second</option><option>5 Seconds</option></select><br></label>
-        <label>Payload size (in bytes) <input id="payload-size" value="1024" style="width:100px"></label><br>
-        <button onclick="benchExec()">Benchmark exec</button><br>
-    </fieldset>
-    <h2>&nbsp</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a><br>
-    <div>Results:</div>
-    <pre id="app-logs" style="white-space:pre-wrap;line-height:initial"></pre>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/benchmarks/autobench.html
----------------------------------------------------------------------
diff --git a/benchmarks/autobench.html b/benchmarks/autobench.html
deleted file mode 100644
index 1a909fb..0000000
--- a/benchmarks/autobench.html
+++ /dev/null
@@ -1,194 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="uubench.js"></script>
-<script>
-    var exec = cordova.require('cordova/exec');
-    var temp, pers, LICENSE_CONTENTS;
-    function $(id) { return document.getElementById(id); }
-
-    function copy_license(filesystem, callback) {
-        filesystem.root.getFile("LICENSE", {create: true, exclusive: false}, function(entry) {
-            entry.createWriter(function(writer) {
-                writer.onwriteend = function(evt) {
-                    callback();
-                };
-                writer.write(LICENSE_CONTENTS);
-            }, function(err) {
-                alert('Error creating LICENSE FileWriter');
-            });
-        }, function(err) {
-            alert('Error copying LICENSE to a file system');
-        });
-    }
-
-    var suite = new uubench.Suite({
-        start:function() {
-            $('loading').innerHTML = "BENCHMARKING IN PROGRESS...";
-        },
-        result: function(name, stats) {
-            var secs = stats.elapsed/1000;
-            var itspersec = stats.iterations / secs;
-            $('table-results').innerHTML += '<tr><td>' + name + '</td><td>' + itspersec + ' per second.</td></tr>';
-            console.log(name + ' bench complete.');
-            results[name] = stats;
-        },
-        min: 2000, // each benchmark should run for at least 2000ms
-        done:function() { 
-            $('loading').innerHTML = "Benchmarks complete.";
-            $('backBtn').style.display="block";
-        }
-    });
-    var results = {};
-
-    document.addEventListener("deviceready", function() {
-        deviceReady = true;
-        var xhr = new XMLHttpRequest();
-        xhr.open("GET", "../LICENSE", true);
-        xhr.onreadystatechange = function() {
-            if (xhr.readyState == 4) {
-                if (xhr.responseText.length > 0) {
-                    LICENSE_CONTENTS = xhr.responseText;
-                } else {
-                    alert('Some prereq XHR stuff to get license content failed mang.');
-                }
-                window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(p_fs) {
-                    pers = p_fs;
-                    copy_license(pers, function() {
-                        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function(t_fs) {
-                            temp = t_fs;
-                            copy_license(temp, function() {
-                                setTimeout(bench, 250);
-                            });
-                        }, function(t_e) {
-                            alert('Failed to get TEMPORARY File System');
-                        });
-                    });
-                }, function(p_e) {
-                    alert('Failed to get PERSISTENT File System');
-                });
-            }
-        };
-        xhr.send(null);
-    });
-
-    window.onload = function() {
-        window.setTimeout(function() {
-            if (!deviceReady) {
-                alert("Error: Cordova did not initialize.  Demo will not run correctly.");
-            }
-        }, 1000);
-    };
-function bench() {
-    suite.bench("Echo exec callbacks", function(next) {
-        exec(function() {
-            // win
-            next();
-        }, function() {
-            // fail
-            next();
-        }, "Echo", "echo", ["test"]);
-    });
-    suite.bench("Echo exec invocations", function(next) {
-        exec(function() {
-            // win
-        }, function() {
-            // fail
-        }, "Echo", "echo", ["test"]);
-        next();
-    });
-    suite.bench("XHR to within-package 11kb asset.", function(next) {
-        var xhr = new XMLHttpRequest();
-        xhr.open("GET", "../LICENSE", true);
-        xhr.onreadystatechange = function() {
-            if (xhr.readyState == 4) {
-                // The result status is being compared to 0 for success instead of 200. This is because the file and ftp schemes do not use HTTP result codes.
-                if (xhr.status == 0 && xhr.responseText.length > 0) {
-                    next();
-                } else {
-                    alert('There was a problem during XHR file read!');
-                }
-            }
-        };
-        xhr.send(null);
-    });
-    if (temp) {
-        suite.bench("Get contents of 11kb asset located on TEMPORARY File System using FileReader's readAsText method.", function(next) {
-            temp.root.getFile("LICENSE", null, function(entry) {
-                entry.file(function(file) {
-                    var reader = new FileReader();
-                    reader.onloadend = function(evt) {
-                        next();
-                    };
-                    reader.readAsText(file);
-                }, function(err) {
-                    alert('Error getting File object from LICENSE file in TEMP FS.');
-                });
-            }, function(err) {
-                alert('Error getting LICENSE file from root of TEMP FS.');
-            });
-        });
-    }
-    if (pers) {
-        suite.bench("Get contents of 11kb asset located on PERSISTENT File System using FileReader's readAsText method.", function(next) {
-            pers.root.getFile("LICENSE", null, function(entry) {
-                entry.file(function(file) {
-                    var reader = new FileReader();
-                    reader.onloadend = function(evt) {
-                        next();
-                    };
-                    reader.readAsText(file);
-                }, function(err) {
-                    alert('Error getting File object from LICENSE file in PERSISTENT FS.');
-                });
-            }, function(err) {
-                alert('Error getting LICENSE file from root of PERSISTENT FS.');
-            });
-        });
-    }
-    suite.run();
-}
-</script>
-
-  </head>
-  <body id="stage" class="theme">
-    <h1>Auto-Benchmarks</h1>
-    <h2 id="loading"></h2>
-    <table>
-        <thead style="font-weight:bold;text-align:center;">
-            <tr>
-                <td>Name</td>
-                <td>Results</td>
-            </tr>
-        </thead>
-        <tbody id="table-results">
-        </tbody>
-    </table>
-    <h2>&nbsp</h2><a href="javascript:" class="backBtn" style="display:none" id='backBtn' onclick="backHome();">Back</a><br>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/benchmarks/exec.html
----------------------------------------------------------------------
diff --git a/benchmarks/exec.html b/benchmarks/exec.html
deleted file mode 100644
index cd51ca4..0000000
--- a/benchmarks/exec.html
+++ /dev/null
@@ -1,239 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script src="../cordova-incl.js"></script>
-    <script src="setImmediate.js"></script>
-<script>
-    var exec = cordova.require('cordova/exec'),
-        appLogElem = null,
-        deviceReady = false,
-        inProgress = false;
-
-    function appLog(message) {
-        if (!appLogElem) {
-            appLogElem = document.getElementById('app-logs');
-        }
-        appLogElem.innerText += message + '\n';
-        if (window.console) {
-            console.log(message);
-        }
-    }
-
-    function clearLogs() {
-        appLogElem.innerHTML = '';
-    }
-
-    function updateUi(val) {
-        inProgress = val;
-        var goBtn = document.getElementById('go-btn');
-        goBtn.textContent = inProgress ? 'Stop' : 'Start';
-        cordova.echo.stopBulkEcho();
-    }
-
-    function createPayload(size, binary) {
-        if (!binary) {
-            return new Array(size * 10 + 1).join('012\n\n 6789');
-        }
-        size = size * 100;
-        var bufView = new Uint8Array(size);
-        for (var i = 0; i < size; ++i) {
-          bufView[i] = i % 20;
-        }
-        return bufView.buffer;
-    }
-
-    function benchExec() {
-        updateUi(!inProgress);
-        if (!inProgress) {
-            return;
-        }
-
-        var echo = cordova.echo,
-            startTime = +new Date,
-            callCount = 0,
-            elapsedMs,
-            lastReportMs = 0,
-            durationMs = parseInt(document.getElementById('test-duration').value, 10) * 1000,
-            asyncEcho = document.getElementById('async-echo').checked,
-            useSetTimeout = document.getElementById('use-setTimeout').checked,
-            bulkEcho = document.getElementById('bulk-echo').checked,
-            jsToNativeMode = document.getElementById('js-native-modes').value,
-            nativeToJsMode = document.getElementById('native-js-modes').value,
-            payloadSize = +document.getElementById('payload-size').value,
-            binaryPayload = document.getElementById('binary-payload').checked,
-            binaryAsyncEncode = document.getElementById('binary-async-encode').checked,
-            binaryAsyncDecode = document.getElementById('binary-async-decode').checked,
-            soFarEl = document.getElementById('so-far'),
-            payload = createPayload(payloadSize, binaryPayload);
-
-        cordova.ASYNC_AB_ENCODE = binaryAsyncEncode;
-        cordova.ASYNC_AB_DECODE = binaryAsyncDecode;
-
-        function reportProgress() {
-            var callsPerSecond = String(callCount * 1000 / elapsedMs).slice(0, 6);
-            soFarEl.textContent = callsPerSecond + ' ops';
-            appLog('Calls per second: ' + callsPerSecond);
-        }
-        function win(result) {
-            if (!inProgress) {
-                console.log('got an excess echo');
-                return;
-            }
-            callCount++;
-            if (result.length !== payload.length || result.byteLength !== payload.byteLength) {
-                appLog('Wrong echo data!');
-                updateUi(false);
-            }
-            elapsedMs = new Date - startTime;
-            if (inProgress && elapsedMs < durationMs) {
-                if (elapsedMs - lastReportMs > 1000) {
-                    reportProgress();
-                    lastReportMs = elapsedMs;
-                }
-                if (bulkEcho) {
-                    // automatically keeps coming.
-                } else if (useSetTimeout) {
-                    setImmediate(echoMessage);
-                } else {
-                    echoMessage();
-                }
-            } else {
-                reportProgress();
-                updateUi(false);
-            }
-        }
-        function fail() {
-            appLog('Call failed!');
-        }
-        function echoMessage() {
-            echo(win, fail, payload, asyncEcho);
-        }
-
-        var logMsg = 'Started exec benchmark with setImmediate: ' + useSetTimeout + ' asyncEcho: ' + asyncEcho + ' payload length: ' + payloadSize;
-        if (jsToNativeMode) {
-            exec.setJsToNativeBridgeMode(+jsToNativeMode);
-            logMsg += ' jsToNativeMode: ' + jsToNativeMode;
-        }
-        if (nativeToJsMode) {
-            exec.setNativeToJsBridgeMode(+nativeToJsMode);
-            logMsg += ' nativeToJsMode: ' + nativeToJsMode;
-        }
-        appLog(logMsg);
-        if (bulkEcho) {
-          echo.bulkEcho(payload, 50, win);
-        } else {
-          echoMessage();
-        }
-        setTimeout(function() {
-            if (!callCount) {
-                alert('Echo plugin did not respond');
-            }
-        }, 500);
-    }
-
-    function configureDragMe() {
-        var dragMeEl = document.getElementById('drag-me');
-        dragMeEl.ontouchmove = function(e) {
-            e.preventDefault();
-            var touch = e.touches[0];
-            dragMeEl.style.left = touch.pageX - 50 + 'px';
-            dragMeEl.style.top = touch.pageY - 50 + 'px';
-        }
-    }
-    function configure() {
-        function configureModes(elemId, modes) {
-            var selectElem = document.getElementById(elemId);
-            for (var modeName in modes) {
-                var optionElem = document.createElement('option');
-                optionElem.value = modes[modeName];
-                optionElem.innerText = modeName;
-                selectElem.appendChild(optionElem);
-            }
-            selectElem.parentNode.style.display = 'block';
-        }
-        if (exec.jsToNativeModes) {
-            configureModes('js-native-modes', exec.jsToNativeModes);
-        }
-        if (exec.nativeToJsModes) {
-            configureModes('native-js-modes', exec.nativeToJsModes);
-        }
-        configureDragMe();
-    }
-
-
-    document.addEventListener("deviceready", function() {
-        deviceReady = true;
-        appLog("Device="+device.platform+" "+device.version);
-        configure();
-    }, false);
-
-    window.onload = function() {
-        window.setTimeout(function() {
-            if (!deviceReady) {
-                alert("Error: Cordova did not initialize.  Demo will not run correctly.");
-            }
-        }, 1000);
-    };
-
-</script>
-
-  </head>
-  <body id="stage" class="theme">
-    <h1>exec() Benchmark</h1>
-    Before running on Android, set the following constants in NativeToJsMessagingBridge:
-    <ul>
-      <li>ENABLE_LOCATION_CHANGE_EXEC_MODE = true
-      <li>DISABLE_EXEC_CHAINING = true
-    </ul>
-    As of iOS 7.0.2, Andrew found that the iframe bridge is still the fastest on iOS.
-    <fieldset>
-        <legend>Settings</legend>
-        <label>Test Duration: <select id="test-duration"><option>1 Second</option><option>3 Seconds</option><option>10 seconds</option></select><br></label>
-        <label style="display:none">JS-&gt;Native Bridge Mode: <select id="js-native-modes"></select><br></label>
-        <label style="display:none">Native-&gt;JS Bridge Mode: <select id="native-js-modes"></select><br></label>
-        <label><input type="checkbox" id="use-setTimeout"> Force async JS-&gt;Native (avoids evalAndFetch optimization on iOS)</label><br>
-        <label><input type="checkbox" id="async-echo"> Force async Native-&gt;JS</label><br>
-        <label><input type="checkbox" id="bulk-echo"> Bulk Echo Mode (test only native-&gt;JS)</label><br>
-        <label><input type="checkbox" id="binary-payload"> Binary Payload</label><br>
-        These two require async_base64_android branch of cordova-js<br>
-        <label><input type="checkbox" id="binary-async-encode"> Use FileReader to encode binary</label><br>
-        <label><input type="checkbox" id="binary-async-decode"> Use XHR to decode binary</label><br>
-        <label>Payload size (in 100s of bytes) <input id="payload-size" value="5" style="width:100px"></label><br>
-        <button id="go-btn" onclick="benchExec()">Start</button><br>
-    </fieldset>
-    <div>some text.<br>
-        <div style="position:absolute;height:100px;background:red;width:100px;left:250px;top:50px;z-index:5" id="drag-me">Drag Me<div id="so-far"></div></div>
-        <input value="dummy input"> text box to see if focus is lost by bridge or if there is typing lag.
-    </div>
-    <h2>&nbsp</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a><br>
-    <div>Results: <a href="javascript:clearLogs();">Clear</a></div>
-    <pre id="app-logs" style="white-space:pre-wrap;line-height:initial; margin-bottom:500px"></pre>
-    You've reached the bottom.
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/benchmarks/index.html
----------------------------------------------------------------------
diff --git a/benchmarks/index.html b/benchmarks/index.html
deleted file mode 100644
index a4d7419..0000000
--- a/benchmarks/index.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script src="../cordova-incl.js"></script>
-  </head>
-  <body id="stage" class="theme">
-    <h1>Benchmarks</h1>
-    <a href="autobench.html" class="btn large">AutoBench</a>
-    <a href="arraybuffer.html" class="btn large">ArrayBuffer</a>
-    <a href="exec.html" class="btn large">Exec Bridge</a>
-    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/benchmarks/setImmediate.js
----------------------------------------------------------------------
diff --git a/benchmarks/setImmediate.js b/benchmarks/setImmediate.js
deleted file mode 100644
index a36b814..0000000
--- a/benchmarks/setImmediate.js
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-(function (global, undefined) {
-    "use strict";
-
-    var tasks = (function () {
-        function Task(handler, args) {
-            this.handler = handler;
-            this.args = args;
-        }
-        Task.prototype.run = function () {
-            // See steps in section 5 of the spec.
-            if (typeof this.handler === "function") {
-                // Choice of `thisArg` is not in the setImmediate spec; `undefined` is in the setTimeout spec though:
-                // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html
-                this.handler.apply(undefined, this.args);
-            } else {
-                var scriptSource = "" + this.handler;
-                /*jshint evil: true */
-                eval(scriptSource);
-            }
-        };
-
-        var nextHandle = 1; // Spec says greater than zero
-        var tasksByHandle = {};
-        var currentlyRunningATask = false;
-
-        return {
-            addFromSetImmediateArguments: function (args) {
-                var handler = args[0];
-                var argsToHandle = Array.prototype.slice.call(args, 1);
-                var task = new Task(handler, argsToHandle);
-
-                var thisHandle = nextHandle++;
-                tasksByHandle[thisHandle] = task;
-                return thisHandle;
-            },
-            runIfPresent: function (handle) {
-                // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
-                // So if we're currently running a task, we'll need to delay this invocation.
-                if (!currentlyRunningATask) {
-                    var task = tasksByHandle[handle];
-                    if (task) {
-                        currentlyRunningATask = true;
-                        try {
-                            task.run();
-                        } finally {
-                            delete tasksByHandle[handle];
-                            currentlyRunningATask = false;
-                        }
-                    }
-                } else {
-                    // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
-                    // "too much recursion" error.
-                    global.setTimeout(function () {
-                        tasks.runIfPresent(handle);
-                    }, 0);
-                }
-            },
-            remove: function (handle) {
-                delete tasksByHandle[handle];
-            }
-        };
-    }());
-
-    function canUseNextTick() {
-        // Don't get fooled by e.g. browserify environments.
-        return typeof process === "object" &&
-               Object.prototype.toString.call(process) === "[object process]";
-    }
-
-    function canUseMessageChannel() {
-        return !!global.MessageChannel;
-    }
-
-    function canUsePostMessage() {
-        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
-        // where `global.postMessage` means something completely different and can't be used for this purpose.
-
-        if (!global.postMessage || global.importScripts) {
-            return false;
-        }
-
-        var postMessageIsAsynchronous = true;
-        var oldOnMessage = global.onmessage;
-        global.onmessage = function () {
-            postMessageIsAsynchronous = false;
-        };
-        global.postMessage("", "*");
-        global.onmessage = oldOnMessage;
-
-        return postMessageIsAsynchronous;
-    }
-
-    function canUseReadyStateChange() {
-        return "document" in global && "onreadystatechange" in global.document.createElement("script");
-    }
-
-    function installNextTickImplementation(attachTo) {
-        attachTo.setImmediate = function () {
-            var handle = tasks.addFromSetImmediateArguments(arguments);
-
-            process.nextTick(function () {
-                tasks.runIfPresent(handle);
-            });
-
-            return handle;
-        };
-    }
-
-    function installMessageChannelImplementation(attachTo) {
-        var channel = new global.MessageChannel();
-        channel.port1.onmessage = function (event) {
-            var handle = event.data;
-            tasks.runIfPresent(handle);
-        };
-        attachTo.setImmediate = function () {
-            var handle = tasks.addFromSetImmediateArguments(arguments);
-
-            channel.port2.postMessage(handle);
-
-            return handle;
-        };
-    }
-
-    function installPostMessageImplementation(attachTo) {
-        // Installs an event handler on `global` for the `message` event: see
-        // * https://developer.mozilla.org/en/DOM/window.postMessage
-        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
-
-        var MESSAGE_PREFIX = "com.bn.NobleJS.setImmediate" + Math.random();
-
-        function isStringAndStartsWith(string, putativeStart) {
-            return typeof string === "string" && string.substring(0, putativeStart.length) === putativeStart;
-        }
-
-        function onGlobalMessage(event) {
-            // This will catch all incoming messages (even from other windows!), so we need to try reasonably hard to
-            // avoid letting anyone else trick us into firing off. We test the origin is still this window, and that a
-            // (randomly generated) unpredictable identifying prefix is present.
-            if (event.source === global && isStringAndStartsWith(event.data, MESSAGE_PREFIX)) {
-                var handle = event.data.substring(MESSAGE_PREFIX.length);
-                tasks.runIfPresent(handle);
-            }
-        }
-        if (global.addEventListener) {
-            global.addEventListener("message", onGlobalMessage, false);
-        } else {
-            global.attachEvent("onmessage", onGlobalMessage);
-        }
-
-        attachTo.setImmediate = function () {
-            var handle = tasks.addFromSetImmediateArguments(arguments);
-
-            // Make `global` post a message to itself with the handle and identifying prefix, thus asynchronously
-            // invoking our onGlobalMessage listener above.
-            global.postMessage(MESSAGE_PREFIX + handle, "*");
-
-            return handle;
-        };
-    }
-
-    function installReadyStateChangeImplementation(attachTo) {
-        attachTo.setImmediate = function () {
-            var handle = tasks.addFromSetImmediateArguments(arguments);
-
-            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
-            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
-            var scriptEl = global.document.createElement("script");
-            scriptEl.onreadystatechange = function () {
-                tasks.runIfPresent(handle);
-
-                scriptEl.onreadystatechange = null;
-                scriptEl.parentNode.removeChild(scriptEl);
-                scriptEl = null;
-            };
-            global.document.documentElement.appendChild(scriptEl);
-
-            return handle;
-        };
-    }
-
-    function installSetTimeoutImplementation(attachTo) {
-        attachTo.setImmediate = function () {
-            var handle = tasks.addFromSetImmediateArguments(arguments);
-
-            global.setTimeout(function () {
-                tasks.runIfPresent(handle);
-            }, 0);
-
-            return handle;
-        };
-    }
-
-    if (!global.setImmediate) {
-        // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
-        var attachTo = typeof Object.getPrototypeOf === "function" && "setTimeout" in Object.getPrototypeOf(global) ?
-                          Object.getPrototypeOf(global)
-                        : global;
-
-        if (canUseNextTick()) {
-            // For Node.js before 0.9
-            installNextTickImplementation(attachTo);
-        } else if (canUsePostMessage()) {
-            // For non-IE10 modern browsers
-            installPostMessageImplementation(attachTo);
-        } else if (canUseMessageChannel()) {
-            // For web workers, where supported
-            installMessageChannelImplementation(attachTo);
-        } else if (canUseReadyStateChange()) {
-            // For IE 6–8
-            installReadyStateChangeImplementation(attachTo);
-        } else {
-            // For older browsers
-            installSetTimeoutImplementation(attachTo);
-        }
-
-        attachTo.clearImmediate = tasks.remove;
-    }
-}(typeof global === "object" && global ? global : this));

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/benchmarks/uubench.js
----------------------------------------------------------------------
diff --git a/benchmarks/uubench.js b/benchmarks/uubench.js
deleted file mode 100644
index 17c0c4d..0000000
--- a/benchmarks/uubench.js
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// uubench - Async Benchmarking v0.0.1
-// http://github.com/akdubya/uubench
-//
-// Copyright (c) 2010, Aleksander Williams
-// Released under the MIT License.
-//
-
-(function(uubench){
-
-function Bench(id, test, options, callback) {
-  this.id = id;
-  this.options = options;
-  this.test = test;
-  this.loop = test.length > 1;
-  this.callback = callback;
-}
-
-Bench.prototype.run = function(iter) {
-  var self = this, fn = self.test,
-      checkfn = self.options.type === "adaptive" ? adaptive : fixed,
-      i = iter, pend = i,
-      min = self.options.min, start;
-
-  if (self.loop) {
-    pend = 1;
-    start = new Date();
-    fn(checkfn, i);
-  } else {
-    start = new Date();
-    while (i--) {
-      fn(checkfn);
-    }
-  }
-
-  function fixed() {
-    if (--pend === 0) {
-      var elapsed = new Date() - start;
-      self.callback({iterations: iter, elapsed: elapsed});
-    }
-  }
-
-  function adaptive() {
-    if (--pend === 0) {
-      var elapsed = new Date() - start;
-      if (elapsed < min) {
-        self.run(iter*2);
-      } else {
-        self.callback({iterations: iter, elapsed: elapsed});
-      }
-    }
-  }
-}
-
-uubench.Bench = Bench;
-
-uubench.defaults = {
-  type:       "adaptive", // adaptive or fixed
-  iterations: 10,         // starting iterations
-  min:        100,        // minimum run time (ms) - adaptive only
-  delay:      100         // delay between tests (ms)
-}
-
-function Suite(opts) {
-  for (var key in uubench.defaults) {
-    if (opts[key] === undefined) {
-      opts[key] = uubench.defaults[key];
-    }
-  }
-  this.options = opts;
-  this.tests = [];
-}
-
-Suite.prototype.bench = function(name, fn) {
-  var self = this;
-  self.tests.push(new Bench(name, fn, this.options, function(stats) {
-    self.emit("result", name, stats);
-    self.pending--;
-    self.check();
-  }));
-}
-
-Suite.prototype.run = function() {
-  if (this.pending) return;
-  var self = this, len = self.tests.length;
-  self.emit("start", self.tests);
-  self.start = new Date().getTime();
-  self.pending = len;
-  for (var i=0; i<len; i++) {
-    self.runOne(i);
-  }
-}
-
-Suite.prototype.runOne = function(idx) {
-  var self = this;
-  setTimeout(function() {
-    self.tests[idx].run(self.options.iterations);
-  }, self.options.delay);
-}
-
-Suite.prototype.check = function() {
-  if (this.pending) return;
-  this.emit("done", new Date().getTime() - this.start);
-}
-
-Suite.prototype.emit = function(type) {
-  var event = this.options[type];
-  if (event) {
-    event.apply(this, Array.prototype.slice.call(arguments, 1));
-  }
-}
-
-uubench.Suite = Suite;
-
-})(typeof exports !== 'undefined' ? exports : window.uubench = {});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/camera/index.html
----------------------------------------------------------------------
diff --git a/camera/index.html b/camera/index.html
deleted file mode 100644
index 4f48190..0000000
--- a/camera/index.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-
-    <h1>Camera</h1>
-    <div id="info" style="white-space: pre-wrap">
-        <b>Status:</b> <div id="camera_status"></div>
-        img: <img width="100" id="camera_image">
-        canvas: <canvas id="canvas" width="1" height="1"></canvas>
-    </div>
-    <h2>Cordova Camera API</h2>
-    <div id="image-options"></div>
-    <div class="btn large getPicture">camera.getPicture()</div>
-    <h2>Native File Inputs</h2>
-    <div>input type=file <input type="file" class="testInputTag"></div>
-    <div>capture=camera <input type="file" accept="image/*;capture=camera" class="testInputTag"></div>
-    <div>capture=camcorder <input type="file" accept="video/*;capture=camcorder" class="testInputTag"></div>
-    <div>capture=microphone <input type="file" accept="audio/*;capture=microphone" class="testInputTag"></div>
-    <h2>Actions</h2>
-    <div class="btn large getFileInfo">Get File Metadata</div>
-    <div class="btn large readFile">Read with FileReader</div>
-    <div class="btn large copyImage">Copy Image</div>
-    <div class="btn large writeImage">Write Image</div>
-    <div class="btn large uploadImage">Upload Image</div>
-    <div class="btn large displayImageUsingCanvas">Draw Using Canvas</div>
-    <div class="btn large removeImage">Remove Image</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/camera/index.js
----------------------------------------------------------------------
diff --git a/camera/index.js b/camera/index.js
deleted file mode 100644
index f9435d0..0000000
--- a/camera/index.js
+++ /dev/null
@@ -1,344 +0,0 @@
-var deviceReady = false;
-var platformId = cordova.require('cordova/platform').id;
-var pictureUrl = null;
-var fileObj = null;
-var fileEntry = null;
-var pageStartTime = +new Date();
-
-//default camera options
-var camQualityDefault = ['quality value', 50];
-var camDestinationTypeDefault = ['FILE_URI', 1];
-var camPictureSourceTypeDefault = ['CAMERA', 1];
-var camAllowEditDefault = ['allowEdit', false];
-var camEncodingTypeDefault = ['JPEG', 0];
-var camMediaTypeDefault = ['mediaType', 0];
-var camCorrectOrientationDefault = ['correctOrientation', false];
-var camSaveToPhotoAlbumDefault = ['saveToPhotoAlbum', true];
-
-
-//-------------------------------------------------------------------------
-// Camera
-//-------------------------------------------------------------------------
-
-function log(value) {
-    console.log(value);
-    document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
-}
-
-function clearStatus() {
-    document.getElementById('camera_status').innerHTML = '';
-    document.getElementById('camera_image').src = 'about:blank';
-    var canvas = document.getElementById('canvas');
-    canvas.width = canvas.height = 1;
-    pictureUrl = null;
-    fileObj = null;
-    fileEntry = null;
-}
-
-function setPicture(url, callback) {
-try {
-  window.atob(url);
-  // if we got here it is a base64 string (DATA_URL)
-  url = "data:image/jpeg;base64," + url;
-} catch (e) {
-  // not DATA_URL
-    log('URL: ' + url.slice(0, 100));
-}    
-
-    pictureUrl = url;
-    var img = document.getElementById('camera_image');
-    var startTime = new Date();
-    img.src = url;
-    img.onloadend = function() {
-        log('Image tag load time: ' + (new Date() - startTime));
-        callback && callback();
-    };
-}
-
-function onGetPictureError(e) {
-    log('Error getting picture: ' + e.code);
-}
-
-function getPictureWin(data) {
-    setPicture(data);
-    // TODO: Fix resolveLocalFileSystemURI to work with native-uri.
-    if (pictureUrl.indexOf('file:') == 0 || pictureUrl.indexOf('content:') == 0) {
-        resolveLocalFileSystemURI(data, function(e) {
-            fileEntry = e;
-            logCallback('resolveLocalFileSystemURI()', true)(e.toURL());
-        }, logCallback('resolveLocalFileSystemURI()', false));
-    } else if (pictureUrl.indexOf('data:image/jpeg;base64' == 0)) {
-      // do nothing
-    } else {
-        var path = pictureUrl.replace(/^file:\/\/(localhost)?/, '').replace(/%20/g, ' ');
-        fileEntry = new FileEntry('image_name.png', path);
-    }
-}
-
-function getPicture() {
-    clearStatus();
-    var options = extractOptions();
-    log('Getting picture with options: ' + JSON.stringify(options));
-    var popoverHandle = navigator.camera.getPicture(getPictureWin, onGetPictureError, options);
-
-    // Reposition the popover if the orientation changes.
-    window.onorientationchange = function() {
-        var newPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0);
-        popoverHandle.setPosition(newPopoverOptions);
-    }
-}
-
-function uploadImage() {
-    var ft = new FileTransfer(),
-        uploadcomplete=0,
-        progress = 0,
-        options = new FileUploadOptions();
-    options.fileKey="photo";
-    options.fileName='test.jpg';
-    options.mimeType="image/jpeg";
-    ft.onprogress = function(progressEvent) {
-        log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total);
-    };
-    var server = "http://cordova-filetransfer.jitsu.com";
-
-    ft.upload(pictureUrl, server + '/upload', win, fail, options);
-    function win(information_back){
-        log('upload complete');
-    }
-    function fail(message) {
-        log('upload failed: ' + JSON.stringify(message));
-    }
-}
-
-function logCallback(apiName, success) {
-    return function() {
-        log('Call to ' + apiName + (success ? ' success: ' : ' failed: ') + JSON.stringify([].slice.call(arguments)));
-    };
-}
-
-/**
- * Select image from library using a NATIVE_URI destination type
- * This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL.
- */
-function readFile() {
-    function onFileReadAsDataURL(evt) {
-        var img = document.getElementById('camera_image');
-        img.style.visibility = "visible";
-        img.style.display = "block";
-        img.src = evt.target.result;
-        log("FileReader.readAsDataURL success");
-    };
-
-    function onFileReceived(file) {
-        log('Got file: ' + JSON.stringify(file));
-        fileObj = file;
-
-        var reader = new FileReader();
-        reader.onload = function() {
-            log('FileReader.readAsDataURL() - length = ' + reader.result.length);
-        };
-        reader.onerror = logCallback('FileReader.readAsDataURL', false);
-        reader.readAsDataURL(file);
-    };
-    // Test out onFileReceived when the file object was set via a native <input> elements.
-    if (fileObj) {
-        onFileReceived(fileObj);
-    } else {
-        fileEntry.file(onFileReceived, logCallback('FileEntry.file', false));
-    }
-}
-function getFileInfo() {
-    // Test FileEntry API here.
-    fileEntry.getMetadata(logCallback('FileEntry.getMetadata', true), logCallback('FileEntry.getMetadata', false));
-    fileEntry.setMetadata(logCallback('FileEntry.setMetadata', true), logCallback('FileEntry.setMetadata', false), { "com.apple.MobileBackup": 1 });
-    fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false));
-    fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false));
-};
-
-/**
- * Copy image from library using a NATIVE_URI destination type
- * This calls FileEntry.copyTo and FileEntry.moveTo.
- */
-function copyImage() {
-    var onFileSystemReceived = function(fileSystem) {
-        var destDirEntry = fileSystem.root;
-
-        // Test FileEntry API here.
-        fileEntry.copyTo(destDirEntry, 'copied_file.png', logCallback('FileEntry.copyTo', true), logCallback('FileEntry.copyTo', false));
-        fileEntry.moveTo(destDirEntry, 'moved_file.png', logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
-    };
-
-    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, onFileSystemReceived, null);
-};
-
-/**
- * Write image to library using a NATIVE_URI destination type
- * This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate.
- */
-function writeImage() {
-    var onFileWriterReceived = function(fileWriter) {
-        fileWriter.onwrite = logCallback('FileWriter.write', true);
-        fileWriter.onerror = logCallback('FileWriter.write', false);
-        fileWriter.write("some text!");
-    };
-
-    var onFileTruncateWriterReceived = function(fileWriter) {
-        fileWriter.onwrite = logCallback('FileWriter.truncate', true);
-        fileWriter.onerror = logCallback('FileWriter.truncate', false);
-        fileWriter.truncate(10);
-    };
-
-    fileEntry.createWriter(onFileWriterReceived, logCallback('FileEntry.createWriter', false));
-    fileEntry.createWriter(onFileTruncateWriterReceived, null);
-};
-
-function displayImageUsingCanvas() {
-    var canvas = document.getElementById('canvas');
-    var img = document.getElementById('camera_image');
-    var w = img.width;
-    var h = img.height;
-    h = 100 / w * h;
-    w = 100;
-    canvas.width = w;
-    canvas.height= h;
-    var context = canvas.getContext('2d');
-    context.drawImage(img, 0, 0, w, h);
-};
-
-/**
- * Remove image from library using a NATIVE_URI destination type
- * This calls FileEntry.remove.
- */
-function removeImage() {
-    fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
-};
-
-function testInputTag(inputEl) {
-    clearStatus();
-    // iOS 6 likes to dead-lock in the onchange context if you
-    // do any alerts or try to remote-debug.
-    window.setTimeout(function() {
-        testNativeFile2(inputEl);
-    }, 0);
-};
-
-function testNativeFile2(inputEl) {
-    if (!inputEl.value) {
-        alert('No file selected.');
-        return;
-    }
-    fileObj = inputEl.files[0];
-    if (!fileObj) {
-        alert('Got value but no file.');
-        return;
-    }
-    var URLApi = window.URL || window.webkitURL;
-    if (URLApi) {
-        var blobURL = URLApi.createObjectURL(fileObj);
-        if (blobURL) {
-            setPicture(blobURL, function() {
-                URLApi.revokeObjectURL(blobURL);
-            });
-        } else {
-            log('URL.createObjectURL returned null');
-        }
-    } else {
-        log('URL.createObjectURL() not supported.');
-    }
-}
-
-function extractOptions() {
-    var els = document.querySelectorAll('#image-options select');
-    var ret = {};
-    for (var i = 0, el; el = els[i]; ++i) {
-        var value = el.value;
-        if (value === '') continue;
-        if (el.isBool) {
-            ret[el.keyName] = !!+value;
-        } else {
-            ret[el.keyName] = +value;
-        }
-    }
-    return ret;
-}
-
-function createOptionsEl(name, values, selectionDefault) {
-    var container = document.createElement('div');
-    container.style.display = 'inline-block';
-    container.appendChild(document.createTextNode(name + ': '));
-    var select = document.createElement('select');
-    select.keyName = name;
-    container.appendChild(select);
-    
-    // if we didn't get a default value, insert the blank <default> entry
-    if (selectionDefault == undefined) {
-        var opt = document.createElement('option');
-        opt.value = '';
-        opt.text = '<default>';
-        select.appendChild(opt);
-    }
-    
-    select.isBool = typeof values == 'boolean';
-    if (select.isBool) {
-        values = {'true': 1, 'false': 0};
-    }
-    
-    for (var k in values) {
-        var opt = document.createElement('option');
-        opt.value = values[k];
-        opt.textContent = k;
-        if (selectionDefault) {
-            if (selectionDefault[0] == k) {
-                opt.selected = true;
-            }
-        }
-        select.appendChild(opt);
-    }
-    var optionsDiv = document.getElementById('image-options');
-    optionsDiv.appendChild(container);
-}
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-        deviceReady = true;
-        console.log("Device="+device.platform+" "+device.version);
-        createOptionsEl('sourceType', Camera.PictureSourceType, camPictureSourceTypeDefault);
-        createOptionsEl('destinationType', Camera.DestinationType, camDestinationTypeDefault);
-        createOptionsEl('encodingType', Camera.EncodingType, camEncodingTypeDefault);
-        createOptionsEl('mediaType', Camera.MediaType, camMediaTypeDefault);
-        createOptionsEl('quality', {'0': 0, '50': 50, '80': 80, '100': 100}, camQualityDefault);
-        createOptionsEl('targetWidth', {'50': 50, '200': 200, '800': 800, '2048': 2048});
-        createOptionsEl('targetHeight', {'50': 50, '200': 200, '800': 800, '2048': 2048});
-        createOptionsEl('allowEdit', true, camAllowEditDefault);
-        createOptionsEl('correctOrientation', true, camCorrectOrientationDefault);
-        createOptionsEl('saveToPhotoAlbum', true, camSaveToPhotoAlbumDefault);
-        createOptionsEl('cameraDirection', Camera.Direction);
-                      
-    }, false);
-    window.setTimeout(function() {
-        if (!deviceReady) {
-            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-        }
-    },1000);
-};
-
-window.onload = function() {
-  addListenerToClass('getPicture', getPicture);
-  addListenerToClass('testInputTag', function(e) {
-    testInputTag(e.target);
-  }, null, 'change', true);
-  addListenerToClass('getFileInfo', getFileInfo);
-  addListenerToClass('readFile', readFile);
-  addListenerToClass('copyImage', copyImage);
-  addListenerToClass('writeImage', writeImage);
-  addListenerToClass('uploadImage', uploadImage);
-  addListenerToClass('displayImageUsingCanvas', displayImageUsingCanvas);
-  addListenerToClass('removeImage', removeImage);
-
-  addListenerToClass('backBtn', backHome);
-  init();
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/capture/index.html
----------------------------------------------------------------------
diff --git a/capture/index.html b/capture/index.html
deleted file mode 100644
index 9543341..0000000
--- a/capture/index.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-
-    <h1>Capture</h1>
-    <div id="info" style="white-space: pre-wrap">
-        <b>Status:</b> <div id="camera_status"></div>
-        img: <img width="100" id="camera_image">
-        video: <div id="video_container"></div>
-    </div>
-    
-    <h2>Cordova Capture API</h2>
-    <div id="image-options"></div>
-
-    <h2>Actions</h2>
-    <div class="btn large getAudio">Capture 10 secs of audio and play</div>
-    <div class="btn large getImage">Capture 1 image</div>
-    <div class="btn large getVideo">Capture 10 secs of video</div>
-    <div class="btn large resolveVideo">Capture 5 secs of video and resolve</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/capture/index.js
----------------------------------------------------------------------
diff --git a/capture/index.js b/capture/index.js
deleted file mode 100644
index 0f98549..0000000
--- a/capture/index.js
+++ /dev/null
@@ -1,137 +0,0 @@
-var deviceReady = false;
-var platformId = cordova.require('cordova/platform').id;
-var pageStartTime = +new Date();
-
-//-------------------------------------------------------------------------
-// Camera
-//-------------------------------------------------------------------------
-
-function log(value) {
-    console.log(value);
-    document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
-}
-
-function captureAudioWin(mediaFiles){
-    var path = mediaFiles[0].fullPath;
-    log('Audio captured: ' + path);
-    var m = new Media(path);
-    m.play(); 
-}
-
-function captureAudioFail(e){
-    log('Error getting audio: ' + e.code);
-}
-
-function getAudio(){
-    clearStatus();
-    var options = { limit: 1, duration: 10};
-    navigator.device.capture.captureAudio(captureAudioWin, captureAudioFail, options);
-}
-
-function captureImageWin(mediaFiles){
-    var path = mediaFiles[0].fullPath;
-    log('Image captured: ' + path);    
-    document.getElementById('camera_image').src = path;    
-}
-
-function captureImageFail(e){
-    log('Error getting image: ' + e.code);
-}
-
-function getImage(){
-    clearStatus();
-    var options = { limit: 1 };
-    navigator.device.capture.captureImage(captureImageWin, captureImageFail, options);    
-}    
-
-function captureVideoWin(mediaFiles){
-    var path = mediaFiles[0].fullPath;
-    log('Video captured: ' + path);
-    
-    // need to inject the video element into the html
-    // doesn't seem to work if you have a pre-existing video element and
-    // add in a source tag
-    var vid = document.createElement('video');
-    vid.id="theVideo";
-    vid.width = "320";
-    vid.height= "240";
-    vid.controls = "true";
-    var source_vid = document.createElement('source');
-    source_vid.id = "theSource";
-    source_vid.src = path;
-    vid.appendChild(source_vid);
-    document.getElementById('video_container').appendChild(vid);    
-}
-
-function captureVideoFail(e){
-    log('Error getting video: ' + e.code);
-}
-
-function getVideo(){
-    clearStatus();
-    var options = { limit: 1, duration: 10 };
-    navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options);      
-}
-
-function resolveMediaFileURL(mediaFile, callback) {
-    resolveLocalFileSystemURL(mediaFile.localURL, function(entry) {
-        log("Resolved by URL: " + mediaFile.localURL);
-        if (callback) callback();
-    }, function(err) {
-        log("Failed to resolve by URL: " + mediaFile.localURL);
-        log("Error: " + JSON.stringify(err));
-        if (callback) callback();
-    });
-}
-
-function resolveMediaFile(mediaFile, callback) {
-    resolveLocalFileSystemURL(mediaFile.fullPath, function(entry) {
-        log("Resolved by path: " + mediaFile.fullPath);
-        if (callback) callback();
-    }, function(err) {
-        log("Failed to resolve by path: " + mediaFile.fullPath);
-        log("Error: " + JSON.stringify(err));
-        if (callback) callback();
-    });
-}
-    
-function resolveVideo() {
-    clearStatus();
-    var options = { limit: 1, duration: 5 };
-    navigator.device.capture.captureVideo(function(mediaFiles) {
-        captureVideoWin(mediaFiles);
-        resolveMediaFile(mediaFiles[0], function() {
-            resolveMediaFileURL(mediaFiles[0]);
-        });
-    }, captureVideoFail, options);      
-}
-
-function clearStatus() {
-    document.getElementById('camera_status').innerHTML = '';
-    document.getElementById('camera_image').src = 'about:blank';
-}
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-        deviceReady = true;
-        console.log("Device="+device.platform+" "+device.version);
-    }, false);
-    window.setTimeout(function() {
-        if (!deviceReady) {
-            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-        }
-    },1000);
-};
-
-
-window.onload = function() {
-  addListenerToClass('getAudio', getAudio);
-  addListenerToClass('getImage', getImage);
-  addListenerToClass('getVideo', getVideo);
-  addListenerToClass('resolveVideo', resolveVideo);
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/compass/index.html
----------------------------------------------------------------------
diff --git a/compass/index.html b/compass/index.html
deleted file mode 100644
index 1734caa..0000000
--- a/compass/index.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Compass</h1>
-    <div id="info">
-        <b>Status:</b> <span id="compass_status">Stopped</span>
-        <table width="100%"><tr>
-            <td width="33%">Heading: <span id="compassHeading"> </span></td>
-        </tr></table>
-    </div>
-    <h2>Action</h2>
-    <div class="btn large getCompass">Get Compass</div>
-    <div class="btn large watchCompass">Start Watching Compass</div>
-    <div class="btn large stopCompass">Stop Watching Compass</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/compass/index.js
----------------------------------------------------------------------
diff --git a/compass/index.js b/compass/index.js
deleted file mode 100644
index 0735ab2..0000000
--- a/compass/index.js
+++ /dev/null
@@ -1,104 +0,0 @@
-var deviceReady = false;
-
-function roundNumber(num) {
-    var dec = 3;
-    var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
-    return result;
-}
-
-//-------------------------------------------------------------------------
-// Compass
-//-------------------------------------------------------------------------
-var watchCompassId = null;
-
-/**
- * Start watching compass
- */
-var watchCompass = function() {
-    console.log("watchCompass()");
-
-    // Success callback
-    var success = function(a){
-        document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
-    };
-
-    // Fail callback
-    var fail = function(e){
-        console.log("watchCompass fail callback with error code "+e);
-        stopCompass();
-        setCompassStatus(e);
-    };
-
-    // Update heading every 1 sec
-    var opt = {};
-    opt.frequency = 1000;
-    watchCompassId = navigator.compass.watchHeading(success, fail, opt);
-
-    setCompassStatus("Running");
-};
-
-/**
- * Stop watching the acceleration
- */
-var stopCompass = function() {
-    setCompassStatus("Stopped");
-    if (watchCompassId) {
-        navigator.compass.clearWatch(watchCompassId);
-        watchCompassId = null;
-    }
-};
-
-/**
- * Get current compass
- */
-var getCompass = function() {
-    console.log("getCompass()");
-
-    // Stop compass if running
-    stopCompass();
-
-    // Success callback
-    var success = function(a){
-        document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
-    };
-
-    // Fail callback
-    var fail = function(e){
-        console.log("getCompass fail callback with error code "+e);
-        setCompassStatus(e);
-    };
-
-    // Make call
-    var opt = {};
-    navigator.compass.getCurrentHeading(success, fail, opt);
-};
-
-/**
- * Set compass status
- */
-var setCompassStatus = function(status) {
-    document.getElementById('compass_status').innerHTML = status;
-};
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-      if (!deviceReady) {
-        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-      }
-    },1000);
-}
-
-window.onload = function() {
-  addListenerToClass('getCompass', getCompass);
-  addListenerToClass('watchCompass', watchCompass);
-  addListenerToClass('stopCompass', stopCompass);
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/contacts/index.html
----------------------------------------------------------------------
diff --git a/contacts/index.html b/contacts/index.html
deleted file mode 100644
index 5782713..0000000
--- a/contacts/index.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Contacts</h1>    
-    <div id="info">
-        <b>Results:</b><br>
-        <span id="contacts_results"> </span>
-    </div>
-    <h2>Action</h2>
-
-    <div class="btn large getContacts">Get phone's contacts</div>
-    <div class="btn large addContact">Add a new contact 'Dooney Evans'</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/contacts/index.js
----------------------------------------------------------------------
diff --git a/contacts/index.js b/contacts/index.js
deleted file mode 100644
index d3f3312..0000000
--- a/contacts/index.js
+++ /dev/null
@@ -1,90 +0,0 @@
-var deviceReady = false;
-
-//-------------------------------------------------------------------------
-// Contacts
-//-------------------------------------------------------------------------
-function getContacts() {
-    obj = new ContactFindOptions();
-    // show all contacts, so don't filter
-    obj.multiple = true;
-    navigator.contacts.find(
-        ["displayName", "name", "phoneNumbers", "emails", "urls", "note"],
-        function(contacts) {
-            var s = "";
-            if (contacts.length == 0) {
-                s = "No contacts found";
-            }
-            else {
-                s = "Number of contacts: "+contacts.length+"<br><table width='100%'><tr><th>Name</th><td>Phone</td><td>Email</td></tr>";
-                for (var i=0; i<contacts.length; i++) {
-                    var contact = contacts[i];
-                    s = s + "<tr><td>" + contact.name.formatted + "</td><td>";
-                    if (contact.phoneNumbers && contact.phoneNumbers.length > 0) {
-                        s = s + contact.phoneNumbers[0].value;
-                    }
-                    s = s + "</td><td>"
-                    if (contact.emails && contact.emails.length > 0) {
-                        s = s + contact.emails[0].value;
-                    }
-                    s = s + "</td></tr>";
-                }
-                s = s + "</table>";
-            }
-            document.getElementById('contacts_results').innerHTML = s;
-        },
-        function(e) {
-            document.getElementById('contacts_results').innerHTML = "Error: "+e.code;
-        },
-        obj);
-};
-
-function addContact(){
-    try{
-        var contact = navigator.contacts.create({"displayName": "Dooney Evans"});
-        var contactName = {
-            formatted: "Dooney Evans",
-            familyName: "Evans",
-            givenName: "Dooney",
-            middleName: ""
-        };
-
-        contact.name = contactName;
-
-        var phoneNumbers = [1];
-        phoneNumbers[0] = new ContactField('work', '512-555-1234', true);
-        contact.phoneNumbers = phoneNumbers;
-
-        contact.save(
-            function() { alert("Contact saved.");},
-            function(e) { alert("Contact save failed: " + e.code); }
-        );
-        console.log("you have saved the contact");
-    }
-    catch (e){
-        alert(e);
-    }
-
-};
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-      if (!deviceReady) {
-        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-      }
-    },1000);
-}
-
-
-window.onload = function() {
-  addListenerToClass('getContacts', getContacts);
-  addListenerToClass('addContact', addContact);
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/cordova-incl.js
----------------------------------------------------------------------
diff --git a/cordova-incl.js b/cordova-incl.js
deleted file mode 100644
index 713dc1b..0000000
--- a/cordova-incl.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var PLAT;
-(function getPlatform() {
-    var platforms = {
-        amazon_fireos: /cordova-amazon-fireos/,
-        android: /Android/,
-        ios: /(iPad)|(iPhone)|(iPod)/,
-        blackberry10: /(BB10)/,
-        blackberry: /(PlayBook)|(BlackBerry)/,
-        windows8: /MSAppHost/,
-        windowsphone: /Windows Phone/,
-        firefoxos: /Firefox/
-    };
-    for (var key in platforms) {
-        if (platforms[key].exec(navigator.userAgent)) {
-            PLAT = key;
-            break;
-        }
-    }
-})();
-
-var scripts = document.getElementsByTagName('script');
-var currentPath = scripts[scripts.length - 1].src;
-if (PLAT !== "blackberry10" && PLAT !== "firefoxos" && PLAT !== 'windowsphone') {
-    currentPath += '?paramShouldBeIgnored';
-}
-var cordovaPath = currentPath.replace("cordova-incl.js", "cordova.js");
-
-if (!window._doNotWriteCordovaScript) {
-    if (PLAT != "windows8") {
-        document.write('<script type="text/javascript" charset="utf-8" src="' + cordovaPath + '"></script>');
-    } else {
-        var s = document.createElement('script');
-        s.src = cordovaPath;
-        document.head.appendChild(s);
-    }
-}
-
-function addListenerToClass(className, listener, argsArray, action, doNotWrap) {
-    if (!action) {
-      action='click';
-    }
-    var elements = document.getElementsByClassName(className);
-    // choose Event target as a scope (like inline scripts)
-    if (!doNotWrap) {
-      if (argsArray && !Array.isArray(argsArray)) {
-        argsArray = [argsArray];
-      }
-      function callListener(e) {
-        listener.apply(null, argsArray);
-      }
-    } else {
-      callListener = listener;
-    }
-    for (var i = 0; i < elements.length; ++i) {
-      var item = elements[i];  
-      item.addEventListener(action, callListener, false);
-    }
-};
-
-function backHome() {
-    if (window.device && device.platform && (device.platform.toLowerCase() == 'android' || device.platform.toLowerCase() == 'amazon-fireos')) {
-        navigator.app.backHistory();
-    }
-    else {
-        window.history.go(-1);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/createmobilespec/createmobilespec.js
----------------------------------------------------------------------
diff --git a/createmobilespec/createmobilespec.js b/createmobilespec/createmobilespec.js
index 7572852..244c300 100755
--- a/createmobilespec/createmobilespec.js
+++ b/createmobilespec/createmobilespec.js
@@ -43,12 +43,14 @@ var top_dir =             process.cwd() + path.sep,
     cordova_js_git_dir =  path.join(top_dir, "cordova-js"),
     platforms =           [],
     // where to find the /bin/create command and www dir in a non-CLI project
-    platform_layout =     { "android":      { "bin": "cordova-android", 
-                                              "www": "assets" + path.sep + "www" },
+    platform_layout =     { "android":      { "bin": "cordova-android",
+                                              "www": "assets" + path.sep + "www",
+                                              "config": "res" + path.sep + "xml" },
                             "blackberry10": { "bin": "cordova-blackberry" + path.sep + "blackberry10",
                                               "www": "www" },
                             "ios":          { "bin": "cordova-ios",
-                                              "www": "www" },
+                                              "www": "www",
+                                              "config": "CUSTOM" },
                             "windows8":     { "bin": "cordova-windows" + path.sep + "windows8",
                                               "www": "www" },
                             "wp8":          { "bin": "cordova-wp8" + path.sep + "wp8",
@@ -178,13 +180,20 @@ if (argv.plugman) {
         console.log("Creating project " + projName + "...");
         shelljs.exec(platform_layout[platform].bin + path.sep + "bin" + path.sep + "create " + projName + " org.apache.cordova.mobilespecplugman " + projName);
         shelljs.rm("-r", path.join(top_dir, projName, platform_layout[platform].www));
-        shelljs.cp("-r", path.join(mobile_spec_git_dir, "*"), path.join(top_dir, projName, platform_layout[platform].www));
+        shelljs.cp("-r", path.join(mobile_spec_git_dir, "www"), path.join(top_dir, projName, platform_layout[platform].www));
+        var configPath = platform == 'ios' ? getProjName(platform) : platform[platform].config;
+        if (configPath) {
+          shelljs.cp("-f", path.join(mobile_spec_git_dir, "config.xml"), path.join(top_dir, projName, configPath));
+        } else {
+          console.warn('createmobilespec doesn\'t know where config.xml goes for platform ' + platform);
+        }
     });
 } else {
     // Create the project using "cordova create"
     myDelete(cli_project_dir);
     console.log("Creating project mobilespec...");
-    shelljs.exec(cli + " create " + projectDirName + " org.apache.cordova.mobilespec MobileSpec_Tests --link-to cordova-mobile-spec");
+    shelljs.exec(cli + " create " + projectDirName + " org.apache.cordova.mobilespec MobileSpec_Tests --link-to cordova-mobile-spec/www");
+    shelljs.cp("-f", path.join(mobile_spec_git_dir, 'config.xml'), path.join(projectDirName, 'config.xml'));
 
     // Config.json file ---> linked to local libraries
     shelljs.pushd(cli_project_dir);

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/events/index.html
----------------------------------------------------------------------
diff --git a/events/index.html b/events/index.html
deleted file mode 100644
index 3f45021..0000000
--- a/events/index.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Events</h1>
-    <div id="info">
-        <b>Results:</b><br>
-        <span id="results"></span>
-    </div>
-    <input type="text" value="Type here to test events when fields are focused" />
-    <h2>Action</h2>
-    <div class="btn large interceptBackButton">Intercept backbutton</div>
-    <div class="btn large stopInterceptOfBackButton">Stop intercept of backbutton</div>
-    <div class="btn large interceptMenuButton">Intercept menubutton</div>
-    <div class="btn large stopInterceptOfMenuButton">Stop intercept of menubutton</div>
-    <div class="btn large interceptSearchButton">Intercept searchbutton</div>
-    <div class="btn large stopInterceptOfSearchButton">Stop intercept of searchbutton</div>
-    <div class="btn large interceptResume">Intercept resume</div>
-    <div class="btn large stopInterceptOfResume">Stop intercept of resume</div>
-    <div class="btn large interceptPause">Intercept pause</div>
-    <div class="btn large stopInterceptOfPause">Stop intercept of pause</div>
-    <div class="btn large interceptOnline">Intercept online</div>
-    <div class="btn large stopInterceptOfOnline">Stop intercept of online</div>
-    <div class="btn large interceptOffline">Intercept offline</div>
-    <div class="btn large stopInterceptOfOffline">Stop intercept of offline</div>
-
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/events/index.js
----------------------------------------------------------------------
diff --git a/events/index.js b/events/index.js
deleted file mode 100644
index e1bb922..0000000
--- a/events/index.js
+++ /dev/null
@@ -1,94 +0,0 @@
-var deviceReady = false;
-
-function interceptBackbutton() {
-  eventOutput("Back button intercepted");
-}
-function interceptMenubutton() {
-  eventOutput("Menu button intercepted");
-}
-function interceptSearchbutton() {
-  eventOutput("Search button intercepted");
-}
-function interceptResume() {
-  eventOutput("Resume event intercepted");
-}
-function interceptPause() {
-  eventOutput("Pause event intercepted");
-}
-function interceptOnline() {
-  eventOutput("Online event intercepted");
-}
-function interceptOffline() {
-  eventOutput("Offline event intercepted");
-}
-
-var eventOutput = function(s) {
-    var el = document.getElementById("results");
-    el.innerHTML = el.innerHTML + s + "<br>";
-};
-
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-            eventOutput("deviceready event: "+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-      if (!deviceReady) {
-        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-      }
-    },1000);
-}
-
-
-window.onload = function() {
-  addListenerToClass('interceptBackButton', function() {
-    document.addEventListener('backbutton', interceptBackbutton, false);
-  });
-  addListenerToClass('stopInterceptOfBackButton', function() {
-    document.removeEventListener('backbutton', interceptBackbutton, false);
-  });
-  addListenerToClass('interceptMenuButton', function() {
-    document.addEventListener('menubutton', interceptMenubutton, false);
-  });
-  addListenerToClass('stopInterceptOfMenuButton', function() {
-    document.removeEventListener('menubutton', interceptMenubutton, false);
-  });
-  addListenerToClass('interceptSearchButton', function() {
-    document.addEventListener('searchbutton', interceptSearchbutton, false);
-  });
-  addListenerToClass('stopInterceptOfSearchButton', function() {
-    document.removeEventListener('searchbutton', interceptSearchbutton, false);
-  });
-  addListenerToClass('interceptResume', function() {
-    document.addEventListener('resume', interceptResume, false);
-  });
-  addListenerToClass('stopInterceptOfResume', function() {
-    document.removeEventListener('resume', interceptResume, false);
-  });
-  addListenerToClass('interceptPause', function() {
-    document.addEventListener('pause', interceptPause, false);
-  });
-  addListenerToClass('stopInterceptOfPause', function() {
-    document.removeEventListener('pause', interceptPause, false);
-  });
-  addListenerToClass('interceptOnline', function() {
-    document.addEventListener('online', interceptOnline, false);
-  });
-  addListenerToClass('stopInterceptOfOnline', function() {
-    document.removeEventListener('online', interceptOnline, false);
-  });
-  addListenerToClass('interceptOffline', function() {
-    document.addEventListener('offline', interceptOffline, false);
-  });
-  addListenerToClass('stopInterceptOfOffline', function() {
-    document.removeEventListener('offline', interceptOffline, false);
-  });
-
-  addListenerToClass('backBtn', backHome);
-  init();
-}


[13/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/globalization.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/globalization.tests.js b/autotest/tests/globalization.tests.js
deleted file mode 100644
index ddc7c3c..0000000
--- a/autotest/tests/globalization.tests.js
+++ /dev/null
@@ -1,869 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-describe('Globalization (navigator.globalization)', function () {
-
-    //not supported on bb10
-    if (cordova.platformId === 'blackberry10') {
-        return;
-    }
-
-    it("globalization.spec.1 should exist", function() {
-        expect(navigator.globalization).toBeDefined();
-    });
-    
-    describe("getPreferredLanguage", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.getPreferredLanguage).toBeDefined();
-            expect(typeof navigator.globalization.getPreferredLanguage == 'function').toBe(true);
-        });
-        it("globalization.spec.3 getPreferredLanguage success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getPreferredLanguage(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("getLocaleName", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.getLocaleName).toBeDefined();
-            expect(typeof navigator.globalization.getLocaleName == 'function').toBe(true);
-        });
-        it("globalization.spec.3 getLocaleName success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getLocaleName(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe('Globalization Constants (window.Globalization)', function () {
-        it("globalization.spec.1 should exist", function() {
-            expect(window.GlobalizationError).toBeDefined();
-            expect(window.GlobalizationError.UNKNOWN_ERROR).toBe(0);
-            expect(window.GlobalizationError.FORMATTING_ERROR).toBe(1);
-            expect(window.GlobalizationError.PARSING_ERROR).toBe(2);
-            expect(window.GlobalizationError.PATTERN_ERROR).toBe(3);
-        });
-    });
-    
-    describe("dateToString", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.dateToString).toBeDefined();
-            expect(typeof navigator.globalization.dateToString == 'function').toBe(true);
-        });
-        it("globalization.spec.5 dateToString using default options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.6 dateToString using formatLength=short and selector=date options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'short', selector: 'date'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.7 dateToString using formatLength=full and selector=date options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'full', selector: 'date'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.8 dateToString using formatLength=medium and selector=date and time(default) options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'medium'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.9 dateToString using formatLength=long and selector=date and time(default) options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'long'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.10 dateToString using formatLength=full and selector=date and time(default) options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'full'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("stringToDate", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.stringToDate).toBeDefined();
-            expect(typeof navigator.globalization.stringToDate == 'function').toBe(true);
-        });
-        it("globalization.spec.12 stringToDate using default options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.year).toBeDefined();
-                    expect(typeof a.year).toBe('number');
-                    expect(a.year >= 0 && a.year <=9999).toBe(true);
-                    expect(a.month).toBeDefined();
-                    expect(typeof a.month).toBe('number');
-                    expect(a.month >= 0 && a.month <=11).toBe(true);
-                    expect(a.day).toBeDefined();
-                    expect(typeof a.day).toBe('number');
-                    expect(a.day >= 1 && a.day <=31).toBe(true);
-                    expect(a.hour).toBeDefined();
-                    expect(typeof a.hour).toBe('number');
-                    expect(a.hour >= 0 && a.hour <=23).toBe(true);
-                    expect(a.minute).toBeDefined();
-                    expect(typeof a.minute).toBe('number');
-                    expect(a.minute >= 0 && a.minute <=59).toBe(true);
-                    expect(a.second).toBeDefined();
-                    expect(typeof a.second).toBe('number');
-                    expect(a.second >= 0 && a.second <=59).toBe(true);
-                    expect(a.millisecond).toBeDefined();
-                    expect(typeof a.millisecond).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-                
-            var win2 = function(a) {
-                navigator.globalization.stringToDate(a.value, win, fail);                
-            };
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win2, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.13 stringToDate using formatLength=short and selector=date options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.year).toBeDefined();
-                    expect(typeof a.year).toBe('number');
-                    expect(a.year >= 0 && a.year <=9999).toBe(true);
-                    expect(a.month).toBeDefined();
-                    expect(typeof a.month).toBe('number');
-                    expect(a.month >= 0 && a.month <=11).toBe(true);
-                    expect(a.day).toBeDefined();
-                    expect(typeof a.day).toBe('number');
-                    expect(a.day >= 1 && a.day <=31).toBe(true);
-                    expect(a.hour).toBeDefined();
-                    expect(typeof a.hour).toBe('number');
-                    expect(a.hour >= 0 && a.hour <=23).toBe(true);
-                    expect(a.minute).toBeDefined();
-                    expect(typeof a.minute).toBe('number');
-                    expect(a.minute >= 0 && a.minute <=59).toBe(true);
-                    expect(a.second).toBeDefined();
-                    expect(typeof a.second).toBe('number');
-                    expect(a.second >= 0 && a.second <=59).toBe(true);
-                    expect(a.millisecond).toBeDefined();
-                    expect(typeof a.millisecond).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-                
-            var win2 = function(a) {
-                navigator.globalization.stringToDate(a.value, win, fail, {formatLength: 'short', selector: 'date'});
-            };
-
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win2, fail, {formatLength: 'short', selector: 'date'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.14 stringToDate using formatLength=full and selector=date options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.year).toBeDefined();
-                    expect(typeof a.year).toBe('number');
-                    expect(a.year >= 0 && a.year <=9999).toBe(true);
-                    expect(a.month).toBeDefined();
-                    expect(typeof a.month).toBe('number');
-                    expect(a.month >= 0 && a.month <=11).toBe(true);
-                    expect(a.day).toBeDefined();
-                    expect(typeof a.day).toBe('number');
-                    expect(a.day >= 1 && a.day <=31).toBe(true);
-                    expect(a.hour).toBeDefined();
-                    expect(typeof a.hour).toBe('number');
-                    expect(a.hour >= 0 && a.hour <=23).toBe(true);
-                    expect(a.minute).toBeDefined();
-                    expect(typeof a.minute).toBe('number');
-                    expect(a.minute >= 0 && a.minute <=59).toBe(true);
-                    expect(a.second).toBeDefined();
-                    expect(typeof a.second).toBe('number');
-                    expect(a.second >= 0 && a.second <=59).toBe(true);
-                    expect(a.millisecond).toBeDefined();
-                    expect(typeof a.millisecond).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-
-            var win2 = function(a) {
-                navigator.globalization.stringToDate(a.value, win, fail, {formatLength: 'full', selector: 'date'});
-            };
-            runs(function () {
-                navigator.globalization.dateToString(new Date(), win2, fail, {formatLength: 'full', selector: 'date'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.15 stringToDate using invalid date, error callback should be called with a GlobalizationError object", function() {
-            var win = jasmine.createSpy(),
-                fail = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.code).toBeDefined();
-                    expect(typeof a.code).toBe('number');
-                    expect(a.code === GlobalizationError.PARSING_ERROR).toBe(true);
-                    expect(a.message).toBeDefined();
-                    expect(typeof a.message).toBe('string');
-                    expect(a.message !== "").toBe(true);
-                });
-
-            runs(function () {
-                navigator.globalization.stringToDate('notADate', win, fail, {selector:'foobar'});
-            });
-
-            waitsFor(function () { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(win).not.toHaveBeenCalled();
-            });
-        });
-    });
-
-    describe("getDatePattern", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.getDatePattern).toBeDefined();
-            expect(typeof navigator.globalization.getDatePattern == 'function').toBe(true);
-        });
-        it("globalization.spec.17 getDatePattern using default options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.pattern).toBeDefined();
-                    expect(typeof a.pattern).toBe('string');
-                    expect(a.pattern.length > 0).toBe(true);
-                    expect(a.timezone).toBeDefined();
-                    expect(typeof a.timezone).toBe('string');
-                    expect(a.timezone.length > 0).toBe(true);
-                    expect(a.utc_offset).toBeDefined();
-                    expect(typeof a.utc_offset).toBe('number');
-                    expect(a.dst_offset).toBeDefined();
-                    expect(typeof a.dst_offset).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getDatePattern(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.18 getDatePattern using formatLength=medium and selector=date options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.pattern).toBeDefined();
-                    expect(typeof a.pattern).toBe('string');
-                    expect(a.pattern.length > 0).toBe(true);
-                    expect(a.timezone).toBeDefined();
-                    expect(typeof a.timezone).toBe('string');
-                    expect(a.timezone.length > 0).toBe(true);
-                    expect(a.utc_offset).toBeDefined();
-                    expect(typeof a.utc_offset).toBe('number');
-                    expect(a.dst_offset).toBeDefined();
-                    expect(typeof a.dst_offset).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getDatePattern(win, fail, {formatLength: 'medium', selector: 'date'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });    
-
-    describe("getDateNames", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.getDateNames).toBeDefined();
-            expect(typeof navigator.globalization.getDateNames == 'function').toBe(true);
-        });
-        it("globalization.spec.20 getDateNames using default options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(a.value instanceof Array).toBe(true);
-                    expect(a.value.length > 0).toBe(true);
-                    expect(typeof a.value[0]).toBe('string');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getDateNames(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.21 getDateNames using type=narrow and item=days options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(a.value instanceof Array).toBe(true);
-                    expect(a.value.length > 0).toBe(true);
-                    expect(typeof a.value[0]).toBe('string');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getDateNames(win, fail, {type: 'narrow', item: 'days'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.22 getDateNames using type=narrow and item=months options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(a.value instanceof Array).toBe(true);
-                    expect(a.value.length > 0).toBe(true);
-                    expect(typeof a.value[0]).toBe('string');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getDateNames(win, fail, {type: 'narrow', item: 'months'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.23 getDateNames using type=wide and item=days options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(a.value instanceof Array).toBe(true);
-                    expect(a.value.length > 0).toBe(true);
-                    expect(typeof a.value[0]).toBe('string');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getDateNames(win, fail, {type: 'wide', item: 'days'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.24 getDateNames using type=wide and item=months options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(a.value instanceof Array).toBe(true);
-                    expect(a.value.length > 0).toBe(true);
-                    expect(typeof a.value[0]).toBe('string');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getDateNames(win, fail, {type: 'wide', item: 'months'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("isDayLightSavingsTime", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.isDayLightSavingsTime).toBeDefined();
-            expect(typeof navigator.globalization.isDayLightSavingsTime == 'function').toBe(true);
-        });
-        it("globalization.spec.26 isDayLightSavingsTime using default options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.dst).toBeDefined();
-                    expect(typeof a.dst).toBe('boolean');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.isDayLightSavingsTime(new Date(), win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("getFirstDayOfWeek", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.getFirstDayOfWeek).toBeDefined();
-            expect(typeof navigator.globalization.getFirstDayOfWeek == 'function').toBe(true);
-        });
-        it("globalization.spec.28 getFirstDayOfWeek success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getFirstDayOfWeek(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("numberToString", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.numberToString).toBeDefined();
-            expect(typeof navigator.globalization.numberToString == 'function').toBe(true);
-        });
-        it("globalization.spec.30 numberToString using default options, should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.numberToString(3.25, win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.31 numberToString using type=percent options, should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.numberToString(.25, win, fail, {type: 'percent'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.32 numberToString using type=currency options, should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('string');
-                    expect(a.value.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.numberToString(5.20, win, fail, {type: 'currency'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("stringToNumber", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.stringToNumber).toBeDefined();
-            expect(typeof navigator.globalization.stringToNumber == 'function').toBe(true);
-        });
-        it("globalization.spec.34 stringToNumber using default options, should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('number');
-                    expect(a.value > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            var win2 = function(a) {
-                navigator.globalization.stringToNumber(a.value, win, fail);
-            };
-            
-            runs(function () {
-                navigator.globalization.numberToString(3.25, win2, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.35 stringToNumber using type=percent options, should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.value).toBeDefined();
-                    expect(typeof a.value).toBe('number');
-                    expect(a.value > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            var win2 = function(a) {
-                navigator.globalization.stringToNumber(a.value, win, fail, {type: 'percent'});
-            };
-            
-            runs(function () {
-                navigator.globalization.numberToString(.25, win2, fail, {type: 'percent'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("getNumberPattern", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.getNumberPattern).toBeDefined();
-            expect(typeof navigator.globalization.getNumberPattern == 'function').toBe(true);
-        });
-        it("globalization.spec.37 getNumberPattern using default options, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.pattern).toBeDefined();
-                    expect(typeof a.pattern).toBe('string');
-                    expect(a.pattern.length > 0).toBe(true);
-                    expect(typeof a.symbol).toBe('string');
-                    expect(typeof a.fraction).toBe('number');
-                    expect(typeof a.rounding).toBe('number');
-                    expect(a.positive).toBeDefined();
-                    expect(typeof a.positive).toBe('string');
-                    expect(a.positive.length >= 0).toBe(true);
-                    expect(a.negative).toBeDefined();
-                    expect(typeof a.negative).toBe('string');
-                    expect(a.negative.length >= 0).toBe(true);
-                    expect(a.decimal).toBeDefined();
-                    expect(typeof a.decimal).toBe('string');
-                    expect(a.decimal.length > 0).toBe(true);
-                    expect(a.grouping).toBeDefined();
-                    expect(typeof a.grouping).toBe('string');
-                    expect(a.grouping.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getNumberPattern(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.38 getNumberPattern using type=percent, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.pattern).toBeDefined();
-                    expect(typeof a.pattern).toBe('string');
-                    expect(a.pattern.length > 0).toBe(true);
-                    expect(typeof a.symbol).toBe('string');
-                    expect(typeof a.fraction).toBe('number');
-                    expect(typeof a.rounding).toBe('number');
-                    expect(a.positive).toBeDefined();
-                    expect(typeof a.positive).toBe('string');
-                    expect(a.positive.length >= 0).toBe(true);
-                    expect(a.negative).toBeDefined();
-                    expect(typeof a.negative).toBe('string');
-                    expect(a.negative.length >= 0).toBe(true);
-                    expect(a.decimal).toBeDefined();
-                    expect(typeof a.decimal).toBe('string');
-                    expect(a.decimal.length > 0).toBe(true);
-                    expect(a.grouping).toBeDefined();
-                    expect(typeof a.grouping).toBe('string');
-                    expect(a.grouping.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getNumberPattern(win, fail, {type: 'percent'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("globalization.spec.39 getNumberPattern using type=currency, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.pattern).toBeDefined();
-                    expect(typeof a.pattern).toBe('string');
-                    expect(a.pattern.length > 0).toBe(true);
-                    expect(typeof a.symbol).toBe('string');
-                    expect(typeof a.fraction).toBe('number');
-                    expect(typeof a.rounding).toBe('number');
-                    expect(a.positive).toBeDefined();
-                    expect(typeof a.positive).toBe('string');
-                    expect(a.positive.length >= 0).toBe(true);
-                    expect(a.negative).toBeDefined();
-                    expect(typeof a.negative).toBe('string');
-                    expect(a.negative.length >= 0).toBe(true);
-                    expect(a.decimal).toBeDefined();
-                    expect(typeof a.decimal).toBe('string');
-                    expect(a.decimal.length > 0).toBe(true);
-                    expect(a.grouping).toBeDefined();
-                    expect(typeof a.grouping).toBe('string');
-                    expect(a.grouping.length > 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getNumberPattern(win, fail, {type: 'currency'});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-    
-    describe("getCurrencyPattern", function() {
-        it("globalization.spec.1 should exist", function() {
-            expect(typeof navigator.globalization.getCurrencyPattern).toBeDefined();
-            expect(typeof navigator.globalization.getCurrencyPattern == 'function').toBe(true);
-        });
-        it("globalization.spec.41 getCurrencyPattern using EUR for currency, success callback should be called with a Properties object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(typeof a).toBe('object');
-                    expect(a.pattern).toBeDefined();
-                    expect(typeof a.pattern).toBe('string');
-                    expect(a.pattern.length > 0).toBe(true);
-                    expect(a.code).toBeDefined();
-                    expect(typeof a.code).toBe('string');
-                    expect(a.code.length > 0).toBe(true);
-                    expect(typeof a.fraction).toBe('number');
-                    expect(typeof a.rounding).toBe('number');                   
-                    expect(a.decimal).toBeDefined();
-                    expect(typeof a.decimal).toBe('string');
-                    expect(a.decimal.length >= 0).toBe(true);                    
-                    expect(a.grouping).toBeDefined();
-                    expect(typeof a.grouping).toBe('string');
-                    expect(a.grouping.length >= 0).toBe(true);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.globalization.getCurrencyPattern("EUR", win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/localXHR.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/localXHR.tests.js b/autotest/tests/localXHR.tests.js
deleted file mode 100644
index c50105d..0000000
--- a/autotest/tests/localXHR.tests.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe("XMLHttpRequest", function () {
-
-    var createXHR = function (url, bAsync, win, lose) {
-        var xhr = new XMLHttpRequest();
-        xhr.open("GET", url, bAsync);
-        xhr.onload = win;
-        xhr.onerror = lose;
-        xhr.send();
-        return xhr;
-    }
-
-        it("XMLHttpRequest.spec.1 should exist", function () {
-            expect(window.XMLHttpRequest).toBeDefined();
-            expect(window.XMLHttpRequest.UNSENT).toBe(0);
-            expect(window.XMLHttpRequest.OPENED).toBe(1);
-            expect(window.XMLHttpRequest.HEADERS_RECEIVED).toBe(2);
-            expect(window.XMLHttpRequest.LOADING).toBe(3);
-            expect(window.XMLHttpRequest.DONE).toBe(4);
-        });
-
-        it("XMLHttpRequest.spec.2 should be able to create new XHR", function () {
-
-        	var xhr = new XMLHttpRequest();
-        	expect(xhr).toBeDefined();
-
-    // abort
-        	expect(xhr.abort).toBeDefined();
-        	expect(typeof xhr.abort == 'function').toBe(true);
-
-    // getResponseHeader
-        	expect(xhr.getResponseHeader).toBeDefined();
-        	expect(typeof xhr.getResponseHeader == 'function').toBe(true);
-
-    // getAllResponseHeaders
-        	expect(xhr.getAllResponseHeaders).toBeDefined();
-        	expect(typeof xhr.getAllResponseHeaders == 'function').toBe(true);
-
-    // overrideMimeType
-        	expect(xhr.overrideMimeType).toBeDefined();
-        	expect(typeof xhr.overrideMimeType == 'function').toBe(true);
-        	return;
-    // open
-        	expect(xhr.open).toBeDefined();
-        	expect(typeof xhr.open == 'function').toBe(true);
-    // send
-        	expect(xhr.send).toBeDefined();
-        	expect(typeof xhr.send == 'function').toBe(true);
-    // setRequestHeader
-        	expect(xhr.setRequestHeader).toBeDefined();
-        	expect(typeof xhr.setRequestHeader == 'function').toBe(true);
-        });
-
-        it("XMLHttpRequest.spec.2 should be able to load the current page", function () {
-            var win = jasmine.createSpy().andCallFake(function (res) {});
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR("localXHR.html", true, win, lose);
-            waitsForAny(win, lose);
-
-        });
-
-        it("XMLHttpRequest.spec.9 calls onload from successful http get", function () {
-            var win = jasmine.createSpy().andCallFake(function (res) { });
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR("http://cordova-filetransfer.jitsu.com", true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-        it("XMLHttpRequest.spec.3 should be able to load the current page", function () {
-            var win = jasmine.createSpy().andCallFake(function (res) {});
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR(window.location.href, true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-        it("XMLHttpRequest.spec.4 should be able to load the parent folder page ../index.html", function () {
-            var win = jasmine.createSpy().andCallFake(function (res) {});
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR("../index.html", true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-        it("XMLHttpRequest.spec.5 should be able to load the current page ./???.html", function () {
-            var win = jasmine.createSpy().andCallFake(function (res) { });
-            var lose = createDoNotCallSpy('xhrFail');
-            var fileName = window.location.href.split('#')[0].split('/').pop();
-            var xhr = createXHR("./" + fileName, true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-        it("XMLHttpRequest.spec.6 adds hash-path and loads file okay", function () {
-            window.location = window.location.href + "#asd/asd/asdasd";
-            var win = jasmine.createSpy().andCallFake(function (res) { });
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR(window.location.href, true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-    it("XMLHttpRequest.spec.10 overlapping async calls are not muxed", function () {
-
-        var order = "";
-
-        var winA = jasmine.createSpy("spyWinA").andCallFake(function(){
-            order += "A";  
-        });
-        var winB = jasmine.createSpy("spyWinB").andCallFake(function(){
-            order += "B";  
-        });
-        var lose = createDoNotCallSpy('xhrFail');
-        var fileName = window.location.href.split('#')[0].split('/').pop();
-        createXHR(fileName, true, winA, lose);
-        createXHR(fileName, false, winB, lose);
-
-        waitsFor(function () {
-            return lose.wasCalled ||
-                (winA.wasCalled && winB.wasCalled);
-        }, "Expecting both callbacks to be called.", Tests.TEST_TIMEOUT);
-
-        runs(function () {
-            expect(lose).not.toHaveBeenCalled();
-            expect(winA).toHaveBeenCalled();
-            expect(winB).toHaveBeenCalled();
-            console.log("order = " + order);
-        });
-    });
-
-
-});
-
-// only add these tests if we are testing on windows phone
-
-if (/Windows Phone/.exec(navigator.userAgent)) {
-
-    var createXHR = function (url, bAsync, win, lose) {
-        var xhr = new XMLHttpRequest();
-        xhr.open("GET", url, bAsync);
-        xhr.onload = win;
-        xhr.onerror = lose;
-        xhr.send();
-        return xhr;
-    }
-
-    describe("XMLHttpRequest Windows Phone", function () {
-
-        console.log("running special windows tests");
-        it("XMLHttpRequest.spec.7 should be able to load the (WP8 backwards compatability) root page www/index.html", function () {
-            var win = jasmine.createSpy().andCallFake(function (res) { });
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR("www/index.html", true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-        it("XMLHttpRequest.spec.8 should be able to load the (WP7 backwards compatability) root page app/www/index.html", function () {
-            var win = jasmine.createSpy().andCallFake(function (res) { });
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR("app/www/index.html", true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-        it("XMLHttpRequest.spec.11 should be able to load the current page using window.location with extra / [CB-6299]", function () {
-            var path = window.location.protocol + "/" + window.location.toString().substr(window.location.protocol.length);
-            var win = jasmine.createSpy().andCallFake(function (res) { });
-            var lose = createDoNotCallSpy('xhrFail');
-            var xhr = createXHR(path, true, win, lose);
-            waitsForAny(win, lose);
-        });
-
-    });
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/media.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/media.tests.js b/autotest/tests/media.tests.js
deleted file mode 100644
index 393ca00..0000000
--- a/autotest/tests/media.tests.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Media', function () {
-	it("should exist", function() {
-        expect(Media).toBeDefined();
-		expect(typeof Media).toBe("function");
-	});
-
-    it("media.spec.1 should have the following properties", function() {
-        var media1 = new Media("dummy");
-        expect(media1.id).toBeDefined();
-        expect(media1.src).toBeDefined();
-        expect(media1._duration).toBeDefined();
-        expect(media1._position).toBeDefined();
-        media1.release();
-    });
-    
-    it("should define constants for Media status", function() {
-        expect(Media).toBeDefined();
-        expect(Media.MEDIA_NONE).toBe(0);
-        expect(Media.MEDIA_STARTING).toBe(1);
-		expect(Media.MEDIA_RUNNING).toBe(2);
-		expect(Media.MEDIA_PAUSED).toBe(3);
-		expect(Media.MEDIA_STOPPED).toBe(4);
-	});
-
-	it("should define constants for Media errors", function() {
-        expect(MediaError).toBeDefined();
-        expect(MediaError.MEDIA_ERR_NONE_ACTIVE).toBe(0);
-        expect(MediaError.MEDIA_ERR_ABORTED).toBe(1);
-		expect(MediaError.MEDIA_ERR_NETWORK).toBe(2);
-		expect(MediaError.MEDIA_ERR_DECODE).toBe(3);
-		expect(MediaError.MEDIA_ERR_NONE_SUPPORTED).toBe(4);
-	});
-
-    it("media.spec.2 should contain a play function", function() {
-        var media1 = new Media();
-        expect(media1.play).toBeDefined();
-        expect(typeof media1.play).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.3 should contain a stop function", function() {
-        var media1 = new Media();
-        expect(media1.stop).toBeDefined();
-        expect(typeof media1.stop).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.4 should contain a seekTo function", function() {
-        var media1 = new Media();
-        expect(media1.seekTo).toBeDefined();
-        expect(typeof media1.seekTo).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.5 should contain a pause function", function() {
-        var media1 = new Media();
-        expect(media1.pause).toBeDefined();
-        expect(typeof media1.pause).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.6 should contain a getDuration function", function() {
-        var media1 = new Media();
-        expect(media1.getDuration).toBeDefined();
-        expect(typeof media1.getDuration).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.7 should contain a getCurrentPosition function", function() {
-        var media1 = new Media();
-        expect(media1.getCurrentPosition).toBeDefined();
-        expect(typeof media1.getCurrentPosition).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.8 should contain a startRecord function", function() {
-        var media1 = new Media();
-        expect(media1.startRecord).toBeDefined();
-        expect(typeof media1.startRecord).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.9 should contain a stopRecord function", function() {
-        var media1 = new Media();
-        expect(media1.stopRecord).toBeDefined();
-        expect(typeof media1.stopRecord).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.10 should contain a release function", function() {
-        var media1 = new Media();
-        expect(media1.release).toBeDefined();
-        expect(typeof media1.release).toBe('function');
-        media1.release();
-    });
-
-    it("media.spec.11 should contain a setVolume function", function() {
-        var media1 = new Media();
-        expect(media1.setVolume).toBeDefined();
-        expect(typeof media1.setVolume).toBe('function');
-        media1.release();
-    });
-
-	it("should return MediaError for bad filename", function() {
-		var badMedia = null,
-            win = jasmine.createSpy(),
-            fail = jasmine.createSpy().andCallFake(function (result) {
-                expect(result).toBeDefined();
-                expect(result.code).toBe(MediaError.MEDIA_ERR_ABORTED);
-            });
-
-        //bb10 dialog pops up, preventing tests from running
-        if (cordova.platformId === 'blackberry10') {
-            return;
-        }
-            
-        runs(function () {
-            badMedia = new Media("invalid.file.name", win,fail);
-            badMedia.play();
-        });
-
-        waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
-
-        runs(function () {
-            expect(win).not.toHaveBeenCalled();
-            badMedia.release();
-        });
-	});
-
-    it("media.spec.12 position should be set properly", function() {
-        var playcomplete = jasmine.createSpy();
-        var fail = jasmine.createSpy();
-        var mediaState=Media.MEDIA_STOPPED;
-        var statuschange= function(statusCode){
-            mediaState=statusCode;
-        };
-        var media1 = new Media("http://cordova.apache.org/downloads/BlueZedEx.mp3",playcomplete,fail,statuschange),
-            test = jasmine.createSpy().andCallFake(function(position) {
-                    console.log("position = " + position);
-                    expect(position).toBeGreaterThan(0.0);
-                    media1.stop()
-                    media1.release();
-                });
-
-        media1.play();
-
-        if (cordova.platformId !== 'blackberry10') {
-            waitsFor(function () { return mediaState==Media.MEDIA_RUNNING; }, 10000);
-        } else {
-            waits(5000);
-        }
-
-        // make sure we are at least one second into the file
-        waits(1000);
-        runs(function () {
-            expect(fail).not.toHaveBeenCalled();
-             // note that the file is about 60 seconds long and we kill the play almost immediately
-             // as a result, the playcomplete should not happen
-            expect(playcomplete).not.toHaveBeenCalled();
-            media1.getCurrentPosition(test, function () {});
-        });
-
-        waitsFor(function () { return test.wasCalled || fail.wasCalled; }, Tests.TEST_TIMEOUT);
-    });
-
-    it("media.spec.13 duration should be set properly", function() {
-
-        if (cordova.platformId === 'blackberry10') {
-            return;
-        }
-
-        var win = jasmine.createSpy();
-        var fail = jasmine.createSpy();
-        var mediaState=Media.MEDIA_STOPPED;
-        var statuschange= function(statusCode){
-            mediaState=statusCode;
-        };
-        var media1 = new Media("http://cordova.apache.org/downloads/BlueZedEx.mp3",win,fail,statuschange);
-        media1.play();
-        waitsFor(function () { return mediaState==Media.MEDIA_RUNNING; }, 10000);
-        runs(function () {
-            expect(media1.getDuration()).toBeGreaterThan(0.0);
-            expect(fail).not.toHaveBeenCalled();
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/network.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/network.tests.js b/autotest/tests/network.tests.js
deleted file mode 100644
index bf3a940..0000000
--- a/autotest/tests/network.tests.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Network (navigator.connection)', function () {
-    it("network.spec.1 should exist", function() {
-        expect(navigator.network && navigator.network.connection).toBeDefined();
-        expect(navigator.connection).toBeDefined();
-    });
-
-    it("network.spec.2 should be set to a valid value", function() {
-        var validValues = {
-            'unknown': 1,
-            'ethernet': 1,
-            'wifi': 1,
-            '2g': 1,
-            'cellular': 1,
-            '3g': 1,
-            '4g': 1,
-            'none': 1
-        };
-        expect(validValues[navigator.connection.type]).toBe(1);
-    });
-
-    it("network.spec.3 should have the same value in deprecated and non-deprecated apis", function() {
-        expect(navigator.network.connection.type).toBe(navigator.connection.type);
-    });
-
-    it("network.spec.4 should define constants for connection status", function() {
-        expect(Connection.UNKNOWN).toBe("unknown");
-        expect(Connection.ETHERNET).toBe("ethernet");
-        expect(Connection.WIFI).toBe("wifi");
-        expect(Connection.CELL_2G).toBe("2g");
-        expect(Connection.CELL_3G).toBe("3g");
-        expect(Connection.CELL_4G).toBe("4g");
-        expect(Connection.NONE).toBe("none");
-        expect(Connection.CELL).toBe("cellular");
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/notification.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/notification.tests.js b/autotest/tests/notification.tests.js
deleted file mode 100644
index 016bcfb..0000000
--- a/autotest/tests/notification.tests.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Notification (navigator.notification)', function () {
-	it("should exist", function() {
-                expect(navigator.notification).toBeDefined();
-	});
-
-	it("should contain a beep function", function() {
-		expect(typeof navigator.notification.beep).toBeDefined();
-		expect(typeof navigator.notification.beep).toBe("function");
-	});
-
-	it("should contain an alert function", function() {
-		expect(typeof navigator.notification.alert).toBeDefined();
-		expect(typeof navigator.notification.alert).toBe("function");
-	});
-
-	it("should contain a confirm function", function() {
-		expect(typeof navigator.notification.confirm).toBeDefined();
-		expect(typeof navigator.notification.confirm).toBe("function");
-	});
-	
-	it("should contain a prompt function", function() {
-		expect(typeof navigator.notification.prompt).toBeDefined();
-		expect(typeof navigator.notification.prompt).toBe("function");
-	});
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/platform.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/platform.tests.js b/autotest/tests/platform.tests.js
deleted file mode 100644
index 4a1c1a4..0000000
--- a/autotest/tests/platform.tests.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Platform (cordova)', function () {
-    it("platform.spec.1 should exist", function() {
-        expect(cordova).toBeDefined();
-    });
-
-    it("platform.spec.2 exec method should exist", function() {
-        expect(cordova.exec).toBeDefined();
-        expect(typeof cordova.exec).toBe('function');
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/splashscreen.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/splashscreen.tests.js b/autotest/tests/splashscreen.tests.js
deleted file mode 100644
index a57cb9f..0000000
--- a/autotest/tests/splashscreen.tests.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Splashscreen (cordova)', function () {
-    it("splashscreen.spec.1 should exist", function() {
-        expect(navigator.splashscreen).toBeDefined();
-    });
-
-    it("splashscreen.spec.2 exec method should exist", function() {
-        expect(navigator.splashscreen.show).toBeDefined();
-        expect(typeof navigator.splashscreen.show).toBe('function');
-    });
-    
-    it("splashscreen.spec.3 exec method should exist", function() {
-        expect(navigator.splashscreen.hide).toBeDefined();
-        expect(typeof navigator.splashscreen.hide).toBe('function');
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/storage.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/storage.tests.js b/autotest/tests/storage.tests.js
deleted file mode 100644
index 4f4bd5b..0000000
--- a/autotest/tests/storage.tests.js
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe("Session Storage", function () {
-    it("storage.spec.1 should exist", function () {
-        expect(window.sessionStorage).toBeDefined();
-        expect(typeof window.sessionStorage.length).not.toBe('undefined');
-        expect(typeof(window.sessionStorage.key)).toBe('function');
-        expect(typeof(window.sessionStorage.getItem)).toBe('function');
-        expect(typeof(window.sessionStorage.setItem)).toBe('function');
-        expect(typeof(window.sessionStorage.removeItem)).toBe('function');
-        expect(typeof(window.sessionStorage.clear)).toBe('function');
-    });
-
-    it("storage.spec.2 check length", function () {
-        expect(window.sessionStorage.length).toBe(0);
-        window.sessionStorage.setItem("key","value");
-        expect(window.sessionStorage.length).toBe(1);
-        window.sessionStorage.removeItem("key");   
-        expect(window.sessionStorage.length).toBe(0);
-    });
-
-    it("storage.spec.3 check key", function () {
-        expect(window.sessionStorage.key(0)).toBe(null);
-        window.sessionStorage.setItem("test","value");
-        expect(window.sessionStorage.key(0)).toBe("test");
-        window.sessionStorage.removeItem("test");   
-        expect(window.sessionStorage.key(0)).toBe(null);
-    });
-
-    it("storage.spec.4 check getItem", function() {
-        expect(window.sessionStorage.getItem("item")).toBe(null);
-        window.sessionStorage.setItem("item","value");
-        expect(window.sessionStorage.getItem("item")).toBe("value");
-        window.sessionStorage.removeItem("item");   
-        expect(window.sessionStorage.getItem("item")).toBe(null);
-    });
-
-    it("storage.spec.5 check setItem", function() {
-        expect(window.sessionStorage.getItem("item")).toBe(null);
-        window.sessionStorage.setItem("item","value");
-        expect(window.sessionStorage.getItem("item")).toBe("value");
-        window.sessionStorage.setItem("item","newval");
-        expect(window.sessionStorage.getItem("item")).toBe("newval");
-        window.sessionStorage.removeItem("item");   
-        expect(window.sessionStorage.getItem("item")).toBe(null);
-    });
-
-    it("storage.spec.6 can remove an item", function () {
-        expect(window.sessionStorage.getItem("item")).toBe(null);
-        window.sessionStorage.setItem("item","value");
-        expect(window.sessionStorage.getItem("item")).toBe("value");
-        window.sessionStorage.removeItem("item");   
-        expect(window.sessionStorage.getItem("item")).toBe(null);
-    });
-
-    it("storage.spec.7 check clear", function() {
-        window.sessionStorage.setItem("item1","value");
-        window.sessionStorage.setItem("item2","value");
-        window.sessionStorage.setItem("item3","value");
-        expect(window.sessionStorage.length).toBe(3);
-        window.sessionStorage.clear();
-        expect(window.sessionStorage.length).toBe(0);
-    });
-
-    it("storage.spec.8 check dot notation", function() {
-        expect(window.sessionStorage.item).not.toBeDefined();
-        window.sessionStorage.item = "value";
-        expect(window.sessionStorage.item).toBe("value");
-        window.sessionStorage.removeItem("item");   
-        expect(window.sessionStorage.item).not.toBeDefined();
-    });
-
-    describe("Local Storage", function () {
-        it("storage.spec.9 should exist", function() {
-            expect(window.localStorage).toBeDefined();
-            expect(window.localStorage.length).toBeDefined();
-            expect(typeof window.localStorage.key).toBe("function");
-            expect(typeof window.localStorage.getItem).toBe("function");
-            expect(typeof window.localStorage.setItem).toBe("function");
-            expect(typeof window.localStorage.removeItem).toBe("function");
-            expect(typeof window.localStorage.clear).toBe("function");
-        });  
-
-        it("storage.spec.10 check length", function() {
-            expect(window.localStorage.length).toBe(0);
-            window.localStorage.setItem("key","value");
-            expect(window.localStorage.length).toBe(1);
-            window.localStorage.removeItem("key");   
-            expect(window.localStorage.length).toBe(0);
-        });
-
-        it("storage.spec.11 check key", function() {
-            expect(window.localStorage.key(0)).toBe(null);
-            window.localStorage.setItem("test","value");
-            expect(window.localStorage.key(0)).toBe("test");
-            window.localStorage.removeItem("test");   
-            expect(window.localStorage.key(0)).toBe(null);
-        });
-
-        it("storage.spec.4 check getItem", function() {
-            expect(window.localStorage.getItem("item")).toBe(null);
-            window.localStorage.setItem("item","value");
-            expect(window.localStorage.getItem("item")).toBe("value");
-            window.localStorage.removeItem("item");   
-            expect(window.localStorage.getItem("item")).toBe(null);
-        });
-
-        it("storage.spec.5 check setItem", function() {
-            expect(window.localStorage.getItem("item")).toBe(null);
-            window.localStorage.setItem("item","value");
-            expect(window.localStorage.getItem("item")).toBe("value");
-            window.localStorage.setItem("item","newval");
-            expect(window.localStorage.getItem("item")).toBe("newval");
-            window.localStorage.removeItem("item");   
-            expect(window.localStorage.getItem("item")).toBe(null);
-        });
-
-        it("storage.spec.14 check removeItem", function() {
-            expect(window.localStorage.getItem("item")).toBe(null);
-            window.localStorage.setItem("item","value");
-            expect(window.localStorage.getItem("item")).toBe("value");
-            window.localStorage.removeItem("item");   
-            expect(window.localStorage.getItem("item")).toBe(null);
-        });
-
-        it("storage.spec.7 check clear", function() {
-            expect(window.localStorage.getItem("item1")).toBe(null);
-            expect(window.localStorage.getItem("item2")).toBe(null);
-            expect(window.localStorage.getItem("item3")).toBe(null);
-            window.localStorage.setItem("item1","value");
-            window.localStorage.setItem("item2","value");
-            window.localStorage.setItem("item3","value");
-            expect(window.localStorage.getItem("item1")).toBe("value");
-            expect(window.localStorage.getItem("item2")).toBe("value");
-            expect(window.localStorage.getItem("item3")).toBe("value");
-            expect(window.localStorage.length).toBe(3);
-            window.localStorage.clear();
-            expect(window.localStorage.length).toBe(0);
-            expect(window.localStorage.getItem("item1")).toBe(null);
-            expect(window.localStorage.getItem("item2")).toBe(null);
-            expect(window.localStorage.getItem("item3")).toBe(null);
-        });
-
-        it("storage.spec.8 check dot notation", function() {
-            expect(window.localStorage.item).not.toBeDefined();
-            window.localStorage.item = "value";
-            expect(window.localStorage.item).toBe("value");
-            window.localStorage.removeItem("item");   
-            expect(window.localStorage.item).not.toBeDefined();
-        });
-    });
-
-    describe("HTML 5 Storage", function () {
-        it("storage.spec.9 should exist", function() {
-            expect(window.openDatabase);
-            
-        });
-        
-        it("storage.spec.17 should contain an openDatabase function", function() {
-            expect(window.openDatabase).toBeDefined();
-            expect(typeof window.openDatabase == 'function').toBe(true);
-        });
-
-        it("storage.spec.18 Should be able to create and drop tables", function() {
-            var win = jasmine.createSpy('win');
-            var fail1 = createDoNotCallSpy('fail1');
-            var fail2 = createDoNotCallSpy('fail2');
-            var db = openDatabase("Database", "1.0", "HTML5 Database API example", 5*1024*1024);
-            db.transaction(function(t) {
-                t.executeSql('CREATE TABLE IF NOT EXISTS foo(id int, name varchar(255));');
-                t.executeSql('CREATE TABLE IF NOT EXISTS foo2(id int, name varchar(255));');
-            }, fail1, step2);
-            function step2() {
-              db.transaction(function(t) {
-                  t.executeSql('DROP TABLE foo;');
-                  t.executeSql('DROP TABLE foo2');
-              }, fail2, win);
-            }
-            waitsForAny(win, fail1, fail2);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/vibration.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/vibration.tests.js b/autotest/tests/vibration.tests.js
deleted file mode 100644
index 18e75f2..0000000
--- a/autotest/tests/vibration.tests.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Vibration (navigator.notification.vibrate)', function () {
-	it("navigator.notification should exist", function() {
-                expect(navigator.notification).toBeDefined();
-	});
-
-	it("should contain a vibrate function", function() {
-		expect(typeof navigator.notification.vibrate).toBeDefined();
-		expect(typeof navigator.notification.vibrate).toBe("function");
-	});
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/whitelist.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/whitelist.tests.js b/autotest/tests/whitelist.tests.js
deleted file mode 100644
index fde24cc..0000000
--- a/autotest/tests/whitelist.tests.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Whitelist API (cordova.whitelist)', function () {
-	it("should exist", function() {
-        expect(cordova.whitelist).toBeDefined();
-	});
-
-    describe("Match function", function() {
-        function expectMatchWithResult(result) {
-            return (function(url, patterns, description) {
-                description = description || ((result ? "should accept " : "should reject ") + url + " for " + JSON.stringify(patterns));
-                it(description, function() {
-                    var cb = jasmine.createSpy();
-                    runs(function() {
-                        cordova.whitelist.match(url, patterns, cb);
-                    });
-                    waitsFor(function() { return cb.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-                    runs(function() {
-                        expect(cb).toHaveBeenCalledWith(result);
-                    });
-                });
-            });
-        }
-
-        var itShouldMatch = expectMatchWithResult(true);
-        var itShouldNotMatch = expectMatchWithResult(false);
-
-        it("should exist", function() {
-            expect(cordova.whitelist.match).toBeDefined();
-            expect(typeof cordova.whitelist.match).toBe("function");
-        });
-
-        itShouldMatch('http://www.apache.org/',['*'], "should accept any domain for *");
-        itShouldNotMatch('http://www.apache.org/',[], "should not accept any domain for []");
-
-        itShouldMatch('http://apache.org/', ['http://*.apache.org']);
-        itShouldMatch('http://www.apache.org/', ['http://*.apache.org']);
-        itShouldMatch('http://www.apache.org/some/path', ['http://*.apache.org']);
-        itShouldMatch('http://some.domain.under.apache.org/', ['http://*.apache.org']);
-        itShouldMatch('http://user:pass@apache.org/', ['http://*.apache.org']);
-        itShouldMatch('http://user:pass@www.apache.org/', ['http://*.apache.org']);
-        itShouldMatch('http://www.apache.org/?some=params', ['http://*.apache.org']);
-        itShouldNotMatch('http://apache.com/', ['http://*.apache.org']);
-        itShouldNotMatch('http://www.evil.com/?url=www.apache.org', ['http://*.apache.org']);
-        itShouldNotMatch('http://www.evil.com/?url=http://www.apache.org', ['http://*.apache.org']);
-        itShouldNotMatch('http://www.evil.com/?url=http%3A%2F%2Fwww%2Eapache%2Eorg', ['http://*.apache.org']);
-        itShouldNotMatch('https://apache.org/', ['http://*.apache.org']);
-        itShouldNotMatch('http://www.apache.org:pass@evil.com/', ['http://*.apache.org']);
-        itShouldNotMatch('http://www.apache.org.evil.com/', ['http://*.apache.org']);
-
-        itShouldMatch('http://www.apache.org/',['http://*.apache.org','https://*.apache.org']);
-        itShouldMatch('https://www.apache.org/',['http://*.apache.org','https://*.apache.org']);
-        itShouldNotMatch('ftp://www.apache.org/',['http://*.apache.org','https://*.apache.org']);
-        itShouldNotMatch('http://www.apache.com/',['http://*.apache.org','https://*.apache.org']);
-
-        itShouldMatch('http://www.apache.org/',['http://www.apache.org']);
-        itShouldNotMatch('http://build.apache.org/',['http://www.apache.org']);
-        itShouldNotMatch('http://apache.org/',['http://www.apache.org']);
-
-        itShouldMatch('http://www.apache.org/', ['http://*/*']);
-        itShouldMatch('http://www.apache.org/foo/bar.html', ['http://*/*']);
-
-        itShouldMatch('http://www.apache.org/foo', ['http://*/foo*']);
-        itShouldMatch('http://www.apache.org/foo/bar.html', ['http://*/foo*']);
-        itShouldNotMatch('http://www.apache.org/', ['http://*/foo*']);
-
-        itShouldMatch('file:///foo', ['file:///*']);
-
-        itShouldMatch('file:///foo', ['file:///foo*']);
-        itShouldMatch('file:///foo/bar.html', ['file:///foo*']);
-        itShouldNotMatch('file:///etc/foo', ['file:///foo*']);
-        itShouldNotMatch('http://www.apache.org/foo', ['file:///foo*']);
-
-        itShouldMatch('http://www.apache.org/', ['*://www.apache.org/*']);
-        itShouldMatch('https://www.apache.org/', ['*://www.apache.org/*']);
-        itShouldMatch('ftp://www.apache.org/', ['*://www.apache.org/*']);
-        itShouldMatch('file://www.apache.org/', ['*://www.apache.org/*']);
-        itShouldMatch('content://www.apache.org/', ['*://www.apache.org/*']);
-        itShouldMatch('foo://www.apache.org/', ['*://www.apache.org/*']);
-        itShouldNotMatch('http://www.apache.com/', ['*://www.apache.org/*']);
-
-        itShouldMatch('http://www.apache.org/', ['*.apache.org']);
-        itShouldMatch('https://www.apache.org/', ['*.apache.org']);
-        itShouldNotMatch('ftp://www.apache.org/', ['*.apache.org']);
-
-        itShouldMatch('http://www.apache.org:81/', ['http://www.apache.org:81/*']);
-        itShouldMatch('http://user:pass@www.apache.org:81/foo/bar.html', ['http://www.apache.org:81/*']);
-        itShouldNotMatch('http://www.apache.org:80/', ['http://www.apache.org:81/*']);
-        itShouldNotMatch('http://www.apache.org/', ['http://www.apache.org:81/*']);
-        itShouldNotMatch('http://www.apache.org:foo/', ['http://www.apache.org:81/*']);
-        itShouldNotMatch('http://www.apache.org:81@www.apache.org/', ['http://www.apache.org:81/*']);
-        itShouldNotMatch('http://www.apache.org:81@www.evil.com/', ['http://www.apache.org:81/*']);
-
-        itShouldMatch('http://www.APAche.org/', ['*.apache.org']);
-        itShouldMatch('http://WWw.apache.org/', ['*.apache.org']);
-        itShouldMatch('http://www.apache.org/', ['*.APACHE.ORG']);
-        itShouldMatch('HTTP://www.apache.org/', ['*.apache.org']);
-        itShouldMatch('HTTP://www.apache.org/', ['http://*.apache.org']);
-        itShouldMatch('http://www.apache.org/', ['HTTP://*.apache.org']);
-
-        itShouldMatch('http://www.apache.org/foo/', ['*://*.apache.org/foo/*']);
-        itShouldMatch('http://www.apache.org/foo/bar', ['*://*.apache.org/foo/*']);
-        itShouldNotMatch('http://www.apache.org/bar/foo/', ['*://*.apache.org/foo/*']);
-        itShouldNotMatch('http://www.apache.org/Foo/', ['*://*.apache.org/foo/*']);
-        itShouldNotMatch('http://www.apache.org/Foo/bar', ['*://*.apache.org/foo/*']);
-
-    });
-
-    describe("Test function", function() {
-        function expectTestWithResult(result) {
-            return (function(url, description) {
-                description = description || ((result ? "should accept " : "should reject ") + url);
-                it(description, function() {
-                    var cb = jasmine.createSpy();
-                    runs(function() {
-                        cordova.whitelist.test(url, cb);
-                    });
-                    waitsFor(function() { return cb.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-                    runs(function() {
-                        expect(cb).toHaveBeenCalledWith(result);
-                    });
-                });
-            });
-        }
-
-        var itShouldAccept = expectTestWithResult(true);
-        var itShouldReject = expectTestWithResult(false);
-
-        it("should exist", function() {
-            expect(cordova.whitelist.test).toBeDefined();
-            expect(typeof cordova.whitelist.test).toBe("function");
-        });
-
-        itShouldAccept('http://apache.org');
-        itShouldAccept('http://apache.org/');
-        itShouldAccept('http://www.apache.org/');
-        itShouldAccept('http://www.apache.org/some/path');
-        itShouldAccept('http://some.domain.under.apache.org/');
-        itShouldAccept('http://user:pass@apache.org/');
-        itShouldAccept('http://user:pass@www.apache.org/');
-        itShouldAccept('https://www.apache.org/');
-        itShouldReject('ftp://www.apache.org/');
-        itShouldReject('http://www.apache.com/');
-        itShouldReject('http://www.apache.org:pass@evil.com/');
-        itShouldReject('http://www.apache.org.evil.com/');
-        itShouldAccept('file:///foo');
-        itShouldAccept('content:///foo');
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/battery/index.html
----------------------------------------------------------------------
diff --git a/battery/index.html b/battery/index.html
deleted file mode 100644
index 016dc87..0000000
--- a/battery/index.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Battery</h1>
-    <div id="info">
-        <b>Status:</b> <span id="battery_status"></span><br>
-        Level: <span id="level"></span><br/>
-        Plugged: <span id="isPlugged"></span><br/>
-        Low: <span id="low"></span><br/>
-        Critical: <span id="crit"></span><br/>
-    </div>
-    <h2>Action</h2>
-    <div class="btn large addBattery">Add "batterystatus" listener</div>
-    <div class="btn large removeBattery">Remove "batterystatus" listener</div>
-    <div class="btn large addLow">Add "batterylow" listener</div>
-    <div class="btn large removeLow">Remove "batterylow" listener</div>
-    <div class="btn large addCritical">Add "batterycritical" listener</div>
-    <div class="btn large removeCritical">Remove "batterycritical" listener</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      


[07/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/contacts.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/contacts.tests.js b/www/autotest/tests/contacts.tests.js
new file mode 100644
index 0000000..73a605c
--- /dev/null
+++ b/www/autotest/tests/contacts.tests.js
@@ -0,0 +1,542 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+// global to store a contact so it doesn't have to be created or retrieved multiple times
+// all of the setup/teardown test methods can reference the following variables to make sure to do the right cleanup
+var gContactObj = null,
+    gContactId = null,
+    isWindowsPhone = cordova.platformId == 'windowsphone';
+
+var removeContact = function(){
+    if (gContactObj) {
+        gContactObj.remove(function(){},function(){
+            console.log("[CONTACTS ERROR]: removeContact cleanup method failed to clean up test artifacts.");
+        });
+        gContactObj = null;
+    }
+};
+
+describe("Contacts (navigator.contacts)", function () {
+    it("contacts.spec.1 should exist", function() {
+        expect(navigator.contacts).toBeDefined();
+    });
+
+    it("contacts.spec.2 should contain a find function", function() {
+        expect(navigator.contacts.find).toBeDefined();
+        expect(typeof navigator.contacts.find).toBe('function');
+    });
+
+    describe("find method", function() {
+        it("contacts.spec.3 success callback should be called with an array", function() {
+            var win = jasmine.createSpy().andCallFake(function(result) {
+                    expect(result).toBeDefined();
+                    expect(result instanceof Array).toBe(true);
+                }),
+                fail = jasmine.createSpy(),
+                obj = new ContactFindOptions();
+
+            runs(function () {
+                obj.filter="";
+                obj.multiple=true;
+                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, obj);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+
+        it("success callback should be called with an array, even if partial ContactFindOptions specified", function () {
+            var win = jasmine.createSpy().andCallFake(function (result) {
+                expect(result).toBeDefined();
+                expect(result instanceof Array).toBe(true);
+            }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, {
+                    multiple: true
+                });
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+
+        it("contacts.spec.4 should throw an exception if success callback is empty", function() {
+            var fail = function() {};
+            var obj = new ContactFindOptions();
+            obj.filter="";
+            obj.multiple=true;
+
+            expect(function () {
+                navigator.contacts.find(["displayName", "name", "emails", "phoneNumbers"], null, fail, obj);
+            }).toThrow();
+        });
+
+        it("contacts.spec.5 error callback should be called when no fields are specified", function() {
+            var win = jasmine.createSpy(),
+                fail = jasmine.createSpy(function(result) {
+                    expect(result).toBeDefined();
+                    expect(result.code).toBe(ContactError.INVALID_ARGUMENT_ERROR);
+                }),
+                obj = new ContactFindOptions();
+
+            runs(function () {
+                obj.filter="";
+                obj.multiple=true;
+                navigator.contacts.find([], win, fail, obj);
+            });
+
+            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(win).not.toHaveBeenCalled();
+                expect(fail).toHaveBeenCalled();
+            });
+        });
+
+        describe("with newly-created contact", function () {
+
+            afterEach(removeContact);
+
+            it("contacts.spec.6 should be able to find a contact by name", function() {
+
+                // this api requires manual user confirmation on WP7/8 so skip it
+                if (isWindowsPhone) return;
+
+                var foundName = jasmine.createSpy().andCallFake(function(result) {
+                        var bFound = false;
+                        try {
+                            for (var i=0; i < result.length; i++) {
+                                if (result[i].name.familyName == "Delete") {
+                                    bFound = true;
+                                    break;
+                                }
+                            }
+                        } catch(e) {
+                            return false;
+                        }
+                        return bFound;
+                    }),
+                    fail = jasmine.createSpy(),
+                    test = jasmine.createSpy().andCallFake(function(savedContact) {
+                        console.log('in test');
+                        // update so contact will get removed
+                        gContactObj = savedContact;
+                        // ----
+                        // Find asserts
+                        // ---
+                        var findWin = jasmine.createSpy().andCallFake(function(object) {
+                                console.log('in findwin');
+                                expect(object instanceof Array).toBe(true);
+                                expect(object.length >= 1).toBe(true);
+                                expect(foundName(object)).toBe(true);
+                            }),
+                            findFail = jasmine.createSpy(),
+                            obj = new ContactFindOptions();
+
+                        obj.filter="Delete";
+                        obj.multiple=true;
+
+                        runs(function () {
+                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
+                        });
+
+                        waitsFor(function () { return foundName.wasCalled; }, "foundName not done", Tests.TEST_TIMEOUT);
+
+                        runs(function () {
+                            expect(findFail).not.toHaveBeenCalled();
+                            expect(fail).not.toHaveBeenCalled();
+                        });
+                    });
+
+                runs(function () {
+                    gContactObj = new Contact();
+                    gContactObj.name = new ContactName();
+                    gContactObj.name.familyName = "Delete";
+                    gContactObj.save(test, fail);
+                });
+
+                waitsFor(function () { return test.wasCalled; }, "test not done", Tests.TEST_TIMEOUT);
+            });
+        });
+    });
+
+    describe('create method', function() {
+
+        it("contacts.spec.7 should exist", function() {
+            expect(navigator.contacts.create).toBeDefined();
+            expect(typeof navigator.contacts.create).toBe('function');
+        });
+
+        it("contacts.spec.8 should return a Contact object", function() {
+            var bDay = new Date(1976, 7,4);
+            var obj = navigator.contacts.create({"displayName": "test name", "gender": "male", "note": "my note", "name": {"formatted": "Mr. Test Name"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay});
+
+            expect(obj).toBeDefined();
+            expect(obj.displayName).toBe('test name');
+            expect(obj.note).toBe('my note');
+            expect(obj.name.formatted).toBe('Mr. Test Name');
+            expect(obj.emails.length).toBe(2);
+            expect(obj.emails[0].value).toBe('here@there.com');
+            expect(obj.emails[1].value).toBe('there@here.com');
+            expect(obj.nickname).toBe(null);
+            expect(obj.birthday).toBe(bDay);
+        });
+    });
+
+    describe("Contact object", function () {
+        it("contacts.spec.9 should be able to create instance", function() {
+            var contact = new Contact("a", "b", new ContactName("a", "b", "c", "d", "e", "f"), "c", [], [], [], [], [], "f", "i",
+                [], [], []);
+            expect(contact).toBeDefined();
+            expect(contact.id).toBe("a");
+            expect(contact.displayName).toBe("b");
+            expect(contact.name.formatted).toBe("a");
+            expect(contact.nickname).toBe("c");
+            expect(contact.phoneNumbers).toBeDefined();
+            expect(contact.emails).toBeDefined();
+            expect(contact.addresses).toBeDefined();
+            expect(contact.ims).toBeDefined();
+            expect(contact.organizations).toBeDefined();
+            expect(contact.birthday).toBe("f");
+            expect(contact.note).toBe("i");
+            expect(contact.photos).toBeDefined();
+            expect(contact.categories).toBeDefined();
+            expect(contact.urls).toBeDefined();
+        });
+
+        it("contacts.spec.10 should be able to define a ContactName object", function() {
+            var contactName = new ContactName("Dr. First Last Jr.", "Last", "First", "Middle", "Dr.", "Jr.");
+            expect(contactName).toBeDefined();
+            expect(contactName.formatted).toBe("Dr. First Last Jr.");
+            expect(contactName.familyName).toBe("Last");
+            expect(contactName.givenName).toBe("First");
+            expect(contactName.middleName).toBe("Middle");
+            expect(contactName.honorificPrefix).toBe("Dr.");
+            expect(contactName.honorificSuffix).toBe("Jr.");
+        });
+
+        it("contacts.spec.11 should be able to define a ContactField object", function() {
+            var contactField = new ContactField("home", "8005551212", true);
+            expect(contactField).toBeDefined();
+            expect(contactField.type).toBe("home");
+            expect(contactField.value).toBe("8005551212");
+            expect(contactField.pref).toBe(true);
+        });
+
+        it("contacts.spec.12 ContactField object should coerce type and value properties to strings", function() {
+            var contactField = new ContactField(12345678, 12345678, true);
+            expect(contactField.type).toBe("12345678");
+            expect(contactField.value).toBe("12345678");
+        });
+
+        it("contacts.spec.13 should be able to define a ContactAddress object", function() {
+            var contactAddress = new ContactAddress(true, "home", "a","b","c","d","e","f");
+            expect(contactAddress).toBeDefined();
+            expect(contactAddress.pref).toBe(true);
+            expect(contactAddress.type).toBe("home");
+            expect(contactAddress.formatted).toBe("a");
+            expect(contactAddress.streetAddress).toBe("b");
+            expect(contactAddress.locality).toBe("c");
+            expect(contactAddress.region).toBe("d");
+            expect(contactAddress.postalCode).toBe("e");
+            expect(contactAddress.country).toBe("f");
+        });
+
+        it("contacts.spec.14 should be able to define a ContactOrganization object", function() {
+            var contactOrg = new ContactOrganization(true, "home", "a","b","c","d","e","f","g");
+            expect(contactOrg).toBeDefined();
+            expect(contactOrg.pref).toBe(true);
+            expect(contactOrg.type).toBe("home");
+            expect(contactOrg.name).toBe("a");
+            expect(contactOrg.department).toBe("b");
+            expect(contactOrg.title).toBe("c");
+        });
+
+        it("contacts.spec.15 should be able to define a ContactFindOptions object", function() {
+            var contactFindOptions = new ContactFindOptions("a", true, "b");
+            expect(contactFindOptions).toBeDefined();
+            expect(contactFindOptions.filter).toBe("a");
+            expect(contactFindOptions.multiple).toBe(true);
+        });
+
+        it("contacts.spec.16 should contain a clone function", function() {
+            var contact = new Contact();
+            expect(contact.clone).toBeDefined();
+            expect(typeof contact.clone).toBe('function');
+        });
+
+        it("contacts.spec.17 clone function should make deep copy of Contact Object", function() {
+            var contact = new Contact();
+            contact.id=1;
+            contact.displayName="Test Name";
+            contact.nickname="Testy";
+            contact.gender="male";
+            contact.note="note to be cloned";
+            contact.name = new ContactName("Mr. Test Name");
+
+            var clonedContact = contact.clone();
+
+            expect(contact.id).toBe(1);
+            expect(clonedContact.id).toBe(null);
+            expect(clonedContact.displayName).toBe(contact.displayName);
+            expect(clonedContact.nickname).toBe(contact.nickname);
+            expect(clonedContact.gender).toBe(contact.gender);
+            expect(clonedContact.note).toBe(contact.note);
+            expect(clonedContact.name.formatted).toBe(contact.name.formatted);
+            expect(clonedContact.connected).toBe(contact.connected);
+        });
+
+        it("contacts.spec.18 should contain a save function", function() {
+            var contact = new Contact();
+            expect(contact.save).toBeDefined();
+            expect(typeof contact.save).toBe('function');
+        });
+
+        it("contacts.spec.19 should contain a remove function", function() {
+            var contact = new Contact();
+            expect(contact.remove).toBeDefined();
+            expect(typeof contact.remove).toBe('function');
+        });
+    });
+
+    describe('save method', function () {
+        it("contacts.spec.20 should be able to save a contact", function() {
+
+            // this api requires manual user confirmation on WP7/8 so skip it
+            if (isWindowsPhone) return;
+
+            var bDay = new Date(1976, 6,4);
+            gContactObj = navigator.contacts.create({"gender": "male", "note": "my note", "name": {"familyName": "Delete", "givenName": "Test"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay});
+
+            var saveSuccess = jasmine.createSpy().andCallFake(function(obj) {
+                    expect(obj).toBeDefined();
+                    if (cordova.platformId !== 'blackberry10') {
+                        expect(obj.note).toBe('my note');
+                    }
+                    expect(obj.name.familyName).toBe('Delete');
+                    expect(obj.name.givenName).toBe('Test');
+                    expect(obj.emails.length).toBe(2);
+                    expect(obj.emails[0].value).toBe('here@there.com');
+                    expect(obj.emails[1].value).toBe('there@here.com');
+                    expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
+                    expect(obj.addresses).toBe(null);
+                    // must store returned object in order to have id for update test below
+                    gContactObj = obj;
+                }),
+                saveFail = jasmine.createSpy();
+
+            runs(function () {
+                gContactObj.save(saveSuccess, saveFail);
+            });
+
+            waitsFor(function () { return saveSuccess.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(saveFail).not.toHaveBeenCalled();
+            });
+         });
+        // HACK: there is a reliance between the previous and next test. This is bad form.
+        it("contacts.spec.21 update a contact", function() {
+
+            // this api requires manual user confirmation on WP7/8 so skip it
+            if (isWindowsPhone) return;
+
+            expect(gContactObj).toBeDefined();
+
+            var bDay = new Date(1975, 5,4);
+            var noteText = "an UPDATED note";
+
+            var win = jasmine.createSpy().andCallFake(function(obj) {
+                    expect(obj).toBeDefined();
+                    expect(obj.id).toBe(gContactObj.id);
+                    if (cordova.platformId !== 'blackberry10') {
+                        expect(obj.note).toBe(noteText);
+                    }
+                    expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
+                    expect(obj.emails.length).toBe(1);
+                    expect(obj.emails[0].value).toBe('here@there.com');
+                    removeContact();         // Clean up contact object
+                }), fail = jasmine.createSpy().andCallFake(removeContact);
+
+            runs(function () {
+                // remove an email
+                gContactObj.emails[1].value = "";
+                // change birthday
+                gContactObj.birthday = bDay;
+                // update note
+                gContactObj.note = noteText;
+                gContactObj.save(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe('Contact.remove method', function () {
+        afterEach(removeContact);
+
+        it("contacts.spec.22 calling remove on a contact has an id of null should return ContactError.UNKNOWN_ERROR", function() {
+            var win = jasmine.createSpy();
+            var fail = jasmine.createSpy().andCallFake(function(result) {
+                expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
+            });
+
+            runs(function () {
+                var rmContact = new Contact();
+                rmContact.remove(win, fail);
+            });
+
+            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(win).not.toHaveBeenCalled();
+            });
+        });
+
+        it("contacts.spec.23 calling remove on a contact that does not exist should return ContactError.UNKNOWN_ERROR", function() {
+            var win = jasmine.createSpy();
+            var fail = jasmine.createSpy().andCallFake(function(result) {
+                expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
+            });
+
+            runs(function () {
+                var rmContact = new Contact();
+                // this is a bit risky as some devices may have contact ids that large
+                var contact = new Contact("this string is supposed to be a unique identifier that will never show up on a device");
+                contact.remove(win, fail);
+            });
+
+            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(win).not.toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe("Round trip Contact tests (creating + save + delete + find).", function () {
+        it("contacts.spec.24 Creating, saving, finding a contact should work, removing it should work, after which we should not be able to find it, and we should not be able to delete it again.", function() {
+
+            // this api requires manual user confirmation on WP7/8 so skip it
+            if (isWindowsPhone) return;
+
+            var done = false;
+            runs(function () {
+                gContactObj = new Contact();
+                gContactObj.name = new ContactName();
+                gContactObj.name.familyName = "DeleteMe";
+                gContactObj.save(function(c_obj) {
+                    var findWin = function(cs) {
+                        expect(cs.length).toBe(1);
+                        // update to have proper saved id
+                        gContactObj = cs[0];
+                        gContactObj.remove(function() {
+                            var findWinAgain = function(seas) {
+                                expect(seas.length).toBe(0);
+                                gContactObj.remove(function() {
+                                    throw("success callback called after non-existent Contact object called remove(). Test failed.");
+                                }, function(e) {
+                                    expect(e.code).toBe(ContactError.UNKNOWN_ERROR);
+                                    done = true;
+                                });
+                            };
+                            var findFailAgain = function(e) {
+                                throw("find error callback invoked after delete, test failed.");
+                            };
+                            var obj = new ContactFindOptions();
+                            obj.filter="DeleteMe";
+                            obj.multiple=true;
+                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWinAgain, findFailAgain, obj);
+                        }, function(e) {
+                            throw("Newly created contact's remove function invoked error callback. Test failed.");
+                        });
+                    };
+                    var findFail = function(e) {
+                        throw("Failure callback invoked in navigator.contacts.find call, test failed.");
+                    };
+                    var obj = new ContactFindOptions();
+                    obj.filter="DeleteMe";
+                    obj.multiple=true;
+                    navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
+                }, function(e) {
+                    throw("Contact creation failed, error callback was invoked.");
+                });
+            });
+
+            waitsFor(function () { return done; }, Tests.TEST_TIMEOUT);
+        });
+    });
+
+    describe('ContactError interface', function () {
+        it("contacts.spec.25 ContactError constants should be defined", function() {
+            expect(ContactError.UNKNOWN_ERROR).toBe(0);
+            expect(ContactError.INVALID_ARGUMENT_ERROR).toBe(1);
+            expect(ContactError.TIMEOUT_ERROR).toBe(2);
+            expect(ContactError.PENDING_OPERATION_ERROR).toBe(3);
+            expect(ContactError.IO_ERROR).toBe(4);
+            expect(ContactError.NOT_SUPPORTED_ERROR).toBe(5);
+            expect(ContactError.PERMISSION_DENIED_ERROR).toBe(20);
+        });
+    });
+
+    describe("Contacts autotests cleanup", function () {
+        it("contacts.spec.26 Cleanup any DeleteMe contacts from Contacts tests.", function() {
+            var done = false;
+            var obj = new ContactFindOptions();
+            obj.filter="DeleteMe";
+            obj.multiple=true;
+            runs(function () {
+                var findSuccess = function (cs) {
+                    var contactObj = new Contact();
+                    if (cs.length>0){
+                        contactObj = cs[0];
+                        contactObj.remove(function(){
+                            console.log("[CONTACTS CLEANUP] DeleteMe contact successfully removed");
+                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findSuccess, findFail, obj);
+                        },function(){
+                            console.log("[CONTACTS CLEANUP ERROR]: failed to remove DeleteMe contact");
+                        });
+                    } else {
+                        done = true;
+                    }
+                };
+                var findFail = function(e) {
+                    throw("Failure callback invoked in navigator.contacts.find call, test failed.");
+                };
+                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findSuccess, findFail, obj);
+            });
+            waitsFor(function () { return done; }, Tests.TEST_TIMEOUT);
+        });
+    });
+
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/datauri.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/datauri.tests.js b/www/autotest/tests/datauri.tests.js
new file mode 100644
index 0000000..08ebbbc
--- /dev/null
+++ b/www/autotest/tests/datauri.tests.js
@@ -0,0 +1,60 @@
+/*
+ * 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 isWindowsPhone = cordova.platformId == 'windowsphone';
+
+describe('data uris', function () {
+    it("datauri.spec.1 should work with iframes", function() {
+        // IE on WP7/8 considers 'data:' in frame.src string as protocol type
+        // so asks user to look for appropriating application in the market;
+        // temporary skipped since requires user interaction
+        if (isWindowsPhone) return;
+        var gotFoo = false,
+            frame = document.createElement('iframe');
+        function onMessage(msg) {
+            gotFoo = gotFoo || msg.data == 'foo';
+        };
+
+        this.after(function() {
+            document.body.removeChild(frame);
+            window.removeEventListener('message', onMessage, false);
+        });
+
+        window.addEventListener('message', onMessage, false);
+        frame.src = 'data:text/html;charset=utf-8,%3Chtml%3E%3Cscript%3Eparent.postMessage%28%27foo%27%2C%27%2A%27%29%3C%2Fscript%3E%3C%2Fhtml%3E'
+        document.body.appendChild(frame);
+        waitsFor(function() {
+            return gotFoo;
+        }, 'iframe did not load.', 1000);
+        runs(function() {
+            expect(gotFoo).toBe(true);
+        });
+    });
+    it("datauri.spec.2 should work with images", function() {
+        var img = new Image();
+        img.onload = jasmine.createSpy('onLoad');
+        img.onerror = jasmine.createSpy('onError');
+        img.src = 'data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'
+        waitsFor(function() {
+            return img.onload.wasCalled || img.onerror.wasCalled;
+        }, 'image did not load or error', 1000);
+        runs(function() {
+            expect(img.onload).toHaveBeenCalled();
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/device.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/device.tests.js b/www/autotest/tests/device.tests.js
new file mode 100644
index 0000000..0bcd0d9
--- /dev/null
+++ b/www/autotest/tests/device.tests.js
@@ -0,0 +1,64 @@
+/*
+ *
+ * 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('Device Information (window.device)', function () {
+	it("should exist", function() {
+        expect(window.device).toBeDefined();
+	});
+
+	it("should contain a platform specification that is a string", function() {
+        expect(window.device.platform).toBeDefined();
+		expect((new String(window.device.platform)).length > 0).toBe(true);
+	});
+
+	it("should contain a version specification that is a string", function() {
+        expect(window.device.version).toBeDefined();
+		expect((new String(window.device.version)).length > 0).toBe(true);
+	});
+
+	it("should contain a UUID specification that is a string or a number", function() {
+        expect(window.device.uuid).toBeDefined();
+		if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') {
+		    expect((new String(window.device.uuid)).length > 0).toBe(true);
+		} else {
+			expect(window.device.uuid > 0).toBe(true);
+		}
+	});
+
+	it("should contain a cordova specification that is a string", function() {
+        expect(window.device.cordova).toBeDefined();
+		expect((new String(window.device.cordova)).length > 0).toBe(true);
+	});
+
+    it("should depend on the precense of cordova.version string", function() {
+            expect(window.cordova.version).toBeDefined();
+            expect((new String(window.cordova.version)).length > 0).toBe(true);
+    });
+
+    it("should contain device.cordova equal to cordova.version", function() {
+             expect(window.device.cordova).toBe(window.cordova.version);
+    });
+
+	it("should contain a model specification that is a string", function() {
+        expect(window.device.model).toBeDefined();
+		expect((new String(window.device.model)).length > 0).toBe(true);
+	});
+});


[03/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/battery/index.html
----------------------------------------------------------------------
diff --git a/www/battery/index.html b/www/battery/index.html
new file mode 100644
index 0000000..016dc87
--- /dev/null
+++ b/www/battery/index.html
@@ -0,0 +1,53 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Battery</h1>
+    <div id="info">
+        <b>Status:</b> <span id="battery_status"></span><br>
+        Level: <span id="level"></span><br/>
+        Plugged: <span id="isPlugged"></span><br/>
+        Low: <span id="low"></span><br/>
+        Critical: <span id="crit"></span><br/>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large addBattery">Add "batterystatus" listener</div>
+    <div class="btn large removeBattery">Remove "batterystatus" listener</div>
+    <div class="btn large addLow">Add "batterylow" listener</div>
+    <div class="btn large removeLow">Remove "batterylow" listener</div>
+    <div class="btn large addCritical">Add "batterycritical" listener</div>
+    <div class="btn large removeCritical">Remove "batterycritical" listener</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/battery/index.js
----------------------------------------------------------------------
diff --git a/www/battery/index.js b/www/battery/index.js
new file mode 100644
index 0000000..1a0d488
--- /dev/null
+++ b/www/battery/index.js
@@ -0,0 +1,72 @@
+var deviceReady = false;
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+        if (!deviceReady) {
+            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+        }
+    },1000);
+}
+
+/* Battery */
+function updateInfo(info) {
+    document.getElementById('level').innerText = info.level;
+    document.getElementById('isPlugged').innerText = info.isPlugged;
+    if (info.level > 5) {
+        document.getElementById('crit').innerText = "false";
+    }
+    if (info.level > 20) {
+        document.getElementById('low').innerText = "false";
+    }
+}
+
+function batteryLow(info) {
+    document.getElementById('low').innerText = "true";
+}
+
+function batteryCritical(info) {
+    document.getElementById('crit').innerText = "true";
+}
+
+function addBattery() {
+    window.addEventListener("batterystatus", updateInfo, false);
+}
+
+function removeBattery() {
+    window.removeEventListener("batterystatus", updateInfo, false);
+}
+
+function addLow() {
+    window.addEventListener("batterylow", batteryLow, false);
+}
+
+function removeLow() {
+    window.removeEventListener("batterylow", batteryLow, false);
+}
+
+function addCritical() {
+    window.addEventListener("batterycritical", batteryCritical, false);
+}
+
+function removeCritical() {
+    window.removeEventListener("batterycritical", batteryCritical, false);
+}
+
+window.onload = function() {
+  addListenerToClass('addBattery', addBattery);
+  addListenerToClass('removeBattery', removeBattery);
+  addListenerToClass('addLow', addLow);
+  addListenerToClass('removeLow', removeLow);
+  addListenerToClass('addCritical', addCritical);
+  addListenerToClass('removeCritical', removeCritical);
+  
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/beep.wav
----------------------------------------------------------------------
diff --git a/www/beep.wav b/www/beep.wav
new file mode 100644
index 0000000..05f5997
Binary files /dev/null and b/www/beep.wav differ

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/benchmarks/arraybuffer.html
----------------------------------------------------------------------
diff --git a/www/benchmarks/arraybuffer.html b/www/benchmarks/arraybuffer.html
new file mode 100644
index 0000000..5686f75
--- /dev/null
+++ b/www/benchmarks/arraybuffer.html
@@ -0,0 +1,132 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+
+<script>
+    var exec = cordova.require('cordova/exec'),
+        deviceReady = false;
+
+    function appLog(message) {
+        if (window.console) {
+            console.log(message);
+        }
+        if (typeof message != 'string') {
+            message = JSON.stringify(message);
+        }
+        document.getElementById('app-logs').innerText += message + '\n';
+    }
+
+    function benchExec() {
+        var echo = cordova.echo,
+            startTime = +new Date,
+            callCount = 0,
+            durationMs = parseInt(document.getElementById('test-duration').value, 10) * 1000,
+            payloadSize = (+document.getElementById('payload-size').value),
+            payload = new ArrayBuffer(payloadSize);
+
+        var payloadView = new Uint8Array(payload);
+        for (var i=0; i<payloadView.length; i++) {
+            payloadView[i] = i;
+        }
+
+        function compareArrayBuffers(arr1, arr2) {
+            arr1 = new Uint8Array(arr1);
+            arr2 = new Uint8Array(arr2);
+            if (arr1.length != arr2.length)
+                return false;
+            for (var i = 0; i < arr1.length; ++i) {
+                if (arr1[i] != arr2[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        function win(result) {
+            callCount++;
+            if (!compareArrayBuffers(result, payload)) {
+                appLog('Wrong echo data!');
+                return;
+            }
+            var elapsedMs = new Date - startTime;
+            if (elapsedMs >= durationMs) {
+                var callsPerSecond = callCount * 1000 / elapsedMs;
+                appLog('Calls per second: ' + callsPerSecond);
+                return;
+            }
+            echoMessage();
+        }
+        function fail() {
+            appLog('Call failed!');
+        }
+        function echoMessage() {
+            setTimeout(function() {
+                echo(win, fail, payload);
+            });
+        }
+
+        appLog('Started exec benchmark with payload length: ' + payloadView.length);
+        echoMessage();
+        setTimeout(function() {
+            if (!callCount) {
+                alert('Echo plugin did not respond');
+            }
+        }, 500);
+    }
+
+    document.addEventListener("deviceready", function() {
+        deviceReady = true;
+        appLog("Device = " + device.platform + " " + device.version);
+    }, false);
+
+    window.onload = function() {
+        window.setTimeout(function() {
+            if (!deviceReady) {
+                alert("Error: Cordova did not initialize.  Demo will not run correctly.");
+            }
+        }, 1000);
+    };
+
+</script>
+
+  </head>
+  <body id="stage" class="theme">
+    <h1>ArrayBuffer Benchmark</h1>
+    <fieldset>
+        <legend>Settings</legend>
+        <label>Test Duration: <select id="test-duration"><option>1 Second</option><option>5 Seconds</option></select><br></label>
+        <label>Payload size (in bytes) <input id="payload-size" value="1024" style="width:100px"></label><br>
+        <button onclick="benchExec()">Benchmark exec</button><br>
+    </fieldset>
+    <h2>&nbsp</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a><br>
+    <div>Results:</div>
+    <pre id="app-logs" style="white-space:pre-wrap;line-height:initial"></pre>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/benchmarks/autobench.html
----------------------------------------------------------------------
diff --git a/www/benchmarks/autobench.html b/www/benchmarks/autobench.html
new file mode 100644
index 0000000..1a909fb
--- /dev/null
+++ b/www/benchmarks/autobench.html
@@ -0,0 +1,194 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="uubench.js"></script>
+<script>
+    var exec = cordova.require('cordova/exec');
+    var temp, pers, LICENSE_CONTENTS;
+    function $(id) { return document.getElementById(id); }
+
+    function copy_license(filesystem, callback) {
+        filesystem.root.getFile("LICENSE", {create: true, exclusive: false}, function(entry) {
+            entry.createWriter(function(writer) {
+                writer.onwriteend = function(evt) {
+                    callback();
+                };
+                writer.write(LICENSE_CONTENTS);
+            }, function(err) {
+                alert('Error creating LICENSE FileWriter');
+            });
+        }, function(err) {
+            alert('Error copying LICENSE to a file system');
+        });
+    }
+
+    var suite = new uubench.Suite({
+        start:function() {
+            $('loading').innerHTML = "BENCHMARKING IN PROGRESS...";
+        },
+        result: function(name, stats) {
+            var secs = stats.elapsed/1000;
+            var itspersec = stats.iterations / secs;
+            $('table-results').innerHTML += '<tr><td>' + name + '</td><td>' + itspersec + ' per second.</td></tr>';
+            console.log(name + ' bench complete.');
+            results[name] = stats;
+        },
+        min: 2000, // each benchmark should run for at least 2000ms
+        done:function() { 
+            $('loading').innerHTML = "Benchmarks complete.";
+            $('backBtn').style.display="block";
+        }
+    });
+    var results = {};
+
+    document.addEventListener("deviceready", function() {
+        deviceReady = true;
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", "../LICENSE", true);
+        xhr.onreadystatechange = function() {
+            if (xhr.readyState == 4) {
+                if (xhr.responseText.length > 0) {
+                    LICENSE_CONTENTS = xhr.responseText;
+                } else {
+                    alert('Some prereq XHR stuff to get license content failed mang.');
+                }
+                window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(p_fs) {
+                    pers = p_fs;
+                    copy_license(pers, function() {
+                        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, function(t_fs) {
+                            temp = t_fs;
+                            copy_license(temp, function() {
+                                setTimeout(bench, 250);
+                            });
+                        }, function(t_e) {
+                            alert('Failed to get TEMPORARY File System');
+                        });
+                    });
+                }, function(p_e) {
+                    alert('Failed to get PERSISTENT File System');
+                });
+            }
+        };
+        xhr.send(null);
+    });
+
+    window.onload = function() {
+        window.setTimeout(function() {
+            if (!deviceReady) {
+                alert("Error: Cordova did not initialize.  Demo will not run correctly.");
+            }
+        }, 1000);
+    };
+function bench() {
+    suite.bench("Echo exec callbacks", function(next) {
+        exec(function() {
+            // win
+            next();
+        }, function() {
+            // fail
+            next();
+        }, "Echo", "echo", ["test"]);
+    });
+    suite.bench("Echo exec invocations", function(next) {
+        exec(function() {
+            // win
+        }, function() {
+            // fail
+        }, "Echo", "echo", ["test"]);
+        next();
+    });
+    suite.bench("XHR to within-package 11kb asset.", function(next) {
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", "../LICENSE", true);
+        xhr.onreadystatechange = function() {
+            if (xhr.readyState == 4) {
+                // The result status is being compared to 0 for success instead of 200. This is because the file and ftp schemes do not use HTTP result codes.
+                if (xhr.status == 0 && xhr.responseText.length > 0) {
+                    next();
+                } else {
+                    alert('There was a problem during XHR file read!');
+                }
+            }
+        };
+        xhr.send(null);
+    });
+    if (temp) {
+        suite.bench("Get contents of 11kb asset located on TEMPORARY File System using FileReader's readAsText method.", function(next) {
+            temp.root.getFile("LICENSE", null, function(entry) {
+                entry.file(function(file) {
+                    var reader = new FileReader();
+                    reader.onloadend = function(evt) {
+                        next();
+                    };
+                    reader.readAsText(file);
+                }, function(err) {
+                    alert('Error getting File object from LICENSE file in TEMP FS.');
+                });
+            }, function(err) {
+                alert('Error getting LICENSE file from root of TEMP FS.');
+            });
+        });
+    }
+    if (pers) {
+        suite.bench("Get contents of 11kb asset located on PERSISTENT File System using FileReader's readAsText method.", function(next) {
+            pers.root.getFile("LICENSE", null, function(entry) {
+                entry.file(function(file) {
+                    var reader = new FileReader();
+                    reader.onloadend = function(evt) {
+                        next();
+                    };
+                    reader.readAsText(file);
+                }, function(err) {
+                    alert('Error getting File object from LICENSE file in PERSISTENT FS.');
+                });
+            }, function(err) {
+                alert('Error getting LICENSE file from root of PERSISTENT FS.');
+            });
+        });
+    }
+    suite.run();
+}
+</script>
+
+  </head>
+  <body id="stage" class="theme">
+    <h1>Auto-Benchmarks</h1>
+    <h2 id="loading"></h2>
+    <table>
+        <thead style="font-weight:bold;text-align:center;">
+            <tr>
+                <td>Name</td>
+                <td>Results</td>
+            </tr>
+        </thead>
+        <tbody id="table-results">
+        </tbody>
+    </table>
+    <h2>&nbsp</h2><a href="javascript:" class="backBtn" style="display:none" id='backBtn' onclick="backHome();">Back</a><br>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/benchmarks/exec.html
----------------------------------------------------------------------
diff --git a/www/benchmarks/exec.html b/www/benchmarks/exec.html
new file mode 100644
index 0000000..cd51ca4
--- /dev/null
+++ b/www/benchmarks/exec.html
@@ -0,0 +1,239 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script src="../cordova-incl.js"></script>
+    <script src="setImmediate.js"></script>
+<script>
+    var exec = cordova.require('cordova/exec'),
+        appLogElem = null,
+        deviceReady = false,
+        inProgress = false;
+
+    function appLog(message) {
+        if (!appLogElem) {
+            appLogElem = document.getElementById('app-logs');
+        }
+        appLogElem.innerText += message + '\n';
+        if (window.console) {
+            console.log(message);
+        }
+    }
+
+    function clearLogs() {
+        appLogElem.innerHTML = '';
+    }
+
+    function updateUi(val) {
+        inProgress = val;
+        var goBtn = document.getElementById('go-btn');
+        goBtn.textContent = inProgress ? 'Stop' : 'Start';
+        cordova.echo.stopBulkEcho();
+    }
+
+    function createPayload(size, binary) {
+        if (!binary) {
+            return new Array(size * 10 + 1).join('012\n\n 6789');
+        }
+        size = size * 100;
+        var bufView = new Uint8Array(size);
+        for (var i = 0; i < size; ++i) {
+          bufView[i] = i % 20;
+        }
+        return bufView.buffer;
+    }
+
+    function benchExec() {
+        updateUi(!inProgress);
+        if (!inProgress) {
+            return;
+        }
+
+        var echo = cordova.echo,
+            startTime = +new Date,
+            callCount = 0,
+            elapsedMs,
+            lastReportMs = 0,
+            durationMs = parseInt(document.getElementById('test-duration').value, 10) * 1000,
+            asyncEcho = document.getElementById('async-echo').checked,
+            useSetTimeout = document.getElementById('use-setTimeout').checked,
+            bulkEcho = document.getElementById('bulk-echo').checked,
+            jsToNativeMode = document.getElementById('js-native-modes').value,
+            nativeToJsMode = document.getElementById('native-js-modes').value,
+            payloadSize = +document.getElementById('payload-size').value,
+            binaryPayload = document.getElementById('binary-payload').checked,
+            binaryAsyncEncode = document.getElementById('binary-async-encode').checked,
+            binaryAsyncDecode = document.getElementById('binary-async-decode').checked,
+            soFarEl = document.getElementById('so-far'),
+            payload = createPayload(payloadSize, binaryPayload);
+
+        cordova.ASYNC_AB_ENCODE = binaryAsyncEncode;
+        cordova.ASYNC_AB_DECODE = binaryAsyncDecode;
+
+        function reportProgress() {
+            var callsPerSecond = String(callCount * 1000 / elapsedMs).slice(0, 6);
+            soFarEl.textContent = callsPerSecond + ' ops';
+            appLog('Calls per second: ' + callsPerSecond);
+        }
+        function win(result) {
+            if (!inProgress) {
+                console.log('got an excess echo');
+                return;
+            }
+            callCount++;
+            if (result.length !== payload.length || result.byteLength !== payload.byteLength) {
+                appLog('Wrong echo data!');
+                updateUi(false);
+            }
+            elapsedMs = new Date - startTime;
+            if (inProgress && elapsedMs < durationMs) {
+                if (elapsedMs - lastReportMs > 1000) {
+                    reportProgress();
+                    lastReportMs = elapsedMs;
+                }
+                if (bulkEcho) {
+                    // automatically keeps coming.
+                } else if (useSetTimeout) {
+                    setImmediate(echoMessage);
+                } else {
+                    echoMessage();
+                }
+            } else {
+                reportProgress();
+                updateUi(false);
+            }
+        }
+        function fail() {
+            appLog('Call failed!');
+        }
+        function echoMessage() {
+            echo(win, fail, payload, asyncEcho);
+        }
+
+        var logMsg = 'Started exec benchmark with setImmediate: ' + useSetTimeout + ' asyncEcho: ' + asyncEcho + ' payload length: ' + payloadSize;
+        if (jsToNativeMode) {
+            exec.setJsToNativeBridgeMode(+jsToNativeMode);
+            logMsg += ' jsToNativeMode: ' + jsToNativeMode;
+        }
+        if (nativeToJsMode) {
+            exec.setNativeToJsBridgeMode(+nativeToJsMode);
+            logMsg += ' nativeToJsMode: ' + nativeToJsMode;
+        }
+        appLog(logMsg);
+        if (bulkEcho) {
+          echo.bulkEcho(payload, 50, win);
+        } else {
+          echoMessage();
+        }
+        setTimeout(function() {
+            if (!callCount) {
+                alert('Echo plugin did not respond');
+            }
+        }, 500);
+    }
+
+    function configureDragMe() {
+        var dragMeEl = document.getElementById('drag-me');
+        dragMeEl.ontouchmove = function(e) {
+            e.preventDefault();
+            var touch = e.touches[0];
+            dragMeEl.style.left = touch.pageX - 50 + 'px';
+            dragMeEl.style.top = touch.pageY - 50 + 'px';
+        }
+    }
+    function configure() {
+        function configureModes(elemId, modes) {
+            var selectElem = document.getElementById(elemId);
+            for (var modeName in modes) {
+                var optionElem = document.createElement('option');
+                optionElem.value = modes[modeName];
+                optionElem.innerText = modeName;
+                selectElem.appendChild(optionElem);
+            }
+            selectElem.parentNode.style.display = 'block';
+        }
+        if (exec.jsToNativeModes) {
+            configureModes('js-native-modes', exec.jsToNativeModes);
+        }
+        if (exec.nativeToJsModes) {
+            configureModes('native-js-modes', exec.nativeToJsModes);
+        }
+        configureDragMe();
+    }
+
+
+    document.addEventListener("deviceready", function() {
+        deviceReady = true;
+        appLog("Device="+device.platform+" "+device.version);
+        configure();
+    }, false);
+
+    window.onload = function() {
+        window.setTimeout(function() {
+            if (!deviceReady) {
+                alert("Error: Cordova did not initialize.  Demo will not run correctly.");
+            }
+        }, 1000);
+    };
+
+</script>
+
+  </head>
+  <body id="stage" class="theme">
+    <h1>exec() Benchmark</h1>
+    Before running on Android, set the following constants in NativeToJsMessagingBridge:
+    <ul>
+      <li>ENABLE_LOCATION_CHANGE_EXEC_MODE = true
+      <li>DISABLE_EXEC_CHAINING = true
+    </ul>
+    As of iOS 7.0.2, Andrew found that the iframe bridge is still the fastest on iOS.
+    <fieldset>
+        <legend>Settings</legend>
+        <label>Test Duration: <select id="test-duration"><option>1 Second</option><option>3 Seconds</option><option>10 seconds</option></select><br></label>
+        <label style="display:none">JS-&gt;Native Bridge Mode: <select id="js-native-modes"></select><br></label>
+        <label style="display:none">Native-&gt;JS Bridge Mode: <select id="native-js-modes"></select><br></label>
+        <label><input type="checkbox" id="use-setTimeout"> Force async JS-&gt;Native (avoids evalAndFetch optimization on iOS)</label><br>
+        <label><input type="checkbox" id="async-echo"> Force async Native-&gt;JS</label><br>
+        <label><input type="checkbox" id="bulk-echo"> Bulk Echo Mode (test only native-&gt;JS)</label><br>
+        <label><input type="checkbox" id="binary-payload"> Binary Payload</label><br>
+        These two require async_base64_android branch of cordova-js<br>
+        <label><input type="checkbox" id="binary-async-encode"> Use FileReader to encode binary</label><br>
+        <label><input type="checkbox" id="binary-async-decode"> Use XHR to decode binary</label><br>
+        <label>Payload size (in 100s of bytes) <input id="payload-size" value="5" style="width:100px"></label><br>
+        <button id="go-btn" onclick="benchExec()">Start</button><br>
+    </fieldset>
+    <div>some text.<br>
+        <div style="position:absolute;height:100px;background:red;width:100px;left:250px;top:50px;z-index:5" id="drag-me">Drag Me<div id="so-far"></div></div>
+        <input value="dummy input"> text box to see if focus is lost by bridge or if there is typing lag.
+    </div>
+    <h2>&nbsp</h2><a href="javascript:" class="backBtn" onclick="backHome();">Back</a><br>
+    <div>Results: <a href="javascript:clearLogs();">Clear</a></div>
+    <pre id="app-logs" style="white-space:pre-wrap;line-height:initial; margin-bottom:500px"></pre>
+    You've reached the bottom.
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/benchmarks/index.html
----------------------------------------------------------------------
diff --git a/www/benchmarks/index.html b/www/benchmarks/index.html
new file mode 100644
index 0000000..a4d7419
--- /dev/null
+++ b/www/benchmarks/index.html
@@ -0,0 +1,39 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script src="../cordova-incl.js"></script>
+  </head>
+  <body id="stage" class="theme">
+    <h1>Benchmarks</h1>
+    <a href="autobench.html" class="btn large">AutoBench</a>
+    <a href="arraybuffer.html" class="btn large">ArrayBuffer</a>
+    <a href="exec.html" class="btn large">Exec Bridge</a>
+    <h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/benchmarks/setImmediate.js
----------------------------------------------------------------------
diff --git a/www/benchmarks/setImmediate.js b/www/benchmarks/setImmediate.js
new file mode 100644
index 0000000..a36b814
--- /dev/null
+++ b/www/benchmarks/setImmediate.js
@@ -0,0 +1,239 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+(function (global, undefined) {
+    "use strict";
+
+    var tasks = (function () {
+        function Task(handler, args) {
+            this.handler = handler;
+            this.args = args;
+        }
+        Task.prototype.run = function () {
+            // See steps in section 5 of the spec.
+            if (typeof this.handler === "function") {
+                // Choice of `thisArg` is not in the setImmediate spec; `undefined` is in the setTimeout spec though:
+                // http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html
+                this.handler.apply(undefined, this.args);
+            } else {
+                var scriptSource = "" + this.handler;
+                /*jshint evil: true */
+                eval(scriptSource);
+            }
+        };
+
+        var nextHandle = 1; // Spec says greater than zero
+        var tasksByHandle = {};
+        var currentlyRunningATask = false;
+
+        return {
+            addFromSetImmediateArguments: function (args) {
+                var handler = args[0];
+                var argsToHandle = Array.prototype.slice.call(args, 1);
+                var task = new Task(handler, argsToHandle);
+
+                var thisHandle = nextHandle++;
+                tasksByHandle[thisHandle] = task;
+                return thisHandle;
+            },
+            runIfPresent: function (handle) {
+                // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
+                // So if we're currently running a task, we'll need to delay this invocation.
+                if (!currentlyRunningATask) {
+                    var task = tasksByHandle[handle];
+                    if (task) {
+                        currentlyRunningATask = true;
+                        try {
+                            task.run();
+                        } finally {
+                            delete tasksByHandle[handle];
+                            currentlyRunningATask = false;
+                        }
+                    }
+                } else {
+                    // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
+                    // "too much recursion" error.
+                    global.setTimeout(function () {
+                        tasks.runIfPresent(handle);
+                    }, 0);
+                }
+            },
+            remove: function (handle) {
+                delete tasksByHandle[handle];
+            }
+        };
+    }());
+
+    function canUseNextTick() {
+        // Don't get fooled by e.g. browserify environments.
+        return typeof process === "object" &&
+               Object.prototype.toString.call(process) === "[object process]";
+    }
+
+    function canUseMessageChannel() {
+        return !!global.MessageChannel;
+    }
+
+    function canUsePostMessage() {
+        // The test against `importScripts` prevents this implementation from being installed inside a web worker,
+        // where `global.postMessage` means something completely different and can't be used for this purpose.
+
+        if (!global.postMessage || global.importScripts) {
+            return false;
+        }
+
+        var postMessageIsAsynchronous = true;
+        var oldOnMessage = global.onmessage;
+        global.onmessage = function () {
+            postMessageIsAsynchronous = false;
+        };
+        global.postMessage("", "*");
+        global.onmessage = oldOnMessage;
+
+        return postMessageIsAsynchronous;
+    }
+
+    function canUseReadyStateChange() {
+        return "document" in global && "onreadystatechange" in global.document.createElement("script");
+    }
+
+    function installNextTickImplementation(attachTo) {
+        attachTo.setImmediate = function () {
+            var handle = tasks.addFromSetImmediateArguments(arguments);
+
+            process.nextTick(function () {
+                tasks.runIfPresent(handle);
+            });
+
+            return handle;
+        };
+    }
+
+    function installMessageChannelImplementation(attachTo) {
+        var channel = new global.MessageChannel();
+        channel.port1.onmessage = function (event) {
+            var handle = event.data;
+            tasks.runIfPresent(handle);
+        };
+        attachTo.setImmediate = function () {
+            var handle = tasks.addFromSetImmediateArguments(arguments);
+
+            channel.port2.postMessage(handle);
+
+            return handle;
+        };
+    }
+
+    function installPostMessageImplementation(attachTo) {
+        // Installs an event handler on `global` for the `message` event: see
+        // * https://developer.mozilla.org/en/DOM/window.postMessage
+        // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
+
+        var MESSAGE_PREFIX = "com.bn.NobleJS.setImmediate" + Math.random();
+
+        function isStringAndStartsWith(string, putativeStart) {
+            return typeof string === "string" && string.substring(0, putativeStart.length) === putativeStart;
+        }
+
+        function onGlobalMessage(event) {
+            // This will catch all incoming messages (even from other windows!), so we need to try reasonably hard to
+            // avoid letting anyone else trick us into firing off. We test the origin is still this window, and that a
+            // (randomly generated) unpredictable identifying prefix is present.
+            if (event.source === global && isStringAndStartsWith(event.data, MESSAGE_PREFIX)) {
+                var handle = event.data.substring(MESSAGE_PREFIX.length);
+                tasks.runIfPresent(handle);
+            }
+        }
+        if (global.addEventListener) {
+            global.addEventListener("message", onGlobalMessage, false);
+        } else {
+            global.attachEvent("onmessage", onGlobalMessage);
+        }
+
+        attachTo.setImmediate = function () {
+            var handle = tasks.addFromSetImmediateArguments(arguments);
+
+            // Make `global` post a message to itself with the handle and identifying prefix, thus asynchronously
+            // invoking our onGlobalMessage listener above.
+            global.postMessage(MESSAGE_PREFIX + handle, "*");
+
+            return handle;
+        };
+    }
+
+    function installReadyStateChangeImplementation(attachTo) {
+        attachTo.setImmediate = function () {
+            var handle = tasks.addFromSetImmediateArguments(arguments);
+
+            // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+            // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+            var scriptEl = global.document.createElement("script");
+            scriptEl.onreadystatechange = function () {
+                tasks.runIfPresent(handle);
+
+                scriptEl.onreadystatechange = null;
+                scriptEl.parentNode.removeChild(scriptEl);
+                scriptEl = null;
+            };
+            global.document.documentElement.appendChild(scriptEl);
+
+            return handle;
+        };
+    }
+
+    function installSetTimeoutImplementation(attachTo) {
+        attachTo.setImmediate = function () {
+            var handle = tasks.addFromSetImmediateArguments(arguments);
+
+            global.setTimeout(function () {
+                tasks.runIfPresent(handle);
+            }, 0);
+
+            return handle;
+        };
+    }
+
+    if (!global.setImmediate) {
+        // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
+        var attachTo = typeof Object.getPrototypeOf === "function" && "setTimeout" in Object.getPrototypeOf(global) ?
+                          Object.getPrototypeOf(global)
+                        : global;
+
+        if (canUseNextTick()) {
+            // For Node.js before 0.9
+            installNextTickImplementation(attachTo);
+        } else if (canUsePostMessage()) {
+            // For non-IE10 modern browsers
+            installPostMessageImplementation(attachTo);
+        } else if (canUseMessageChannel()) {
+            // For web workers, where supported
+            installMessageChannelImplementation(attachTo);
+        } else if (canUseReadyStateChange()) {
+            // For IE 6–8
+            installReadyStateChangeImplementation(attachTo);
+        } else {
+            // For older browsers
+            installSetTimeoutImplementation(attachTo);
+        }
+
+        attachTo.clearImmediate = tasks.remove;
+    }
+}(typeof global === "object" && global ? global : this));

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/benchmarks/uubench.js
----------------------------------------------------------------------
diff --git a/www/benchmarks/uubench.js b/www/benchmarks/uubench.js
new file mode 100644
index 0000000..17c0c4d
--- /dev/null
+++ b/www/benchmarks/uubench.js
@@ -0,0 +1,115 @@
+//
+// uubench - Async Benchmarking v0.0.1
+// http://github.com/akdubya/uubench
+//
+// Copyright (c) 2010, Aleksander Williams
+// Released under the MIT License.
+//
+
+(function(uubench){
+
+function Bench(id, test, options, callback) {
+  this.id = id;
+  this.options = options;
+  this.test = test;
+  this.loop = test.length > 1;
+  this.callback = callback;
+}
+
+Bench.prototype.run = function(iter) {
+  var self = this, fn = self.test,
+      checkfn = self.options.type === "adaptive" ? adaptive : fixed,
+      i = iter, pend = i,
+      min = self.options.min, start;
+
+  if (self.loop) {
+    pend = 1;
+    start = new Date();
+    fn(checkfn, i);
+  } else {
+    start = new Date();
+    while (i--) {
+      fn(checkfn);
+    }
+  }
+
+  function fixed() {
+    if (--pend === 0) {
+      var elapsed = new Date() - start;
+      self.callback({iterations: iter, elapsed: elapsed});
+    }
+  }
+
+  function adaptive() {
+    if (--pend === 0) {
+      var elapsed = new Date() - start;
+      if (elapsed < min) {
+        self.run(iter*2);
+      } else {
+        self.callback({iterations: iter, elapsed: elapsed});
+      }
+    }
+  }
+}
+
+uubench.Bench = Bench;
+
+uubench.defaults = {
+  type:       "adaptive", // adaptive or fixed
+  iterations: 10,         // starting iterations
+  min:        100,        // minimum run time (ms) - adaptive only
+  delay:      100         // delay between tests (ms)
+}
+
+function Suite(opts) {
+  for (var key in uubench.defaults) {
+    if (opts[key] === undefined) {
+      opts[key] = uubench.defaults[key];
+    }
+  }
+  this.options = opts;
+  this.tests = [];
+}
+
+Suite.prototype.bench = function(name, fn) {
+  var self = this;
+  self.tests.push(new Bench(name, fn, this.options, function(stats) {
+    self.emit("result", name, stats);
+    self.pending--;
+    self.check();
+  }));
+}
+
+Suite.prototype.run = function() {
+  if (this.pending) return;
+  var self = this, len = self.tests.length;
+  self.emit("start", self.tests);
+  self.start = new Date().getTime();
+  self.pending = len;
+  for (var i=0; i<len; i++) {
+    self.runOne(i);
+  }
+}
+
+Suite.prototype.runOne = function(idx) {
+  var self = this;
+  setTimeout(function() {
+    self.tests[idx].run(self.options.iterations);
+  }, self.options.delay);
+}
+
+Suite.prototype.check = function() {
+  if (this.pending) return;
+  this.emit("done", new Date().getTime() - this.start);
+}
+
+Suite.prototype.emit = function(type) {
+  var event = this.options[type];
+  if (event) {
+    event.apply(this, Array.prototype.slice.call(arguments, 1));
+  }
+}
+
+uubench.Suite = Suite;
+
+})(typeof exports !== 'undefined' ? exports : window.uubench = {});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/camera/index.html
----------------------------------------------------------------------
diff --git a/www/camera/index.html b/www/camera/index.html
new file mode 100644
index 0000000..4f48190
--- /dev/null
+++ b/www/camera/index.html
@@ -0,0 +1,60 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+
+    <h1>Camera</h1>
+    <div id="info" style="white-space: pre-wrap">
+        <b>Status:</b> <div id="camera_status"></div>
+        img: <img width="100" id="camera_image">
+        canvas: <canvas id="canvas" width="1" height="1"></canvas>
+    </div>
+    <h2>Cordova Camera API</h2>
+    <div id="image-options"></div>
+    <div class="btn large getPicture">camera.getPicture()</div>
+    <h2>Native File Inputs</h2>
+    <div>input type=file <input type="file" class="testInputTag"></div>
+    <div>capture=camera <input type="file" accept="image/*;capture=camera" class="testInputTag"></div>
+    <div>capture=camcorder <input type="file" accept="video/*;capture=camcorder" class="testInputTag"></div>
+    <div>capture=microphone <input type="file" accept="audio/*;capture=microphone" class="testInputTag"></div>
+    <h2>Actions</h2>
+    <div class="btn large getFileInfo">Get File Metadata</div>
+    <div class="btn large readFile">Read with FileReader</div>
+    <div class="btn large copyImage">Copy Image</div>
+    <div class="btn large writeImage">Write Image</div>
+    <div class="btn large uploadImage">Upload Image</div>
+    <div class="btn large displayImageUsingCanvas">Draw Using Canvas</div>
+    <div class="btn large removeImage">Remove Image</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/camera/index.js
----------------------------------------------------------------------
diff --git a/www/camera/index.js b/www/camera/index.js
new file mode 100644
index 0000000..f9435d0
--- /dev/null
+++ b/www/camera/index.js
@@ -0,0 +1,344 @@
+var deviceReady = false;
+var platformId = cordova.require('cordova/platform').id;
+var pictureUrl = null;
+var fileObj = null;
+var fileEntry = null;
+var pageStartTime = +new Date();
+
+//default camera options
+var camQualityDefault = ['quality value', 50];
+var camDestinationTypeDefault = ['FILE_URI', 1];
+var camPictureSourceTypeDefault = ['CAMERA', 1];
+var camAllowEditDefault = ['allowEdit', false];
+var camEncodingTypeDefault = ['JPEG', 0];
+var camMediaTypeDefault = ['mediaType', 0];
+var camCorrectOrientationDefault = ['correctOrientation', false];
+var camSaveToPhotoAlbumDefault = ['saveToPhotoAlbum', true];
+
+
+//-------------------------------------------------------------------------
+// Camera
+//-------------------------------------------------------------------------
+
+function log(value) {
+    console.log(value);
+    document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
+}
+
+function clearStatus() {
+    document.getElementById('camera_status').innerHTML = '';
+    document.getElementById('camera_image').src = 'about:blank';
+    var canvas = document.getElementById('canvas');
+    canvas.width = canvas.height = 1;
+    pictureUrl = null;
+    fileObj = null;
+    fileEntry = null;
+}
+
+function setPicture(url, callback) {
+try {
+  window.atob(url);
+  // if we got here it is a base64 string (DATA_URL)
+  url = "data:image/jpeg;base64," + url;
+} catch (e) {
+  // not DATA_URL
+    log('URL: ' + url.slice(0, 100));
+}    
+
+    pictureUrl = url;
+    var img = document.getElementById('camera_image');
+    var startTime = new Date();
+    img.src = url;
+    img.onloadend = function() {
+        log('Image tag load time: ' + (new Date() - startTime));
+        callback && callback();
+    };
+}
+
+function onGetPictureError(e) {
+    log('Error getting picture: ' + e.code);
+}
+
+function getPictureWin(data) {
+    setPicture(data);
+    // TODO: Fix resolveLocalFileSystemURI to work with native-uri.
+    if (pictureUrl.indexOf('file:') == 0 || pictureUrl.indexOf('content:') == 0) {
+        resolveLocalFileSystemURI(data, function(e) {
+            fileEntry = e;
+            logCallback('resolveLocalFileSystemURI()', true)(e.toURL());
+        }, logCallback('resolveLocalFileSystemURI()', false));
+    } else if (pictureUrl.indexOf('data:image/jpeg;base64' == 0)) {
+      // do nothing
+    } else {
+        var path = pictureUrl.replace(/^file:\/\/(localhost)?/, '').replace(/%20/g, ' ');
+        fileEntry = new FileEntry('image_name.png', path);
+    }
+}
+
+function getPicture() {
+    clearStatus();
+    var options = extractOptions();
+    log('Getting picture with options: ' + JSON.stringify(options));
+    var popoverHandle = navigator.camera.getPicture(getPictureWin, onGetPictureError, options);
+
+    // Reposition the popover if the orientation changes.
+    window.onorientationchange = function() {
+        var newPopoverOptions = new CameraPopoverOptions(0, 0, 100, 100, 0);
+        popoverHandle.setPosition(newPopoverOptions);
+    }
+}
+
+function uploadImage() {
+    var ft = new FileTransfer(),
+        uploadcomplete=0,
+        progress = 0,
+        options = new FileUploadOptions();
+    options.fileKey="photo";
+    options.fileName='test.jpg';
+    options.mimeType="image/jpeg";
+    ft.onprogress = function(progressEvent) {
+        log('progress: ' + progressEvent.loaded + ' of ' + progressEvent.total);
+    };
+    var server = "http://cordova-filetransfer.jitsu.com";
+
+    ft.upload(pictureUrl, server + '/upload', win, fail, options);
+    function win(information_back){
+        log('upload complete');
+    }
+    function fail(message) {
+        log('upload failed: ' + JSON.stringify(message));
+    }
+}
+
+function logCallback(apiName, success) {
+    return function() {
+        log('Call to ' + apiName + (success ? ' success: ' : ' failed: ') + JSON.stringify([].slice.call(arguments)));
+    };
+}
+
+/**
+ * Select image from library using a NATIVE_URI destination type
+ * This calls FileEntry.getMetadata, FileEntry.setMetadata, FileEntry.getParent, FileEntry.file, and FileReader.readAsDataURL.
+ */
+function readFile() {
+    function onFileReadAsDataURL(evt) {
+        var img = document.getElementById('camera_image');
+        img.style.visibility = "visible";
+        img.style.display = "block";
+        img.src = evt.target.result;
+        log("FileReader.readAsDataURL success");
+    };
+
+    function onFileReceived(file) {
+        log('Got file: ' + JSON.stringify(file));
+        fileObj = file;
+
+        var reader = new FileReader();
+        reader.onload = function() {
+            log('FileReader.readAsDataURL() - length = ' + reader.result.length);
+        };
+        reader.onerror = logCallback('FileReader.readAsDataURL', false);
+        reader.readAsDataURL(file);
+    };
+    // Test out onFileReceived when the file object was set via a native <input> elements.
+    if (fileObj) {
+        onFileReceived(fileObj);
+    } else {
+        fileEntry.file(onFileReceived, logCallback('FileEntry.file', false));
+    }
+}
+function getFileInfo() {
+    // Test FileEntry API here.
+    fileEntry.getMetadata(logCallback('FileEntry.getMetadata', true), logCallback('FileEntry.getMetadata', false));
+    fileEntry.setMetadata(logCallback('FileEntry.setMetadata', true), logCallback('FileEntry.setMetadata', false), { "com.apple.MobileBackup": 1 });
+    fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false));
+    fileEntry.getParent(logCallback('FileEntry.getParent', true), logCallback('FileEntry.getParent', false));
+};
+
+/**
+ * Copy image from library using a NATIVE_URI destination type
+ * This calls FileEntry.copyTo and FileEntry.moveTo.
+ */
+function copyImage() {
+    var onFileSystemReceived = function(fileSystem) {
+        var destDirEntry = fileSystem.root;
+
+        // Test FileEntry API here.
+        fileEntry.copyTo(destDirEntry, 'copied_file.png', logCallback('FileEntry.copyTo', true), logCallback('FileEntry.copyTo', false));
+        fileEntry.moveTo(destDirEntry, 'moved_file.png', logCallback('FileEntry.moveTo', true), logCallback('FileEntry.moveTo', false));
+    };
+
+    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, onFileSystemReceived, null);
+};
+
+/**
+ * Write image to library using a NATIVE_URI destination type
+ * This calls FileEntry.createWriter, FileWriter.write, and FileWriter.truncate.
+ */
+function writeImage() {
+    var onFileWriterReceived = function(fileWriter) {
+        fileWriter.onwrite = logCallback('FileWriter.write', true);
+        fileWriter.onerror = logCallback('FileWriter.write', false);
+        fileWriter.write("some text!");
+    };
+
+    var onFileTruncateWriterReceived = function(fileWriter) {
+        fileWriter.onwrite = logCallback('FileWriter.truncate', true);
+        fileWriter.onerror = logCallback('FileWriter.truncate', false);
+        fileWriter.truncate(10);
+    };
+
+    fileEntry.createWriter(onFileWriterReceived, logCallback('FileEntry.createWriter', false));
+    fileEntry.createWriter(onFileTruncateWriterReceived, null);
+};
+
+function displayImageUsingCanvas() {
+    var canvas = document.getElementById('canvas');
+    var img = document.getElementById('camera_image');
+    var w = img.width;
+    var h = img.height;
+    h = 100 / w * h;
+    w = 100;
+    canvas.width = w;
+    canvas.height= h;
+    var context = canvas.getContext('2d');
+    context.drawImage(img, 0, 0, w, h);
+};
+
+/**
+ * Remove image from library using a NATIVE_URI destination type
+ * This calls FileEntry.remove.
+ */
+function removeImage() {
+    fileEntry.remove(logCallback('FileEntry.remove', true), logCallback('FileEntry.remove', false));
+};
+
+function testInputTag(inputEl) {
+    clearStatus();
+    // iOS 6 likes to dead-lock in the onchange context if you
+    // do any alerts or try to remote-debug.
+    window.setTimeout(function() {
+        testNativeFile2(inputEl);
+    }, 0);
+};
+
+function testNativeFile2(inputEl) {
+    if (!inputEl.value) {
+        alert('No file selected.');
+        return;
+    }
+    fileObj = inputEl.files[0];
+    if (!fileObj) {
+        alert('Got value but no file.');
+        return;
+    }
+    var URLApi = window.URL || window.webkitURL;
+    if (URLApi) {
+        var blobURL = URLApi.createObjectURL(fileObj);
+        if (blobURL) {
+            setPicture(blobURL, function() {
+                URLApi.revokeObjectURL(blobURL);
+            });
+        } else {
+            log('URL.createObjectURL returned null');
+        }
+    } else {
+        log('URL.createObjectURL() not supported.');
+    }
+}
+
+function extractOptions() {
+    var els = document.querySelectorAll('#image-options select');
+    var ret = {};
+    for (var i = 0, el; el = els[i]; ++i) {
+        var value = el.value;
+        if (value === '') continue;
+        if (el.isBool) {
+            ret[el.keyName] = !!+value;
+        } else {
+            ret[el.keyName] = +value;
+        }
+    }
+    return ret;
+}
+
+function createOptionsEl(name, values, selectionDefault) {
+    var container = document.createElement('div');
+    container.style.display = 'inline-block';
+    container.appendChild(document.createTextNode(name + ': '));
+    var select = document.createElement('select');
+    select.keyName = name;
+    container.appendChild(select);
+    
+    // if we didn't get a default value, insert the blank <default> entry
+    if (selectionDefault == undefined) {
+        var opt = document.createElement('option');
+        opt.value = '';
+        opt.text = '<default>';
+        select.appendChild(opt);
+    }
+    
+    select.isBool = typeof values == 'boolean';
+    if (select.isBool) {
+        values = {'true': 1, 'false': 0};
+    }
+    
+    for (var k in values) {
+        var opt = document.createElement('option');
+        opt.value = values[k];
+        opt.textContent = k;
+        if (selectionDefault) {
+            if (selectionDefault[0] == k) {
+                opt.selected = true;
+            }
+        }
+        select.appendChild(opt);
+    }
+    var optionsDiv = document.getElementById('image-options');
+    optionsDiv.appendChild(container);
+}
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+        deviceReady = true;
+        console.log("Device="+device.platform+" "+device.version);
+        createOptionsEl('sourceType', Camera.PictureSourceType, camPictureSourceTypeDefault);
+        createOptionsEl('destinationType', Camera.DestinationType, camDestinationTypeDefault);
+        createOptionsEl('encodingType', Camera.EncodingType, camEncodingTypeDefault);
+        createOptionsEl('mediaType', Camera.MediaType, camMediaTypeDefault);
+        createOptionsEl('quality', {'0': 0, '50': 50, '80': 80, '100': 100}, camQualityDefault);
+        createOptionsEl('targetWidth', {'50': 50, '200': 200, '800': 800, '2048': 2048});
+        createOptionsEl('targetHeight', {'50': 50, '200': 200, '800': 800, '2048': 2048});
+        createOptionsEl('allowEdit', true, camAllowEditDefault);
+        createOptionsEl('correctOrientation', true, camCorrectOrientationDefault);
+        createOptionsEl('saveToPhotoAlbum', true, camSaveToPhotoAlbumDefault);
+        createOptionsEl('cameraDirection', Camera.Direction);
+                      
+    }, false);
+    window.setTimeout(function() {
+        if (!deviceReady) {
+            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+        }
+    },1000);
+};
+
+window.onload = function() {
+  addListenerToClass('getPicture', getPicture);
+  addListenerToClass('testInputTag', function(e) {
+    testInputTag(e.target);
+  }, null, 'change', true);
+  addListenerToClass('getFileInfo', getFileInfo);
+  addListenerToClass('readFile', readFile);
+  addListenerToClass('copyImage', copyImage);
+  addListenerToClass('writeImage', writeImage);
+  addListenerToClass('uploadImage', uploadImage);
+  addListenerToClass('displayImageUsingCanvas', displayImageUsingCanvas);
+  addListenerToClass('removeImage', removeImage);
+
+  addListenerToClass('backBtn', backHome);
+  init();
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/capture/index.html
----------------------------------------------------------------------
diff --git a/www/capture/index.html b/www/capture/index.html
new file mode 100644
index 0000000..9543341
--- /dev/null
+++ b/www/capture/index.html
@@ -0,0 +1,52 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+
+    <h1>Capture</h1>
+    <div id="info" style="white-space: pre-wrap">
+        <b>Status:</b> <div id="camera_status"></div>
+        img: <img width="100" id="camera_image">
+        video: <div id="video_container"></div>
+    </div>
+    
+    <h2>Cordova Capture API</h2>
+    <div id="image-options"></div>
+
+    <h2>Actions</h2>
+    <div class="btn large getAudio">Capture 10 secs of audio and play</div>
+    <div class="btn large getImage">Capture 1 image</div>
+    <div class="btn large getVideo">Capture 10 secs of video</div>
+    <div class="btn large resolveVideo">Capture 5 secs of video and resolve</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/capture/index.js
----------------------------------------------------------------------
diff --git a/www/capture/index.js b/www/capture/index.js
new file mode 100644
index 0000000..0f98549
--- /dev/null
+++ b/www/capture/index.js
@@ -0,0 +1,137 @@
+var deviceReady = false;
+var platformId = cordova.require('cordova/platform').id;
+var pageStartTime = +new Date();
+
+//-------------------------------------------------------------------------
+// Camera
+//-------------------------------------------------------------------------
+
+function log(value) {
+    console.log(value);
+    document.getElementById('camera_status').textContent += (new Date() - pageStartTime) / 1000 + ': ' + value + '\n';
+}
+
+function captureAudioWin(mediaFiles){
+    var path = mediaFiles[0].fullPath;
+    log('Audio captured: ' + path);
+    var m = new Media(path);
+    m.play(); 
+}
+
+function captureAudioFail(e){
+    log('Error getting audio: ' + e.code);
+}
+
+function getAudio(){
+    clearStatus();
+    var options = { limit: 1, duration: 10};
+    navigator.device.capture.captureAudio(captureAudioWin, captureAudioFail, options);
+}
+
+function captureImageWin(mediaFiles){
+    var path = mediaFiles[0].fullPath;
+    log('Image captured: ' + path);    
+    document.getElementById('camera_image').src = path;    
+}
+
+function captureImageFail(e){
+    log('Error getting image: ' + e.code);
+}
+
+function getImage(){
+    clearStatus();
+    var options = { limit: 1 };
+    navigator.device.capture.captureImage(captureImageWin, captureImageFail, options);    
+}    
+
+function captureVideoWin(mediaFiles){
+    var path = mediaFiles[0].fullPath;
+    log('Video captured: ' + path);
+    
+    // need to inject the video element into the html
+    // doesn't seem to work if you have a pre-existing video element and
+    // add in a source tag
+    var vid = document.createElement('video');
+    vid.id="theVideo";
+    vid.width = "320";
+    vid.height= "240";
+    vid.controls = "true";
+    var source_vid = document.createElement('source');
+    source_vid.id = "theSource";
+    source_vid.src = path;
+    vid.appendChild(source_vid);
+    document.getElementById('video_container').appendChild(vid);    
+}
+
+function captureVideoFail(e){
+    log('Error getting video: ' + e.code);
+}
+
+function getVideo(){
+    clearStatus();
+    var options = { limit: 1, duration: 10 };
+    navigator.device.capture.captureVideo(captureVideoWin, captureVideoFail, options);      
+}
+
+function resolveMediaFileURL(mediaFile, callback) {
+    resolveLocalFileSystemURL(mediaFile.localURL, function(entry) {
+        log("Resolved by URL: " + mediaFile.localURL);
+        if (callback) callback();
+    }, function(err) {
+        log("Failed to resolve by URL: " + mediaFile.localURL);
+        log("Error: " + JSON.stringify(err));
+        if (callback) callback();
+    });
+}
+
+function resolveMediaFile(mediaFile, callback) {
+    resolveLocalFileSystemURL(mediaFile.fullPath, function(entry) {
+        log("Resolved by path: " + mediaFile.fullPath);
+        if (callback) callback();
+    }, function(err) {
+        log("Failed to resolve by path: " + mediaFile.fullPath);
+        log("Error: " + JSON.stringify(err));
+        if (callback) callback();
+    });
+}
+    
+function resolveVideo() {
+    clearStatus();
+    var options = { limit: 1, duration: 5 };
+    navigator.device.capture.captureVideo(function(mediaFiles) {
+        captureVideoWin(mediaFiles);
+        resolveMediaFile(mediaFiles[0], function() {
+            resolveMediaFileURL(mediaFiles[0]);
+        });
+    }, captureVideoFail, options);      
+}
+
+function clearStatus() {
+    document.getElementById('camera_status').innerHTML = '';
+    document.getElementById('camera_image').src = 'about:blank';
+}
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+        deviceReady = true;
+        console.log("Device="+device.platform+" "+device.version);
+    }, false);
+    window.setTimeout(function() {
+        if (!deviceReady) {
+            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+        }
+    },1000);
+};
+
+
+window.onload = function() {
+  addListenerToClass('getAudio', getAudio);
+  addListenerToClass('getImage', getImage);
+  addListenerToClass('getVideo', getVideo);
+  addListenerToClass('resolveVideo', resolveVideo);
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/compass/index.html
----------------------------------------------------------------------
diff --git a/www/compass/index.html b/www/compass/index.html
new file mode 100644
index 0000000..1734caa
--- /dev/null
+++ b/www/compass/index.html
@@ -0,0 +1,48 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Compass</h1>
+    <div id="info">
+        <b>Status:</b> <span id="compass_status">Stopped</span>
+        <table width="100%"><tr>
+            <td width="33%">Heading: <span id="compassHeading"> </span></td>
+        </tr></table>
+    </div>
+    <h2>Action</h2>
+    <div class="btn large getCompass">Get Compass</div>
+    <div class="btn large watchCompass">Start Watching Compass</div>
+    <div class="btn large stopCompass">Stop Watching Compass</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/compass/index.js
----------------------------------------------------------------------
diff --git a/www/compass/index.js b/www/compass/index.js
new file mode 100644
index 0000000..0735ab2
--- /dev/null
+++ b/www/compass/index.js
@@ -0,0 +1,104 @@
+var deviceReady = false;
+
+function roundNumber(num) {
+    var dec = 3;
+    var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
+    return result;
+}
+
+//-------------------------------------------------------------------------
+// Compass
+//-------------------------------------------------------------------------
+var watchCompassId = null;
+
+/**
+ * Start watching compass
+ */
+var watchCompass = function() {
+    console.log("watchCompass()");
+
+    // Success callback
+    var success = function(a){
+        document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
+    };
+
+    // Fail callback
+    var fail = function(e){
+        console.log("watchCompass fail callback with error code "+e);
+        stopCompass();
+        setCompassStatus(e);
+    };
+
+    // Update heading every 1 sec
+    var opt = {};
+    opt.frequency = 1000;
+    watchCompassId = navigator.compass.watchHeading(success, fail, opt);
+
+    setCompassStatus("Running");
+};
+
+/**
+ * Stop watching the acceleration
+ */
+var stopCompass = function() {
+    setCompassStatus("Stopped");
+    if (watchCompassId) {
+        navigator.compass.clearWatch(watchCompassId);
+        watchCompassId = null;
+    }
+};
+
+/**
+ * Get current compass
+ */
+var getCompass = function() {
+    console.log("getCompass()");
+
+    // Stop compass if running
+    stopCompass();
+
+    // Success callback
+    var success = function(a){
+        document.getElementById('compassHeading').innerHTML = roundNumber(a.magneticHeading);
+    };
+
+    // Fail callback
+    var fail = function(e){
+        console.log("getCompass fail callback with error code "+e);
+        setCompassStatus(e);
+    };
+
+    // Make call
+    var opt = {};
+    navigator.compass.getCurrentHeading(success, fail, opt);
+};
+
+/**
+ * Set compass status
+ */
+var setCompassStatus = function(status) {
+    document.getElementById('compass_status').innerHTML = status;
+};
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+      if (!deviceReady) {
+        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+      }
+    },1000);
+}
+
+window.onload = function() {
+  addListenerToClass('getCompass', getCompass);
+  addListenerToClass('watchCompass', watchCompass);
+  addListenerToClass('stopCompass', stopCompass);
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/contacts/index.html
----------------------------------------------------------------------
diff --git a/www/contacts/index.html b/www/contacts/index.html
new file mode 100644
index 0000000..5782713
--- /dev/null
+++ b/www/contacts/index.html
@@ -0,0 +1,47 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Contacts</h1>    
+    <div id="info">
+        <b>Results:</b><br>
+        <span id="contacts_results"> </span>
+    </div>
+    <h2>Action</h2>
+
+    <div class="btn large getContacts">Get phone's contacts</div>
+    <div class="btn large addContact">Add a new contact 'Dooney Evans'</div>
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/contacts/index.js
----------------------------------------------------------------------
diff --git a/www/contacts/index.js b/www/contacts/index.js
new file mode 100644
index 0000000..d3f3312
--- /dev/null
+++ b/www/contacts/index.js
@@ -0,0 +1,90 @@
+var deviceReady = false;
+
+//-------------------------------------------------------------------------
+// Contacts
+//-------------------------------------------------------------------------
+function getContacts() {
+    obj = new ContactFindOptions();
+    // show all contacts, so don't filter
+    obj.multiple = true;
+    navigator.contacts.find(
+        ["displayName", "name", "phoneNumbers", "emails", "urls", "note"],
+        function(contacts) {
+            var s = "";
+            if (contacts.length == 0) {
+                s = "No contacts found";
+            }
+            else {
+                s = "Number of contacts: "+contacts.length+"<br><table width='100%'><tr><th>Name</th><td>Phone</td><td>Email</td></tr>";
+                for (var i=0; i<contacts.length; i++) {
+                    var contact = contacts[i];
+                    s = s + "<tr><td>" + contact.name.formatted + "</td><td>";
+                    if (contact.phoneNumbers && contact.phoneNumbers.length > 0) {
+                        s = s + contact.phoneNumbers[0].value;
+                    }
+                    s = s + "</td><td>"
+                    if (contact.emails && contact.emails.length > 0) {
+                        s = s + contact.emails[0].value;
+                    }
+                    s = s + "</td></tr>";
+                }
+                s = s + "</table>";
+            }
+            document.getElementById('contacts_results').innerHTML = s;
+        },
+        function(e) {
+            document.getElementById('contacts_results').innerHTML = "Error: "+e.code;
+        },
+        obj);
+};
+
+function addContact(){
+    try{
+        var contact = navigator.contacts.create({"displayName": "Dooney Evans"});
+        var contactName = {
+            formatted: "Dooney Evans",
+            familyName: "Evans",
+            givenName: "Dooney",
+            middleName: ""
+        };
+
+        contact.name = contactName;
+
+        var phoneNumbers = [1];
+        phoneNumbers[0] = new ContactField('work', '512-555-1234', true);
+        contact.phoneNumbers = phoneNumbers;
+
+        contact.save(
+            function() { alert("Contact saved.");},
+            function(e) { alert("Contact save failed: " + e.code); }
+        );
+        console.log("you have saved the contact");
+    }
+    catch (e){
+        alert(e);
+    }
+
+};
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+      if (!deviceReady) {
+        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+      }
+    },1000);
+}
+
+
+window.onload = function() {
+  addListenerToClass('getContacts', getContacts);
+  addListenerToClass('addContact', addContact);
+  addListenerToClass('backBtn', backHome);
+  init();
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/cordova-incl.js
----------------------------------------------------------------------
diff --git a/www/cordova-incl.js b/www/cordova-incl.js
new file mode 100644
index 0000000..713dc1b
--- /dev/null
+++ b/www/cordova-incl.js
@@ -0,0 +1,88 @@
+/*
+ *
+ * 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 PLAT;
+(function getPlatform() {
+    var platforms = {
+        amazon_fireos: /cordova-amazon-fireos/,
+        android: /Android/,
+        ios: /(iPad)|(iPhone)|(iPod)/,
+        blackberry10: /(BB10)/,
+        blackberry: /(PlayBook)|(BlackBerry)/,
+        windows8: /MSAppHost/,
+        windowsphone: /Windows Phone/,
+        firefoxos: /Firefox/
+    };
+    for (var key in platforms) {
+        if (platforms[key].exec(navigator.userAgent)) {
+            PLAT = key;
+            break;
+        }
+    }
+})();
+
+var scripts = document.getElementsByTagName('script');
+var currentPath = scripts[scripts.length - 1].src;
+if (PLAT !== "blackberry10" && PLAT !== "firefoxos" && PLAT !== 'windowsphone') {
+    currentPath += '?paramShouldBeIgnored';
+}
+var cordovaPath = currentPath.replace("cordova-incl.js", "cordova.js");
+
+if (!window._doNotWriteCordovaScript) {
+    if (PLAT != "windows8") {
+        document.write('<script type="text/javascript" charset="utf-8" src="' + cordovaPath + '"></script>');
+    } else {
+        var s = document.createElement('script');
+        s.src = cordovaPath;
+        document.head.appendChild(s);
+    }
+}
+
+function addListenerToClass(className, listener, argsArray, action, doNotWrap) {
+    if (!action) {
+      action='click';
+    }
+    var elements = document.getElementsByClassName(className);
+    // choose Event target as a scope (like inline scripts)
+    if (!doNotWrap) {
+      if (argsArray && !Array.isArray(argsArray)) {
+        argsArray = [argsArray];
+      }
+      function callListener(e) {
+        listener.apply(null, argsArray);
+      }
+    } else {
+      callListener = listener;
+    }
+    for (var i = 0; i < elements.length; ++i) {
+      var item = elements[i];  
+      item.addEventListener(action, callListener, false);
+    }
+};
+
+function backHome() {
+    if (window.device && device.platform && (device.platform.toLowerCase() == 'android' || device.platform.toLowerCase() == 'amazon-fireos')) {
+        navigator.app.backHistory();
+    }
+    else {
+        window.history.go(-1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/events/index.html
----------------------------------------------------------------------
diff --git a/www/events/index.html b/www/events/index.html
new file mode 100644
index 0000000..3f45021
--- /dev/null
+++ b/www/events/index.html
@@ -0,0 +1,60 @@
+<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
+    <title>Cordova Mobile Spec</title>
+    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
+    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
+    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
+
+  </head>
+  <body id="stage" class="theme">
+  
+    <h1>Events</h1>
+    <div id="info">
+        <b>Results:</b><br>
+        <span id="results"></span>
+    </div>
+    <input type="text" value="Type here to test events when fields are focused" />
+    <h2>Action</h2>
+    <div class="btn large interceptBackButton">Intercept backbutton</div>
+    <div class="btn large stopInterceptOfBackButton">Stop intercept of backbutton</div>
+    <div class="btn large interceptMenuButton">Intercept menubutton</div>
+    <div class="btn large stopInterceptOfMenuButton">Stop intercept of menubutton</div>
+    <div class="btn large interceptSearchButton">Intercept searchbutton</div>
+    <div class="btn large stopInterceptOfSearchButton">Stop intercept of searchbutton</div>
+    <div class="btn large interceptResume">Intercept resume</div>
+    <div class="btn large stopInterceptOfResume">Stop intercept of resume</div>
+    <div class="btn large interceptPause">Intercept pause</div>
+    <div class="btn large stopInterceptOfPause">Stop intercept of pause</div>
+    <div class="btn large interceptOnline">Intercept online</div>
+    <div class="btn large stopInterceptOfOnline">Stop intercept of online</div>
+    <div class="btn large interceptOffline">Intercept offline</div>
+    <div class="btn large stopInterceptOfOffline">Stop intercept of offline</div>
+
+    <h2> </h2><div class="backBtn">Back</div>
+  </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/events/index.js
----------------------------------------------------------------------
diff --git a/www/events/index.js b/www/events/index.js
new file mode 100644
index 0000000..e1bb922
--- /dev/null
+++ b/www/events/index.js
@@ -0,0 +1,94 @@
+var deviceReady = false;
+
+function interceptBackbutton() {
+  eventOutput("Back button intercepted");
+}
+function interceptMenubutton() {
+  eventOutput("Menu button intercepted");
+}
+function interceptSearchbutton() {
+  eventOutput("Search button intercepted");
+}
+function interceptResume() {
+  eventOutput("Resume event intercepted");
+}
+function interceptPause() {
+  eventOutput("Pause event intercepted");
+}
+function interceptOnline() {
+  eventOutput("Online event intercepted");
+}
+function interceptOffline() {
+  eventOutput("Offline event intercepted");
+}
+
+var eventOutput = function(s) {
+    var el = document.getElementById("results");
+    el.innerHTML = el.innerHTML + s + "<br>";
+};
+
+
+/**
+ * Function called when page has finished loading.
+ */
+function init() {
+    document.addEventListener("deviceready", function() {
+            deviceReady = true;
+            console.log("Device="+device.platform+" "+device.version);
+            eventOutput("deviceready event: "+device.platform+" "+device.version);
+        }, false);
+    window.setTimeout(function() {
+      if (!deviceReady) {
+        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
+      }
+    },1000);
+}
+
+
+window.onload = function() {
+  addListenerToClass('interceptBackButton', function() {
+    document.addEventListener('backbutton', interceptBackbutton, false);
+  });
+  addListenerToClass('stopInterceptOfBackButton', function() {
+    document.removeEventListener('backbutton', interceptBackbutton, false);
+  });
+  addListenerToClass('interceptMenuButton', function() {
+    document.addEventListener('menubutton', interceptMenubutton, false);
+  });
+  addListenerToClass('stopInterceptOfMenuButton', function() {
+    document.removeEventListener('menubutton', interceptMenubutton, false);
+  });
+  addListenerToClass('interceptSearchButton', function() {
+    document.addEventListener('searchbutton', interceptSearchbutton, false);
+  });
+  addListenerToClass('stopInterceptOfSearchButton', function() {
+    document.removeEventListener('searchbutton', interceptSearchbutton, false);
+  });
+  addListenerToClass('interceptResume', function() {
+    document.addEventListener('resume', interceptResume, false);
+  });
+  addListenerToClass('stopInterceptOfResume', function() {
+    document.removeEventListener('resume', interceptResume, false);
+  });
+  addListenerToClass('interceptPause', function() {
+    document.addEventListener('pause', interceptPause, false);
+  });
+  addListenerToClass('stopInterceptOfPause', function() {
+    document.removeEventListener('pause', interceptPause, false);
+  });
+  addListenerToClass('interceptOnline', function() {
+    document.addEventListener('online', interceptOnline, false);
+  });
+  addListenerToClass('stopInterceptOfOnline', function() {
+    document.removeEventListener('online', interceptOnline, false);
+  });
+  addListenerToClass('interceptOffline', function() {
+    document.addEventListener('offline', interceptOffline, false);
+  });
+  addListenerToClass('stopInterceptOfOffline', function() {
+    document.removeEventListener('offline', interceptOffline, false);
+  });
+
+  addListenerToClass('backBtn', backHome);
+  init();
+}


[17/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/compass.html
----------------------------------------------------------------------
diff --git a/autotest/pages/compass.html b/autotest/pages/compass.html
deleted file mode 100644
index 80de16f..0000000
--- a/autotest/pages/compass.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Compass API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/compass.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/contacts.html
----------------------------------------------------------------------
diff --git a/autotest/pages/contacts.html b/autotest/pages/contacts.html
deleted file mode 100644
index e8e5fae..0000000
--- a/autotest/pages/contacts.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!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>Cordova: Contacts API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/contacts.tests.js"></script>
-
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn" id="backHome">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/datauri.html
----------------------------------------------------------------------
diff --git a/autotest/pages/datauri.html b/autotest/pages/datauri.html
deleted file mode 100644
index 33474dd..0000000
--- a/autotest/pages/datauri.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!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>Cordova: Data URI tests</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/datauri.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/device.html
----------------------------------------------------------------------
diff --git a/autotest/pages/device.html b/autotest/pages/device.html
deleted file mode 100644
index b1bed1d..0000000
--- a/autotest/pages/device.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Device API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/device.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/file.html
----------------------------------------------------------------------
diff --git a/autotest/pages/file.html b/autotest/pages/file.html
deleted file mode 100644
index d201791..0000000
--- a/autotest/pages/file.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!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>Cordova: File API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/file.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./file.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/file.js
----------------------------------------------------------------------
diff --git a/autotest/pages/file.js b/autotest/pages/file.js
deleted file mode 100644
index 9b1a67a..0000000
--- a/autotest/pages/file.js
+++ /dev/null
@@ -1,39 +0,0 @@
-var root, temp_root, persistent_root;
-
-document.addEventListener('deviceready', function () {
-    // one-time retrieval of the root file system entry
-    var onError = function(e) {
-        console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.');
-        console.log(JSON.stringify(e));
-    };
-
-    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
-        function(fileSystem) {
-            console.log('File API test Init: Setting PERSISTENT FS.');
-            root = fileSystem.root; // set in file.tests.js
-            persistent_root = root;
-
-            // Once root is set up, fire off tests
-            var jasmineEnv = jasmine.getEnv();
-            jasmineEnv.updateInterval = 1000;
-
-            var htmlReporter = new jasmine.HtmlReporter();
-
-            jasmineEnv.addReporter(htmlReporter);
-
-            jasmineEnv.specFilter = function(spec) {
-              return htmlReporter.specFilter(spec);
-            };
-
-            jasmineEnv.execute();
-        }, onError);
-    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
-        function(fileSystem) {
-            console.log('File API test Init: Setting TEMPORARY FS.');
-            temp_root = fileSystem.root; // set in file.tests.js
-        }, onError);
-}, false);
-
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/filetransfer.html
----------------------------------------------------------------------
diff --git a/autotest/pages/filetransfer.html b/autotest/pages/filetransfer.html
deleted file mode 100644
index 09809d8..0000000
--- a/autotest/pages/filetransfer.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!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>Cordova: File API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/filetransfer.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./file.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/geolocation.html
----------------------------------------------------------------------
diff --git a/autotest/pages/geolocation.html b/autotest/pages/geolocation.html
deleted file mode 100644
index b7a0698..0000000
--- a/autotest/pages/geolocation.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Geolocation API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/geolocation.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/globalization.html
----------------------------------------------------------------------
diff --git a/autotest/pages/globalization.html b/autotest/pages/globalization.html
deleted file mode 100644
index 295067e..0000000
--- a/autotest/pages/globalization.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!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>Cordova: Globalization API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/globalization.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/localXHR.html
----------------------------------------------------------------------
diff --git a/autotest/pages/localXHR.html b/autotest/pages/localXHR.html
deleted file mode 100644
index 10415f0..0000000
--- a/autotest/pages/localXHR.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!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>Cordova: Local XHR Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/localXHR.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/media.html
----------------------------------------------------------------------
diff --git a/autotest/pages/media.html b/autotest/pages/media.html
deleted file mode 100644
index ac1fa75..0000000
--- a/autotest/pages/media.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Media API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/media.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/network.html
----------------------------------------------------------------------
diff --git a/autotest/pages/network.html b/autotest/pages/network.html
deleted file mode 100644
index 6af5521..0000000
--- a/autotest/pages/network.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Network API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/network.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/notification.html
----------------------------------------------------------------------
diff --git a/autotest/pages/notification.html b/autotest/pages/notification.html
deleted file mode 100644
index 50777bf..0000000
--- a/autotest/pages/notification.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Notification API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/notification.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/platform.html
----------------------------------------------------------------------
diff --git a/autotest/pages/platform.html b/autotest/pages/platform.html
deleted file mode 100644
index 3ddecd0..0000000
--- a/autotest/pages/platform.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Platform API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/platform.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/run-tests.js
----------------------------------------------------------------------
diff --git a/autotest/pages/run-tests.js b/autotest/pages/run-tests.js
deleted file mode 100644
index 8e079ad..0000000
--- a/autotest/pages/run-tests.js
+++ /dev/null
@@ -1,18 +0,0 @@
-document.addEventListener('deviceready', function () {
-  var jasmineEnv = jasmine.getEnv();
-  jasmineEnv.updateInterval = 1000;
-
-  var htmlReporter = new jasmine.HtmlReporter();
-
-  jasmineEnv.addReporter(htmlReporter);
-
-  jasmineEnv.specFilter = function(spec) {
-    return htmlReporter.specFilter(spec);
-  };
-
-  jasmineEnv.execute();
-}, false);
-
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/splashscreen.html
----------------------------------------------------------------------
diff --git a/autotest/pages/splashscreen.html b/autotest/pages/splashscreen.html
deleted file mode 100644
index 6ac1c4d..0000000
--- a/autotest/pages/splashscreen.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Splashscreen API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/splashscreen.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/storage.html
----------------------------------------------------------------------
diff --git a/autotest/pages/storage.html b/autotest/pages/storage.html
deleted file mode 100644
index 0f836e9..0000000
--- a/autotest/pages/storage.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Storage API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/storage.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/vibration.html
----------------------------------------------------------------------
diff --git a/autotest/pages/vibration.html b/autotest/pages/vibration.html
deleted file mode 100644
index 04db2ec..0000000
--- a/autotest/pages/vibration.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Vibration API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/vibration.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/whitelist.html
----------------------------------------------------------------------
diff --git a/autotest/pages/whitelist.html b/autotest/pages/whitelist.html
deleted file mode 100644
index ececfa2..0000000
--- a/autotest/pages/whitelist.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Whitelist API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/whitelist.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/test-runner.js
----------------------------------------------------------------------
diff --git a/autotest/test-runner.js b/autotest/test-runner.js
deleted file mode 100644
index a744f81..0000000
--- a/autotest/test-runner.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-if (window.sessionStorage != null) {
-    window.sessionStorage.clear();
-}
-
-// Timeout is 2 seconds to allow physical devices enough
-// time to query the response. This is important for some
-// Android devices.
-var Tests = function() {};
-Tests.TEST_TIMEOUT = 7500;
-
-// Creates a spy that will fail if called.
-function createDoNotCallSpy(name, opt_extraMessage) {
-    return jasmine.createSpy().andCallFake(function() {
-        var errorMessage = "" + name + ' should not have been called.';
-        try {
-            if (arguments.length) {
-                errorMessage += ' Got args: ' + JSON.stringify(arguments);
-            }
-            if (opt_extraMessage) {
-                errorMessage += '\n' + opt_extraMessage;
-            }
-        } catch(e) {
-            errorMessage += " (Cannot print details)";
-        }
-        expect(false).toBe(true, errorMessage);
-    });
-}
-
-// Waits for any of the given spys to be called.
-// Last param may be a custom timeout duration.
-function waitsForAny() {
-    var spys = [].slice.call(arguments);
-    var timeout = Tests.TEST_TIMEOUT;
-    if (typeof spys[spys.length - 1] == 'number') {
-        timeout = spys.pop();
-    }
-    waitsFor(function() {
-        for (var i = 0; i < spys.length; ++i) {
-            if (spys[i].wasCalled) {
-                return true;
-            }
-        }
-        return false;
-    }, "Expecting callbacks to be called.", timeout);
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/accelerometer.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/accelerometer.tests.js b/autotest/tests/accelerometer.tests.js
deleted file mode 100644
index 029db05..0000000
--- a/autotest/tests/accelerometer.tests.js
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Accelerometer (navigator.accelerometer)', function () {
-    it("accelerometer.spec.1 should exist", function () {
-        expect(navigator.accelerometer).toBeDefined();
-    });
-
-    describe("getCurrentAcceleration", function() {
-        afterEach(function(){
-            // wait between testcases to avoid interference
-            var flag=false;
-            runs(function() {
-                setTimeout(function() {flag = true;}, 500);
-            });
-
-            waitsFor(function() {return flag;}, "flag to be true", Tests.TEST_TIMEOUT);
-        });
-
-        it("accelerometer.spec.2 should exist", function() {
-            expect(typeof navigator.accelerometer.getCurrentAcceleration).toBeDefined();
-            expect(typeof navigator.accelerometer.getCurrentAcceleration == 'function').toBe(true);
-        });
-
-        it("accelerometer.spec.3 success callback should be called with an Acceleration object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(a.x).toBeDefined();
-                    expect(typeof a.x == 'number').toBe(true);
-                    expect(a.y).toBeDefined();
-                    expect(typeof a.y == 'number').toBe(true);
-                    expect(a.z).toBeDefined();
-                    expect(typeof a.z == 'number').toBe(true);
-                    expect(a.timestamp).toBeDefined();
-                    expect(typeof a.timestamp).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.accelerometer.getCurrentAcceleration(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-
-        it("accelerometer.spec.4 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function() {
-            var reasonableThreshold = 15;
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a.x).toBeLessThan(reasonableThreshold);
-                    expect(a.x).toBeGreaterThan(reasonableThreshold * -1);
-                    expect(a.y).toBeLessThan(reasonableThreshold);
-                    expect(a.y).toBeGreaterThan(reasonableThreshold * -1);
-                    expect(a.z).toBeLessThan(reasonableThreshold);
-                    expect(a.z).toBeGreaterThan(reasonableThreshold * -1);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.accelerometer.getCurrentAcceleration(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-
-        it("accelerometer.spec.5 success callback Acceleration object should return a recent timestamp", function() {
-            // Check that timestamp returned is within a reasonable window.
-            var veryRecently = (new Date()).getTime()-1000; // lower bound - 1 second prior
-            var reasonableTimeLimit = veryRecently + 6000;  // upper bound - 5 seconds from now
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a.timestamp).toBeGreaterThan(veryRecently);
-                    expect(a.timestamp).toBeLessThan(reasonableTimeLimit);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.accelerometer.getCurrentAcceleration(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-
-    describe("watchAcceleration", function() {
-        var id;
-
-        afterEach(function() {
-            navigator.accelerometer.clearWatch(id);
-        });
-
-        it("accelerometer.spec.6 should exist", function() {
-            expect(navigator.accelerometer.watchAcceleration).toBeDefined();
-            expect(typeof navigator.accelerometer.watchAcceleration == 'function').toBe(true);
-        });
-        it("accelerometer.spec.7 success callback should be called with an Acceleration object", function() {
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a).toBeDefined();
-                    expect(a.x).toBeDefined();
-                    expect(typeof a.x == 'number').toBe(true);
-                    expect(a.y).toBeDefined();
-                    expect(typeof a.y == 'number').toBe(true);
-                    expect(a.z).toBeDefined();
-                    expect(typeof a.z == 'number').toBe(true);
-                    expect(a.timestamp).toBeDefined();
-                    expect(typeof a.timestamp).toBe('number');
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                id = navigator.accelerometer.watchAcceleration(win, fail, {frequency:500});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-
-        it("accelerometer.spec.8 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function() {
-            var reasonableThreshold = 15;
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a.x).toBeLessThan(reasonableThreshold);
-                    expect(a.x).toBeGreaterThan(reasonableThreshold * -1);
-                    expect(a.y).toBeLessThan(reasonableThreshold);
-                    expect(a.y).toBeGreaterThan(reasonableThreshold * -1);
-                    expect(a.z).toBeLessThan(reasonableThreshold);
-                    expect(a.z).toBeGreaterThan(reasonableThreshold * -1);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                id = navigator.accelerometer.watchAcceleration(win, fail, {frequency:500});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-
-        it("accelerometer.spec.9 success callback Acceleration object should return a recent timestamp", function() {
-            // Check that timestamp returned is within a reasonable window.
-            var veryRecently = (new Date()).getTime()-1000; // lower bound - 1 second prior
-            var reasonableTimeLimit = veryRecently + 6000;  // upper bound - 5 seconds from now
-            var win = jasmine.createSpy().andCallFake(function(a) {
-                    expect(a.timestamp).toBeGreaterThan(veryRecently);
-                    expect(a.timestamp).toBeLessThan(reasonableTimeLimit);
-                }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                id = navigator.accelerometer.watchAcceleration(win, fail, {frequency:500});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-
-    describe("clearWatch", function() {
-        it("accelerometer.spec.10 should exist", function() {
-            expect(navigator.accelerometer.clearWatch).toBeDefined();
-            expect(typeof navigator.accelerometer.clearWatch == 'function').toBe(true);
-        });
-
-        it("accelerometer.spec.11 should clear an existing watch", function() {
-            var id,
-                win = jasmine.createSpy();
-
-            runs(function() {
-                id = navigator.accelerometer.watchAcceleration(win, function() {}, {frequency:100});
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                win.reset();
-                navigator.accelerometer.clearWatch(id);
-            });
-
-            waits(201);
-
-            runs(function() {
-                expect(win).not.toHaveBeenCalled();
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/battery.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/battery.tests.js b/autotest/tests/battery.tests.js
deleted file mode 100644
index 47a86d4..0000000
--- a/autotest/tests/battery.tests.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Battery (navigator.battery)', function () {
-
-    // used to keep the count of event listeners > 0, in order to avoid battery level being updated with the real value when adding the first listener during test cases
-    var dummyOnEvent = jasmine.createSpy();
-    beforeEach(function () {
-        window.addEventListener("batterycritical", dummyOnEvent, false);
-    });
-
-    afterEach(function () {
-        window.removeEventListener("batterystatus", dummyOnEvent, false);
-    });
-
-
-    it("battery.spec.1 should exist", function() {
-        expect(navigator.battery).toBeDefined();
-    });
-
-    it("battery.spec.2 should fire batterystatus events", function () {
-
-        // batterystatus
-        var onEvent;
-        
-        runs(function () {
-            onEvent = jasmine.createSpy().andCallFake(function () {
-                window.removeEventListener("batterystatus", onEvent, false);
-            });
-            window.addEventListener("batterystatus", onEvent, false);
-            navigator.battery._status({ level: 30, isPlugged: false });
-        });
-        waitsFor(function () { return onEvent.wasCalled; }, "batterystatus onEvent was not called", 100);
-        runs(function () {
-            expect(onEvent).toHaveBeenCalled();
-        });
-
-    });
-
-    it("battery.spec.3 should fire batterylow events", function () {
-
-        var onEvent;
-        
-        // batterylow 30 -> 20
-        runs(function () {
-            onEvent = jasmine.createSpy().andCallFake(function () {
-                //console.log("batterylow fake callback called");
-                window.removeEventListener("batterylow", onEvent, false);
-            });
-            window.addEventListener("batterylow", onEvent, false);
-            navigator.battery._status({ level: 20, isPlugged: false });
-        });
-        waitsFor(function () { return onEvent.wasCalled; }, "batterylow onEvent was not called when level goes from 30->20", 100);
-        runs(function () {
-            expect(onEvent).toHaveBeenCalled();
-        });
-
-        // batterylow 30 -> 19
-        runs(function () {
-            onEvent = jasmine.createSpy().andCallFake(function () {
-                //console.log("batterylow fake callback called");
-                window.removeEventListener("batterylow", onEvent, false);
-            });
-            navigator.battery._status({ level: 30, isPlugged: false });
-            window.addEventListener("batterylow", onEvent, false);
-            navigator.battery._status({ level: 19, isPlugged: false });
-        });
-        waitsFor(function () { return onEvent.wasCalled; }, "batterylow onEvent was not called when level goes from 30->19", 100);
-        runs(function () {
-            expect(onEvent).toHaveBeenCalled();
-        });
-
-    });
-
-    it("battery.spec.4 should fire batterycritical events", function () {
-
-        var onEvent;
-
-        // batterycritical 19->5
-        runs(function () {
-            onEvent = jasmine.createSpy().andCallFake(function () {
-                window.removeEventListener("batterycritical", onEvent, false);
-            });
-            window.addEventListener("batterycritical", onEvent, false);
-            navigator.battery._status({ level: 5, isPlugged: false });
-        });
-        waitsFor(function () { return onEvent.wasCalled; }, "batterycritical onEvent was not called  when level goes from 19->5", 100);
-        runs(function () {
-            expect(onEvent).toHaveBeenCalled();
-        });
-        
-        // batterycritical 19->4
-        runs(function () {
-            onEvent = jasmine.createSpy().andCallFake(function () {
-                window.removeEventListener("batterycritical", onEvent, false);
-            });
-            navigator.battery._status({ level: 19, isPlugged: false });
-            window.addEventListener("batterycritical", onEvent, false);
-            navigator.battery._status({ level: 4, isPlugged: false });
-        });
-        waitsFor(function () { return onEvent.wasCalled; }, "batterycritical onEvent was not called  when level goes from 19->4", 100);
-        runs(function () {
-            expect(onEvent).toHaveBeenCalled();
-        });
-    });
-
-    it("battery.spec.5 should NOT fire events when charging or level is increasing", function () {
-       var onEvent;
-       // setup: batterycritical should fire when level decreases (100->4) ( CB-4519 )
-       runs(function () {
-            onEvent = jasmine.createSpy("onbatterycritical");
-            navigator.battery._status({ level: 100, isPlugged: false });
-            window.addEventListener("batterycritical", onEvent, false);
-            navigator.battery._status({ level: 4, isPlugged: false });
-            });
-       waits(100);
-       runs(function () {
-            expect(onEvent).toHaveBeenCalled();
-            });
-       
-       // batterycritical should not fire when level increases (4->5)( CB-4519 )
-       runs(function () {
-            onEvent = jasmine.createSpy("onbatterycritical");
-            navigator.battery._status({ level: 4, isPlugged: false });
-            window.addEventListener("batterycritical", onEvent, false);
-            navigator.battery._status({ level: 5, isPlugged: false });
-            });
-       waits(100);
-       runs(function () {
-            expect(onEvent).not.toHaveBeenCalled();
-            });
-        // batterylow should not fire when level increases (5->20) ( CB-4519 )
-        runs(function () {
-            onEvent = jasmine.createSpy("onbatterylow");
-            window.addEventListener("batterylow", onEvent, false);
-            navigator.battery._status({ level: 20, isPlugged: false });
-        });
-        waits(100);
-        runs(function () {
-            expect(onEvent).not.toHaveBeenCalled();
-        });
-
-        // batterylow should NOT fire if we are charging   ( CB-4520 )
-        runs(function () {
-            onEvent = jasmine.createSpy("onbatterylow");
-            navigator.battery._status({ level: 21, isPlugged: true });
-            window.addEventListener("batterylow", onEvent, false);
-            navigator.battery._status({ level: 20, isPlugged: true });
-        });
-        waits(100);
-        runs(function () {
-            expect(onEvent).not.toHaveBeenCalled();
-        });
-
-        // batterycritical should NOT fire if we are charging   ( CB-4520 )
-        runs(function () {
-            onEvent = jasmine.createSpy("onbatterycritical");
-            navigator.battery._status({ level: 6, isPlugged: true });
-            window.addEventListener("batterycritical", onEvent, false);
-            navigator.battery._status({ level: 5, isPlugged: true });
-            
-        });
-        waits(100);
-        runs(function () {
-            expect(onEvent).not.toHaveBeenCalled();
-        });
-    });
-
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/bridge.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/bridge.tests.js b/autotest/tests/bridge.tests.js
deleted file mode 100644
index 28c44c2..0000000
--- a/autotest/tests/bridge.tests.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Bridge', function() {
-    if (cordova.platformId == 'android') {
-        it("bridge.spec.1 should reject bridge from iframe with data: URL", function() {
-            var ifr = document.createElement('iframe');
-            var done = false;
-            ifr.src = 'data:text/html,';
-            ifr.onload = function() {
-                var stolenSecret = ifr.contentWindow.prompt('', 'gap_init:');
-                done = true;
-                expect(stolenSecret).toBe(null);
-            };
-            document.body.appendChild(ifr);
-            waitsFor(function() { return done; });
-        });
-    }
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/camera.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/camera.tests.js b/autotest/tests/camera.tests.js
deleted file mode 100644
index ee5bacd..0000000
--- a/autotest/tests/camera.tests.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Camera (navigator.camera)', function () {
-	it("should exist", function() {
-        expect(navigator.camera).toBeDefined();
-	});
-
-	it("should contain a getPicture function", function() {
-        expect(navigator.camera.getPicture).toBeDefined();
-		expect(typeof navigator.camera.getPicture == 'function').toBe(true);
-	});
-});
-
-describe('Camera Constants (window.Camera + navigator.camera)', function () {
-    it("camera.spec.1 window.Camera should exist", function() {
-        expect(window.Camera).toBeDefined();
-    });
-
-    it("camera.spec.2 should contain three DestinationType constants", function() {
-        expect(Camera.DestinationType.DATA_URL).toBe(0);
-        expect(Camera.DestinationType.FILE_URI).toBe(1);
-        expect(Camera.DestinationType.NATIVE_URI).toBe(2);
-        expect(navigator.camera.DestinationType.DATA_URL).toBe(0);
-        expect(navigator.camera.DestinationType.FILE_URI).toBe(1);
-        expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
-    });
-
-    it("camera.spec.3 should contain two EncodingType constants", function() {
-        expect(Camera.EncodingType.JPEG).toBe(0);
-        expect(Camera.EncodingType.PNG).toBe(1);
-        expect(navigator.camera.EncodingType.JPEG).toBe(0);
-        expect(navigator.camera.EncodingType.PNG).toBe(1);
-    });
-
-    it("camera.spec.4 should contain three MediaType constants", function() {
-        expect(Camera.MediaType.PICTURE).toBe(0);
-        expect(Camera.MediaType.VIDEO).toBe(1);
-        expect(Camera.MediaType.ALLMEDIA).toBe(2);
-        expect(navigator.camera.MediaType.PICTURE).toBe(0);
-        expect(navigator.camera.MediaType.VIDEO).toBe(1);
-        expect(navigator.camera.MediaType.ALLMEDIA).toBe(2);
-    });
-    it("camera.spec.5 should contain three PictureSourceType constants", function() {
-        expect(Camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
-        expect(Camera.PictureSourceType.CAMERA).toBe(1);
-        expect(Camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
-        expect(navigator.camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
-        expect(navigator.camera.PictureSourceType.CAMERA).toBe(1);
-        expect(navigator.camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/capture.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/capture.tests.js b/autotest/tests/capture.tests.js
deleted file mode 100644
index 99ce438..0000000
--- a/autotest/tests/capture.tests.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Capture (navigator.device.capture)', function () {
-    it("capture.spec.1 should exist", function() {
-        expect(navigator.device).toBeDefined();
-        expect(navigator.device.capture).toBeDefined();
-    });
-
-    it("capture.spec.2 should have the correct properties ", function() {
-        expect(navigator.device.capture.supportedAudioModes).toBeDefined();
-        expect(navigator.device.capture.supportedImageModes).toBeDefined();
-        expect(navigator.device.capture.supportedVideoModes).toBeDefined();
-    });
-
-    it("capture.spec.3 should contain a captureAudio function", function() {
-        expect(navigator.device.capture.captureAudio).toBeDefined();
-        expect(typeof navigator.device.capture.captureAudio == 'function').toBe(true);
-    });
-
-    it("capture.spec.4 should contain a captureImage function", function() {
-        expect(navigator.device.capture.captureImage).toBeDefined();
-        expect(typeof navigator.device.capture.captureImage == 'function').toBe(true);
-    });
-
-    it("capture.spec.5 should contain a captureVideo function", function() {
-        expect(navigator.device.capture.captureVideo).toBeDefined();
-        expect(typeof navigator.device.capture.captureVideo == 'function').toBe(true);
-    });
-
-    describe('CaptureAudioOptions', function () {
-        it("capture.spec.6 CaptureAudioOptions constructor should exist", function() {
-            var options = new CaptureAudioOptions();
-            expect(options).toBeDefined();
-            expect(options.limit).toBeDefined();
-            expect(options.duration).toBeDefined();
-        });
-    });
-
-    describe('CaptureImageOptions', function () {
-        it("capture.spec.7 CaptureImageOptions constructor should exist", function() {
-            var options = new CaptureImageOptions();
-            expect(options).toBeDefined();
-            expect(options.limit).toBeDefined();
-        });
-    });
-
-    describe('CaptureVideoOptions', function () {
-        it("capture.spec.8 CaptureVideoOptions constructor should exist", function() {
-            var options = new CaptureVideoOptions();
-            expect(options).toBeDefined();
-            expect(options.limit).toBeDefined();
-            expect(options.duration).toBeDefined();
-        });
-    });
-
-    describe('CaptureError interface', function () {
-        it("capture.spec.9 CaptureError constants should be defined", function() {
-            expect(CaptureError.CAPTURE_INTERNAL_ERR).toBe(0);
-            expect(CaptureError.CAPTURE_APPLICATION_BUSY).toBe(1);
-            expect(CaptureError.CAPTURE_INVALID_ARGUMENT).toBe(2);
-            expect(CaptureError.CAPTURE_NO_MEDIA_FILES).toBe(3);
-        });
-
-        it("capture.spec.10 CaptureError properties should exist", function() {
-            var error = new CaptureError();
-            expect(error).toBeDefined();
-            expect(error.code).toBeDefined();
-        });
-    });
-
-    describe('MediaFileData', function () {
-        it("capture.spec.11 MediaFileData constructor should exist", function() {
-            var fileData = new MediaFileData();
-            expect(fileData).toBeDefined();
-            expect(fileData.bitrate).toBeDefined();
-            expect(fileData.codecs).toBeDefined();
-            expect(fileData.duration).toBeDefined();
-            expect(fileData.height).toBeDefined();
-            expect(fileData.width).toBeDefined();
-        });
-    });
-
-    describe('MediaFile', function () {
-        it("capture.spec.12 MediaFile constructor should exist", function() {
-            var fileData = new MediaFile();
-            expect(fileData).toBeDefined();
-            expect(fileData.name).toBeDefined();
-            expect(fileData.type).toBeDefined();
-            expect(fileData.lastModifiedDate).toBeDefined();
-            expect(fileData.size).toBeDefined();
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/compass.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/compass.tests.js b/autotest/tests/compass.tests.js
deleted file mode 100644
index 332daea..0000000
--- a/autotest/tests/compass.tests.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Compass (navigator.compass)', function () {
-	var hardwarefailure = false;
-	beforeEach(function() {
-        this.addMatchers({
-        	// check to see if the device has a compass, if it doesn't fail gracefully 
-            hasHardware: function() {
-        		var toreturn = true;
-        	    
-        		try{
-        			this.actual;
-        			toreturn = true;
-        		} catch (error){
-        			if (error.code == CompassError.COMPASS_NOT_SUPPORTED){
-        				hardwarefailure = true;
-            			toreturn = false;
-        			}
-        		}
-        		this.message = function () {
-        	       return "The device does not have compass support.  The remaining compass tests will be ignored.";
-        	    }
-
-        		return toreturn;
-            }
-        });
-	});
-	
-	afterEach(function () {
-		// We want to gracefully fail if there is a hardware failure
-		if(this.results_.failedCount > 0 && hardwarefailure == true) {
-			//there was a hardware failure, cancelling all tests
-			jasmine.Queue.prototype.next_ = function () { this.onComplete();}
-		}
-	});
-	
-	it("compass.hardwarecheck is compass supported", function() {
-		var f = function(){navigator.compass.getCurrentHeading(function onSuccess(){}, function onError(error) {})};
-		expect(f).hasHardware();
-	}); 
-	
-	it("compass.spec.1 should exist", function() {
-        expect(navigator.compass).toBeDefined();
-    });
-
-    it("compass.spec.2 should contain a getCurrentHeading function", function() {
-        expect(navigator.compass.getCurrentHeading).toBeDefined();
-		expect(typeof navigator.compass.getCurrentHeading == 'function').toBe(true);
-	});
-
-    it("compass.spec.3 getCurrentHeading success callback should be called with a Heading object", function() {
-        var win = jasmine.createSpy().andCallFake(function(a) {
-                expect(a instanceof CompassHeading).toBe(true);
-                expect(a.magneticHeading).toBeDefined();
-                expect(typeof a.magneticHeading == 'number').toBe(true);
-                expect(a.trueHeading).not.toBe(undefined);
-                expect(typeof a.trueHeading == 'number' || a.trueHeading === null).toBe(true);
-                expect(a.headingAccuracy).not.toBe(undefined);
-                expect(typeof a.headingAccuracy == 'number' || a.headingAccuracy === null).toBe(true);
-                expect(typeof a.timestamp == 'number').toBe(true);
-            }),
-            fail = jasmine.createSpy();
-
-        runs(function () {
-            navigator.compass.getCurrentHeading(win, fail);
-        });
-
-        waitsFor(function () { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-
-        runs(function () {
-            expect(fail).not.toHaveBeenCalled();
-            expect(win).toHaveBeenCalled();
-        });
-	});
-
-    it("compass.spec.4 should contain a watchHeading function", function() {
-        expect(navigator.compass.watchHeading).toBeDefined();
-        expect(typeof navigator.compass.watchHeading == 'function').toBe(true);
-    });
-
-    it("compass.spec.5 should contain a clearWatch function", function() {
-        expect(navigator.compass.clearWatch).toBeDefined();
-        expect(typeof navigator.compass.clearWatch == 'function').toBe(true);
-    });
-
-    describe('Compass Constants (window.CompassError)', function () {
-        it("compass.spec.1 should exist", function() {
-            expect(window.CompassError).toBeDefined();
-            expect(window.CompassError.COMPASS_INTERNAL_ERR).toBe(0);
-            expect(window.CompassError.COMPASS_NOT_SUPPORTED).toBe(20);
-        });
-    });
-
-    describe('Compass Heading model (CompassHeading)', function () {
-        it("compass.spec.1 should exist", function() {
-            expect(CompassHeading).toBeDefined();
-        });
-
-        it("compass.spec.8 should be able to create a new CompassHeading instance with no parameters", function() {
-            var h = new CompassHeading();
-            expect(h).toBeDefined();
-            expect(h.magneticHeading).toBeUndefined();
-            expect(h.trueHeading).toBeUndefined();
-            expect(h.headingAccuracy).toBeUndefined();
-            expect(typeof h.timestamp == 'number').toBe(true);
-        });
-
-        it("compass.spec.9 should be able to create a new CompassHeading instance with parameters", function() {
-            var h = new CompassHeading(1,2,3,4);
-            expect(h.magneticHeading).toBe(1);
-            expect(h.trueHeading).toBe(2);
-            expect(h.headingAccuracy).toBe(3);
-            expect(h.timestamp.valueOf()).toBe(4);
-            expect(typeof h.timestamp == 'number').toBe(true);
-        });
-    });
-});


[14/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/filetransfer.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/filetransfer.tests.js b/autotest/tests/filetransfer.tests.js
deleted file mode 100644
index cbe15c0..0000000
--- a/autotest/tests/filetransfer.tests.js
+++ /dev/null
@@ -1,945 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('FileTransfer', function() {
-    // https://github.com/apache/cordova-labs/tree/cordova-filetransfer
-    var server = "http://cordova-filetransfer.jitsu.com";
-    var server_with_credentials = "http://cordova_user:cordova_password@cordova-filetransfer.jitsu.com";
-
-    // deletes and re-creates the specified content
-    var writeFile = function(fileName, fileContent, success, error) {
-        deleteFile(fileName, function() {
-            root.getFile(fileName, {create: true}, function(fileEntry) {
-                fileEntry.createWriter(function (writer) {
-
-                    writer.onwrite = function(evt) {
-                        success(fileEntry);
-                    };
-
-                    writer.onabort = function(evt) {
-                        error(evt);
-                    };
-
-                    writer.error = function(evt) {
-                        error(evt);
-                    };
-
-                    writer.write(fileContent + "\n");
-                }, error);
-            }, error);
-        });
-    };
-
-    var readFileEntry = function(entry, success, error) {
-        entry.file(function(file) {
-            var reader = new FileReader();
-            reader.onerror = error;
-            reader.onload = function(e) {
-                success(reader.result);
-            };
-            reader.readAsText(file);
-        }, error);
-    };
-
-    var getMalformedUrl = function() {
-        if (device.platform.match(/Android/i)) {
-            // bad protocol causes a MalformedUrlException on Android
-            return "httpssss://example.com";
-        } else {
-            // iOS doesn't care about protocol, space in hostname causes error
-            return "httpssss://exa mple.com";
-        }
-    };
-
-    // deletes file, if it exists, then invokes callback
-    var deleteFile = function(fileName, callback) {
-        callback = callback || function() {};
-        var spy = jasmine.createSpy().andCallFake(callback);
-        root.getFile(fileName, null,
-            // remove file system entry
-            function(entry) {
-                entry.remove(spy, spy);
-            },
-            // doesn't exist
-            spy);
-        waitsFor(function() { return spy.wasCalled; }, Tests.TEST_TIMEOUT);
-    };
-
-    it("filetransfer.spec.1 should exist and be constructable", function() {
-        var ft = new FileTransfer();
-        expect(ft).toBeDefined();
-    });
-    it("filetransfer.spec.2 should contain proper functions", function() {
-        var ft = new FileTransfer();
-        expect(typeof ft.upload).toBe('function');
-        expect(typeof ft.download).toBe('function');
-    });
-    describe('FileTransferError', function() {
-        it("filetransfer.spec.3 FileTransferError constants should be defined", function() {
-            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBe(1);
-            expect(FileTransferError.INVALID_URL_ERR).toBe(2);
-            expect(FileTransferError.CONNECTION_ERR).toBe(3);
-        });
-    });
-
-    describe('download method', function() {
-
-        // NOTE: if download tests are failing, check the white list
-        //
-        //   <access origin="httpssss://example.com"/>
-        //   <access origin="apache.org" subdomains="true" />
-        //   <access origin="cordova-filetransfer.jitsu.com"/>
-
-        it("filetransfer.spec.4 should be able to download a file using http", function() {
-            var fail = createDoNotCallSpy('downloadFail');
-            var fileFail = createDoNotCallSpy('downloadFail');
-            var remoteFile = server + "/robots.txt"
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var lastProgressEvent = null;
-
-            var fileWin = jasmine.createSpy().andCallFake(function(blob) {
-                expect(lastProgressEvent.loaded).not.toBeGreaterThan(blob.size);
-            });
-
-            var downloadWin = function(entry) {
-                expect(entry.name).toBe(localFileName);
-                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
-                if (lastProgressEvent.lengthComputable) {
-                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-                } else {
-                    expect(lastProgressEvent.total).toBe(0);
-                }
-                entry.file(fileWin, fileFail);
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.onprogress = function(e) {
-                    lastProgressEvent = e;
-                };
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
-            });
-
-            waitsForAny(fileWin, fail, fileFail);
-        });
-        it("filetransfer.spec.5 should be able to download a file using http basic auth", function() {
-            var fail = createDoNotCallSpy('downloadFail');
-            var remoteFile = server_with_credentials + "/download_basic_auth"
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var lastProgressEvent = null;
-
-            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
-                expect(entry.name).toBe(localFileName);
-                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
-                if (lastProgressEvent.lengthComputable) {
-                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-                } else {
-                    expect(lastProgressEvent.total).toBe(0);
-                }
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.onprogress = function(e) {
-                    lastProgressEvent = e;
-                };
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
-            });
-
-            waitsForAny(downloadWin, fail);
-        });
-        it("filetransfer.spec.6 should get http status on basic auth failure", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-
-            var remoteFile = server + "/download_basic_auth";
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.http_status).toBe(401);
-                expect(error.http_status).not.toBe(404, "Ensure " + remoteFile + " is in the white list");
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });        
-        it("filetransfer.spec.7 should be able to download a file using file:// (when hosted from file://)", function() {
-            var fail = createDoNotCallSpy('downloadFail');
-            var remoteFile = window.location.href.replace(/\?.*/, '').replace(/ /g, '%20');
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var lastProgressEvent = null;
-
-            if (!/^file/.exec(remoteFile) && cordova.platformId !== 'blackberry10') {
-                expect(remoteFile).toMatch(/^file:/);
-                return;
-            }
-
-            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
-                expect(entry.name).toBe(localFileName);
-                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
-                if (lastProgressEvent.lengthComputable) {
-                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-                } else {
-                    expect(lastProgressEvent.total).toBe(0);
-                }
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-
-            var ft = new FileTransfer();
-            ft.onprogress = function(e) {
-                lastProgressEvent = e;
-            };
-            ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
-
-            waitsForAny(downloadWin, fail);
-        });
-        it("filetransfer.spec.8 should be able to download a file using https", function() {
-            var remoteFile = "https://www.apache.org/licenses/";
-            var localFileName = 'httpstest.html';
-            var downloadFail = createDoNotCallSpy('downloadFail', 'Ensure ' + remoteFile + ' is in the white-list');
-            var fileFail = createDoNotCallSpy('fileFail');
-            var lastProgressEvent = null;
-            var downloadWin = function(entry) {
-                readFileEntry(entry, fileWin, fileFail);
-            };
-            var fileWin = jasmine.createSpy().andCallFake(function(content) {
-                expect(content).toMatch(/The Apache Software Foundation/);
-                expect(lastProgressEvent.loaded).not.toBeGreaterThan(content.length);
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-
-            var ft = new FileTransfer();
-            ft.onprogress = function(e) {
-                lastProgressEvent = e;
-            };
-            ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-
-            waitsForAny(fileWin, downloadFail, fileFail);
-        });
-        it("filetransfer.spec.9 should not leave partial file due to abort", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-            var remoteFile = 'http://cordova.apache.org/downloads/logos_2.zip';
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var startTime = +new Date();
-
-            var downloadFail = jasmine.createSpy().andCallFake(function(e) {
-                expect(e.code).toBe(FileTransferError.ABORT_ERR);
-                var didNotExistSpy = jasmine.createSpy();
-                var existedSpy = createDoNotCallSpy('file existed after abort');
-                root.getFile(localFileName, null, existedSpy, didNotExistSpy);
-                waitsForAny(didNotExistSpy, existedSpy);
-            });
-
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.onprogress = function(e) {
-                    if (e.loaded > 0) {
-                        ft.abort();
-                    }
-                };
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });
-        it("filetransfer.spec.10 should be stopped by abort() right away", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-            var remoteFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var startTime = +new Date();
-
-            var downloadFail = jasmine.createSpy().andCallFake(function(e) {
-                expect(e.code).toBe(FileTransferError.ABORT_ERR);
-                expect(new Date() - startTime).toBeLessThan(300);
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.abort(); // should be a no-op.
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-                ft.abort();
-                ft.abort(); // should be a no-op.
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });
-        it("filetransfer.spec.11 should call the error callback on abort()", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-           var downloadFail = jasmine.createSpy().andCallFake(function(e) { console.log("Abort called") });
-            var remoteFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var startTime = +new Date();
-                
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.abort(); // should be a no-op.
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-                ft.abort();
-                ft.abort(); // should be a no-op.
-            });
-                
-            waitsForAny(downloadFail);
-        });
-        it("filetransfer.spec.12 should get http status on failure", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-
-            var remoteFile = server + "/404";
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.http_status).toBe(404);
-                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });
-        it("filetransfer.spec.13 should get response body on failure", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-
-            var remoteFile = server + "/404";
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.body).toBeDefined();
-                expect(error.body).toMatch('You requested a 404');
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });
-        it("filetransfer.spec.14 should handle malformed urls", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-
-            var remoteFile = getMalformedUrl();
-            var localFileName = "download_malformed_url.txt";
-            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
-                // Note: Android needs the bad protocol to be added to the access list
-                // <access origin=".*"/> won't match because ^https?:// is prepended to the regex
-                // The bad protocol must begin with http to avoid automatic prefix
-                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
-                expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });
-        it("filetransfer.spec.15 should handle unknown host", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-
-            var remoteFile = "http://foobar.apache.org/index.html";
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
-            });
-
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });
-        it("filetransfer.spec.16 should handle bad file path", function() {
-            var downloadWin = createDoNotCallSpy('downloadWin');
-
-            var remoteFile = server;
-            var badFilePath = "c:\\54321";
-            var downloadFail = jasmine.createSpy();
-
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.download(remoteFile, badFilePath, downloadWin, downloadFail);
-            });
-
-            waitsForAny(downloadWin, downloadFail);
-        });
-        it("filetransfer.spec.17 progress should work with gzip encoding", function() {
-
-           //lengthComputable false on bb10 when downloading gzip 
-           if (cordova.platformId === 'blackberry10') {
-                return;
-           }
-
-           var downloadFail = createDoNotCallSpy('downloadFail');
-           var remoteFile = "http://www.apache.org/";
-           var localFileName = "index.html";
-           var lastProgressEvent = null;
-           
-           var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
-               expect(entry.name).toBe(localFileName);
-               expect(lastProgressEvent.loaded).toBeGreaterThan(1, 'loaded');
-               expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-               expect(lastProgressEvent.lengthComputable).toBe(true, 'lengthComputable');
-           });
-
-           this.after(function() {
-                      deleteFile(localFileName);
-                      });
-           runs(function() {
-               var ft = new FileTransfer();
-               ft.onprogress = function(e) {
-                   lastProgressEvent = e;
-               };
-               ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
-           });
-           waitsForAny(downloadWin, downloadFail);
-        });
-    });
-    describe('upload method', function() {
-        it("filetransfer.spec.18 should be able to upload a file", function() {
-            var remoteFile = server + "/upload";
-            var localFileName = "upload.txt";
-            var fileContents = 'This file should upload';
-
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
-            var lastProgressEvent = null;
-
-            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
-                expect(uploadResult.bytesSent).toBeGreaterThan(0);
-                expect(uploadResult.responseCode).toBe(200);
-                var obj = null;
-                try {
-                    obj = JSON.parse(uploadResult.response);
-                    expect(obj.fields).toBeDefined();
-                    expect(obj.fields.value1).toBe("test");
-                    expect(obj.fields.value2).toBe("param");
-                } catch (e) {
-                    expect(obj).not.toBeNull('returned data from server should be valid json');
-                }
-                expect(lastProgressEvent).not.toBeNull('expected progress events');
-                if (cordova.platformId == 'ios') {
-                    expect(uploadResult.headers && uploadResult.headers['Content-Type']).toBeDefined('Expected content-type header to be defined.');
-                }
-            });
-
-            var fileWin = function(fileEntry) {
-                ft = new FileTransfer();
-
-                var options = new FileUploadOptions();
-                options.fileKey = "file";
-                options.fileName = localFileName;
-                options.mimeType = "text/plain";
-
-                var params = new Object();
-                params.value1 = "test";
-                params.value2 = "param";
-                options.params = params;
-
-                ft.onprogress = function(e) {
-                    lastProgressEvent = e;
-                    expect(e.lengthComputable).toBe(true);
-                    expect(e.total).toBeGreaterThan(0);
-                    expect(e.loaded).toBeGreaterThan(0);
-                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-                };
-
-                // removing options cause Android to timeout
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, fileContents, fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail);
-        });
-        it("filetransfer.spec.19 should be able to upload a file with http basic auth", function() {
-            var remoteFile = server_with_credentials + "/upload_basic_auth";
-            var localFileName = "upload.txt";
-            var fileContents = 'This file should upload';
-
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
-            var lastProgressEvent = null;
-
-            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
-                expect(uploadResult.bytesSent).toBeGreaterThan(0);
-                expect(uploadResult.responseCode).toBe(200);
-                var obj = null;
-                try {
-                    obj = JSON.parse(uploadResult.response);
-                    expect(obj.fields).toBeDefined();
-                    expect(obj.fields.value1).toBe("test");
-                    expect(obj.fields.value2).toBe("param");
-                } catch (e) {
-                    expect(obj).not.toBeNull('returned data from server should be valid json');
-                }
-            });
-
-            var fileWin = function(fileEntry) {
-                ft = new FileTransfer();
-
-                var options = new FileUploadOptions();
-                options.fileKey = "file";
-                options.fileName = localFileName;
-                options.mimeType = "text/plain";
-
-                var params = new Object();
-                params.value1 = "test";
-                params.value2 = "param";
-                options.params = params;
-
-                ft.onprogress = function(e) {
-                    expect(e.lengthComputable).toBe(true);
-                    expect(e.total).toBeGreaterThan(0);
-                    expect(e.loaded).toBeGreaterThan(0);
-                    lastProgressEvent = e;
-                };
-
-                // removing options cause Android to timeout
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, fileContents, fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail);
-            runs(function() {
-                expect(lastProgressEvent).not.toBeNull('expected progress events');
-                expect(lastProgressEvent.loaded).toBeGreaterThan(1, 'loaded');
-                expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-            });
-        });
-        it("filetransfer.spec.6 should get http status on basic auth failure", function() {
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadWin = createDoNotCallSpy('uploadWin');
-
-            var remoteFile = server + "/upload_basic_auth";
-            var localFileName = "upload_expect_fail.txt";
-            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.http_status).toBe(401);
-                expect(error.http_status).not.toBe(404, "Ensure " + remoteFile + " is in the white list");
-            });
-
-            var fileWin = function(fileEntry) {
-                var ft = new FileTransfer();
-
-                var options = new FileUploadOptions();
-                options.fileKey="file";
-                options.fileName=fileEntry.name;
-                options.mimeType="text/plain";
-
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, "this file should fail to upload", fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail);
-        });
-        it("filetransfer.spec.21 should be stopped by abort() right away.", function() {
-            var remoteFile = server + "/upload";
-            var localFileName = "upload.txt";
-
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadWin = createDoNotCallSpy('uploadWin', 'Should have been aborted');
-            var startTime;
-
-            var uploadFail = jasmine.createSpy().andCallFake(function(e) {
-                expect(e.code).toBe(FileTransferError.ABORT_ERR);
-                expect(new Date() - startTime).toBeLessThan(300);
-            });
-
-            var fileWin = function(fileEntry) {
-                ft = new FileTransfer();
-
-                var options = new FileUploadOptions();
-                options.fileKey = "file";
-                options.fileName = localFileName;
-                options.mimeType = "text/plain";
-
-                startTime = +new Date();
-                // removing options cause Android to timeout
-                ft.abort(); // should be a no-op.
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
-                ft.abort();
-                ft.abort(); // should be a no-op.
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, new Array(10000).join('aborttest!'), fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail);
-        });
-        it("filetransfer.spec.12 should get http status on failure", function() {
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadWin = createDoNotCallSpy('uploadWin');
-
-            var remoteFile = server + "/403";
-            var localFileName = "upload_expect_fail.txt";
-            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.http_status).toBe(403);
-                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
-            });
-
-            var fileWin = function(fileEntry) {
-                var ft = new FileTransfer();
-
-                var options = new FileUploadOptions();
-                options.fileKey="file";
-                options.fileName=fileEntry.name;
-                options.mimeType="text/plain";
-
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, "this file should fail to upload", fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail);
-        });
-        it("filetransfer.spec.14 should handle malformed urls", function() {
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadWin = createDoNotCallSpy('uploadWin');
-
-            var remoteFile = getMalformedUrl();
-            var localFileName = "malformed_url.txt";
-            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
-                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
-            });
-            var fileWin = function(fileEntry) {
-                var ft = new FileTransfer();
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, {});
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, "Some content", fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail);
-        });
-        it("filetransfer.spec.15 should handle unknown host", function() {
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadWin = createDoNotCallSpy('uploadWin');
-
-            var remoteFile = "http://foobar.apache.org/robots.txt";
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
-                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
-            });
-            var fileWin = function(fileEntry) {
-                var ft = new FileTransfer();
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, {});
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, "# allow all", fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail);
-        });
-        it("filetransfer.spec.25 should handle missing file", function() {
-            var uploadWin = createDoNotCallSpy('uploadWin');
-
-            var remoteFile = server + "/upload";
-            var localFileName = "does_not_exist.txt";
-
-            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
-                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
-            });
-
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.upload(root.toURL() + "/" + localFileName, remoteFile, uploadWin, uploadFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail);
-        });
-        it("filetransfer.spec.16 should handle bad file path", function() {
-            var uploadWin = createDoNotCallSpy('uploadWin');
-
-            var remoteFile = server + "/upload";
-
-            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
-                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
-            });
-
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.upload("/usr/local/bad/file/path.txt", remoteFile, uploadWin, uploadFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail);
-        });
-        it("filetransfer.spec.27 should be able to set custom headers", function() {
-            var remoteFile = "http://whatheaders.com";
-            var localFileName = "upload.txt";
-
-            var fileFail = function() {};
-            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list and that Content-Length header is being set.");
-
-            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
-                expect(uploadResult.bytesSent).toBeGreaterThan(0);
-                expect(uploadResult.responseCode).toBe(200);
-                expect(uploadResult.response).toBeDefined();
-                var responseHtml = decodeURIComponent(uploadResult.response);
-                expect(responseHtml).toMatch(/CustomHeader1[\s\S]*CustomValue1/i);
-                expect(responseHtml).toMatch(/CustomHeader2[\s\S]*CustomValue2[\s\S]*CustomValue3/i, "Should allow array values");
-            });
-
-            var fileWin = function(fileEntry) {
-                ft = new FileTransfer();
-
-                var options = new FileUploadOptions();
-                options.fileKey = "file";
-                options.fileName = localFileName;
-                options.mimeType = "text/plain";
-
-                var params = new Object();
-                params.value1 = "test";
-                params.value2 = "param";
-                options.params = params;
-                options.headers = {
-                    "CustomHeader1": "CustomValue1",
-                    "CustomHeader2": ["CustomValue2", "CustomValue3"],
-                };
-
-                // removing options cause Android to timeout
-                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, "this file should upload", fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail);
-        });
-    });
-    describe('Backwards compatibility', function() {
-        /* These specs exist to test that the previously supported API still works with
-         * the new version of file-transfer.
-         * They rely on an undocumented interface to File which provides absolute file
-         * paths, which are not used internally anymore.
-         * If that interface is not present, then these tests will silently succeed.
-         */
-        it("filetransfer.spec.28 should be able to download a file using local paths", function() {
-            var fail = createDoNotCallSpy('downloadFail');
-            var remoteFile = server + "/robots.txt"
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
-            var localURL = root.toURL() + "/" + localFileName;
-            var lastProgressEvent = null;
-
-            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
-                expect(entry.name).toBe(localFileName);
-                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
-            });
-            var unsupportedOperation = jasmine.createSpy("Operation not supported");
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                /* This is an undocumented interface to File which exists only for testing
-                 * backwards compatibilty. By obtaining the raw filesystem path of the download
-                 * location, we can pass that to ft.download() to make sure that previously-stored
-                 * paths are still valid.
-                 */
-                cordova.exec(function(localPath) {
-                    var ft = new FileTransfer();
-                    ft.onprogress = function(e) {
-                        lastProgressEvent = e;
-                        if (lastProgressEvent.lengthComputable) {
-                            expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-                        } else {
-                            expect(lastProgressEvent.total).toBe(0);
-                        }
-                    };
-                    ft.download(remoteFile, localPath, downloadWin, fail);
-                }, unsupportedOperation, 'File', '_getLocalFilesystemPath', [localURL]);
-            });
-
-            waitsForAny(downloadWin, fail, unsupportedOperation);
-        });
-        it("filetransfer.spec.29 should be able to upload a file using local paths", function() {
-            var remoteFile = server + "/upload";
-            var localFileName = "upload.txt";
-            var fileContents = 'This file should upload';
-
-            var fileFail = createDoNotCallSpy('fileFail');
-            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
-            var unsupportedOperation = jasmine.createSpy("Operation not supported");
-            var lastProgressEvent = null;
-
-            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
-                expect(uploadResult.bytesSent).toBeGreaterThan(0);
-                expect(uploadResult.responseCode).toBe(200);
-                var obj = null;
-                try {
-                    obj = JSON.parse(uploadResult.response);
-                    expect(obj.fields).toBeDefined();
-                    expect(obj.fields.value1).toBe("test");
-                    expect(obj.fields.value2).toBe("param");
-                } catch (e) {
-                    expect(obj).not.toBeNull('returned data from server should be valid json');
-                }
-            });
-
-            var fileWin = function(fileEntry) {
-                ft = new FileTransfer();
-
-                var options = new FileUploadOptions();
-                options.fileKey = "file";
-                options.fileName = localFileName;
-                options.mimeType = "text/plain";
-
-                var params = new Object();
-                params.value1 = "test";
-                params.value2 = "param";
-                options.params = params;
-
-                ft.onprogress = function(e) {
-                    expect(e.lengthComputable).toBe(true);
-                    expect(e.total).toBeGreaterThan(0);
-                    expect(e.loaded).toBeGreaterThan(0);
-                    lastProgressEvent = e;
-                };
-
-                // removing options cause Android to timeout
-
-                /* This is an undocumented interface to File which exists only for testing
-                 * backwards compatibilty. By obtaining the raw filesystem path of the download
-                 * location, we can pass that to ft.download() to make sure that previously-stored
-                 * paths are still valid.
-                 */
-                cordova.exec(function(localPath) {
-                    ft.upload(localPath, remoteFile, uploadWin, uploadFail, options);
-                }, unsupportedOperation, 'File', '_getLocalFilesystemPath', [fileEntry.toURL()]);
-
-            };
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                writeFile(localFileName, fileContents, fileWin, fileFail);
-            });
-
-            waitsForAny(uploadWin, uploadFail, fileFail, unsupportedOperation);
-            runs(function() {
-                if (!unsupportedOperation.wasCalled) {
-                    expect(lastProgressEvent).not.toBeNull('expected progress events');
-                    expect(lastProgressEvent.loaded).toBeGreaterThan(1);
-                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
-                }
-            });
-        });
-    });
-    describe('native URL interface', function() {
-        it("filetransfer.spec.30 downloaded file entries should have a toNativeURL method", function() {
-            var fail = createDoNotCallSpy('downloadFail');
-            var remoteFile = server + "/robots.txt";
-            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1)+".spec30";
-
-            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
-                expect(entry.toNativeURL).toBeDefined();
-                expect(typeof entry.toNativeURL).toBe("function");
-                var nativeURL = entry.toNativeURL();
-                expect(typeof nativeURL).toBe("string");
-                expect(nativeURL.substring(0,7)).toBe('file://');
-            });
-
-            this.after(function() {
-                deleteFile(localFileName);
-            });
-            runs(function() {
-                var ft = new FileTransfer();
-                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
-            });
-
-            waitsForAny(downloadWin, fail);
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/geolocation.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/geolocation.tests.js b/autotest/tests/geolocation.tests.js
deleted file mode 100644
index bdb0b53..0000000
--- a/autotest/tests/geolocation.tests.js
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Geolocation (navigator.geolocation)', function () {
-    it("geolocation.spec.1 should exist", function() {
-        expect(navigator.geolocation).toBeDefined();
-    });
-
-    it("geolocation.spec.2 should contain a getCurrentPosition function", function() {
-        expect(typeof navigator.geolocation.getCurrentPosition).toBeDefined();
-        expect(typeof navigator.geolocation.getCurrentPosition == 'function').toBe(true);
-    });
-
-    it("geolocation.spec.3 should contain a watchPosition function", function() {
-        expect(typeof navigator.geolocation.watchPosition).toBeDefined();
-        expect(typeof navigator.geolocation.watchPosition == 'function').toBe(true);
-    });
-
-    it("geolocation.spec.4 should contain a clearWatch function", function() {
-        expect(typeof navigator.geolocation.clearWatch).toBeDefined();
-        expect(typeof navigator.geolocation.clearWatch == 'function').toBe(true);
-    });
-
-    describe('getCurrentPosition method', function() {
-        // this api requires manual user confirmation on windows8 so skip it
-        if (cordova.platformId == 'windows8') return;
-        
-        describe('error callback', function() {
-            it("geolocation.spec.5 should be called if we set timeout to 0 and maximumAge to a very small number", function() {
-                console.log("Here I am");
-                var win = jasmine.createSpy(),
-                    fail = jasmine.createSpy();
-
-                runs(function () {
-                    navigator.geolocation.getCurrentPosition(win, fail, {
-                        maximumAge: 0,
-                        timeout: 0
-                    });
-                });
-
-                waitsFor(function () { return fail.wasCalled; }, "fail never called", 250); //small timeout as this should fire very fast
-
-                runs(function () {
-                    expect(win).not.toHaveBeenCalled();
-                });
-            });
-        });
-
-        describe('success callback', function() {
-            it("geolocation.spec.6 should be called with a Position object", function() {
-                var providerAvailable=true;
-                var win = jasmine.createSpy().andCallFake(function(p) {
-                          expect(p.coords).toBeDefined();
-                          expect(p.timestamp).toBeDefined();
-                      }),
-                      fail = jasmine.createSpy().andCallFake(function(e) {
-                          if(e.code == 2) {
-                              providerAvailable=false;
-                          }
-                      });
-
-                runs(function () {
-                    navigator.geolocation.getCurrentPosition(win, fail, {
-                        maximumAge:300000 // 5 minutes maximum age of cached position
-                    });
-                });
-
-                waitsFor(function () { return (win.wasCalled || fail.wasCalled); }, "win/fail never called", 20000);
-
-                runs(function () {
-                    if(providerAvailable) {
-                        expect(fail).not.toHaveBeenCalled();
-                    }
-                });
-            });
-        });
-    });
-
-    describe('watchPosition method', function() {
-        // this api requires manual user confirmation on windows8 so skip it
-        if (cordova.platformId == 'windows8') return;
-        
-        describe('error callback', function() {
-            var errorWatch = null;
-
-            afterEach(function() {
-                navigator.geolocation.clearWatch(errorWatch);
-            });
-            it("geolocation.spec.7 should be called if we set timeout to 0 and maximumAge to a very small number", function() {
-                var win = jasmine.createSpy(),
-                    fail = jasmine.createSpy();
-
-                runs(function () {
-                    errorWatch = navigator.geolocation.watchPosition(win, fail, {
-                        maximumAge: 0,
-                        timeout: 0
-                    });
-                });
-
-                waitsFor(function () { return fail.wasCalled; }, "fail never called", 250); // small timeout as this should fire very quickly
-
-                runs(function () {
-                    expect(win).not.toHaveBeenCalled();
-                });
-            });
-        });
-
-        describe('success callback', function() {
-            var successWatch = null;
- 
-            afterEach(function() {
-                navigator.geolocation.clearWatch(successWatch);
-            });
-            it("geolocation.spec.8 should be called with a Position object", function() {
-                var providerAvailable=true;
-                var win = jasmine.createSpy().andCallFake(function(p) {
-                          expect(p.coords).toBeDefined();
-                          expect(p.timestamp).toBeDefined();
-                      }),
-                      fail = jasmine.createSpy().andCallFake(function(e) {
-                          if(e.code ==2) {
-                              providerAvailable=false;
-                          }
-                      });
-
-                runs(function () {
-                    successWatch = navigator.geolocation.watchPosition(win, fail, {
-                        maximumAge:(5 * 60 * 1000) // 5 minutes maximum age of cached position
-                    });
-                });
-
-                waitsFor(function () { return (win.wasCalled || fail.wasCalled); }, "win/fail never called", 20000);
-
-                runs(function () {
-                    if(providerAvailable) {
-                        expect(fail).not.toHaveBeenCalled();
-                    }
-                });
-            });
-        });
-    });
-});


[05/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/filetransfer.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/filetransfer.tests.js b/www/autotest/tests/filetransfer.tests.js
new file mode 100644
index 0000000..cbe15c0
--- /dev/null
+++ b/www/autotest/tests/filetransfer.tests.js
@@ -0,0 +1,945 @@
+/*
+ *
+ * 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('FileTransfer', function() {
+    // https://github.com/apache/cordova-labs/tree/cordova-filetransfer
+    var server = "http://cordova-filetransfer.jitsu.com";
+    var server_with_credentials = "http://cordova_user:cordova_password@cordova-filetransfer.jitsu.com";
+
+    // deletes and re-creates the specified content
+    var writeFile = function(fileName, fileContent, success, error) {
+        deleteFile(fileName, function() {
+            root.getFile(fileName, {create: true}, function(fileEntry) {
+                fileEntry.createWriter(function (writer) {
+
+                    writer.onwrite = function(evt) {
+                        success(fileEntry);
+                    };
+
+                    writer.onabort = function(evt) {
+                        error(evt);
+                    };
+
+                    writer.error = function(evt) {
+                        error(evt);
+                    };
+
+                    writer.write(fileContent + "\n");
+                }, error);
+            }, error);
+        });
+    };
+
+    var readFileEntry = function(entry, success, error) {
+        entry.file(function(file) {
+            var reader = new FileReader();
+            reader.onerror = error;
+            reader.onload = function(e) {
+                success(reader.result);
+            };
+            reader.readAsText(file);
+        }, error);
+    };
+
+    var getMalformedUrl = function() {
+        if (device.platform.match(/Android/i)) {
+            // bad protocol causes a MalformedUrlException on Android
+            return "httpssss://example.com";
+        } else {
+            // iOS doesn't care about protocol, space in hostname causes error
+            return "httpssss://exa mple.com";
+        }
+    };
+
+    // deletes file, if it exists, then invokes callback
+    var deleteFile = function(fileName, callback) {
+        callback = callback || function() {};
+        var spy = jasmine.createSpy().andCallFake(callback);
+        root.getFile(fileName, null,
+            // remove file system entry
+            function(entry) {
+                entry.remove(spy, spy);
+            },
+            // doesn't exist
+            spy);
+        waitsFor(function() { return spy.wasCalled; }, Tests.TEST_TIMEOUT);
+    };
+
+    it("filetransfer.spec.1 should exist and be constructable", function() {
+        var ft = new FileTransfer();
+        expect(ft).toBeDefined();
+    });
+    it("filetransfer.spec.2 should contain proper functions", function() {
+        var ft = new FileTransfer();
+        expect(typeof ft.upload).toBe('function');
+        expect(typeof ft.download).toBe('function');
+    });
+    describe('FileTransferError', function() {
+        it("filetransfer.spec.3 FileTransferError constants should be defined", function() {
+            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBe(1);
+            expect(FileTransferError.INVALID_URL_ERR).toBe(2);
+            expect(FileTransferError.CONNECTION_ERR).toBe(3);
+        });
+    });
+
+    describe('download method', function() {
+
+        // NOTE: if download tests are failing, check the white list
+        //
+        //   <access origin="httpssss://example.com"/>
+        //   <access origin="apache.org" subdomains="true" />
+        //   <access origin="cordova-filetransfer.jitsu.com"/>
+
+        it("filetransfer.spec.4 should be able to download a file using http", function() {
+            var fail = createDoNotCallSpy('downloadFail');
+            var fileFail = createDoNotCallSpy('downloadFail');
+            var remoteFile = server + "/robots.txt"
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var lastProgressEvent = null;
+
+            var fileWin = jasmine.createSpy().andCallFake(function(blob) {
+                expect(lastProgressEvent.loaded).not.toBeGreaterThan(blob.size);
+            });
+
+            var downloadWin = function(entry) {
+                expect(entry.name).toBe(localFileName);
+                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
+                if (lastProgressEvent.lengthComputable) {
+                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+                } else {
+                    expect(lastProgressEvent.total).toBe(0);
+                }
+                entry.file(fileWin, fileFail);
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.onprogress = function(e) {
+                    lastProgressEvent = e;
+                };
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
+            });
+
+            waitsForAny(fileWin, fail, fileFail);
+        });
+        it("filetransfer.spec.5 should be able to download a file using http basic auth", function() {
+            var fail = createDoNotCallSpy('downloadFail');
+            var remoteFile = server_with_credentials + "/download_basic_auth"
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var lastProgressEvent = null;
+
+            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
+                expect(entry.name).toBe(localFileName);
+                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
+                if (lastProgressEvent.lengthComputable) {
+                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+                } else {
+                    expect(lastProgressEvent.total).toBe(0);
+                }
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.onprogress = function(e) {
+                    lastProgressEvent = e;
+                };
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
+            });
+
+            waitsForAny(downloadWin, fail);
+        });
+        it("filetransfer.spec.6 should get http status on basic auth failure", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+
+            var remoteFile = server + "/download_basic_auth";
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.http_status).toBe(401);
+                expect(error.http_status).not.toBe(404, "Ensure " + remoteFile + " is in the white list");
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });        
+        it("filetransfer.spec.7 should be able to download a file using file:// (when hosted from file://)", function() {
+            var fail = createDoNotCallSpy('downloadFail');
+            var remoteFile = window.location.href.replace(/\?.*/, '').replace(/ /g, '%20');
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var lastProgressEvent = null;
+
+            if (!/^file/.exec(remoteFile) && cordova.platformId !== 'blackberry10') {
+                expect(remoteFile).toMatch(/^file:/);
+                return;
+            }
+
+            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
+                expect(entry.name).toBe(localFileName);
+                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
+                if (lastProgressEvent.lengthComputable) {
+                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+                } else {
+                    expect(lastProgressEvent.total).toBe(0);
+                }
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+
+            var ft = new FileTransfer();
+            ft.onprogress = function(e) {
+                lastProgressEvent = e;
+            };
+            ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
+
+            waitsForAny(downloadWin, fail);
+        });
+        it("filetransfer.spec.8 should be able to download a file using https", function() {
+            var remoteFile = "https://www.apache.org/licenses/";
+            var localFileName = 'httpstest.html';
+            var downloadFail = createDoNotCallSpy('downloadFail', 'Ensure ' + remoteFile + ' is in the white-list');
+            var fileFail = createDoNotCallSpy('fileFail');
+            var lastProgressEvent = null;
+            var downloadWin = function(entry) {
+                readFileEntry(entry, fileWin, fileFail);
+            };
+            var fileWin = jasmine.createSpy().andCallFake(function(content) {
+                expect(content).toMatch(/The Apache Software Foundation/);
+                expect(lastProgressEvent.loaded).not.toBeGreaterThan(content.length);
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+
+            var ft = new FileTransfer();
+            ft.onprogress = function(e) {
+                lastProgressEvent = e;
+            };
+            ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+
+            waitsForAny(fileWin, downloadFail, fileFail);
+        });
+        it("filetransfer.spec.9 should not leave partial file due to abort", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+            var remoteFile = 'http://cordova.apache.org/downloads/logos_2.zip';
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var startTime = +new Date();
+
+            var downloadFail = jasmine.createSpy().andCallFake(function(e) {
+                expect(e.code).toBe(FileTransferError.ABORT_ERR);
+                var didNotExistSpy = jasmine.createSpy();
+                var existedSpy = createDoNotCallSpy('file existed after abort');
+                root.getFile(localFileName, null, existedSpy, didNotExistSpy);
+                waitsForAny(didNotExistSpy, existedSpy);
+            });
+
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.onprogress = function(e) {
+                    if (e.loaded > 0) {
+                        ft.abort();
+                    }
+                };
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });
+        it("filetransfer.spec.10 should be stopped by abort() right away", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+            var remoteFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var startTime = +new Date();
+
+            var downloadFail = jasmine.createSpy().andCallFake(function(e) {
+                expect(e.code).toBe(FileTransferError.ABORT_ERR);
+                expect(new Date() - startTime).toBeLessThan(300);
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.abort(); // should be a no-op.
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+                ft.abort();
+                ft.abort(); // should be a no-op.
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });
+        it("filetransfer.spec.11 should call the error callback on abort()", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+           var downloadFail = jasmine.createSpy().andCallFake(function(e) { console.log("Abort called") });
+            var remoteFile = 'http://cordova.apache.org/downloads/BlueZedEx.mp3';
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var startTime = +new Date();
+                
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.abort(); // should be a no-op.
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+                ft.abort();
+                ft.abort(); // should be a no-op.
+            });
+                
+            waitsForAny(downloadFail);
+        });
+        it("filetransfer.spec.12 should get http status on failure", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+
+            var remoteFile = server + "/404";
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.http_status).toBe(404);
+                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });
+        it("filetransfer.spec.13 should get response body on failure", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+
+            var remoteFile = server + "/404";
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.body).toBeDefined();
+                expect(error.body).toMatch('You requested a 404');
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });
+        it("filetransfer.spec.14 should handle malformed urls", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+
+            var remoteFile = getMalformedUrl();
+            var localFileName = "download_malformed_url.txt";
+            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
+                // Note: Android needs the bad protocol to be added to the access list
+                // <access origin=".*"/> won't match because ^https?:// is prepended to the regex
+                // The bad protocol must begin with http to avoid automatic prefix
+                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
+                expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });
+        it("filetransfer.spec.15 should handle unknown host", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+
+            var remoteFile = "http://foobar.apache.org/index.html";
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
+            });
+
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });
+        it("filetransfer.spec.16 should handle bad file path", function() {
+            var downloadWin = createDoNotCallSpy('downloadWin');
+
+            var remoteFile = server;
+            var badFilePath = "c:\\54321";
+            var downloadFail = jasmine.createSpy();
+
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.download(remoteFile, badFilePath, downloadWin, downloadFail);
+            });
+
+            waitsForAny(downloadWin, downloadFail);
+        });
+        it("filetransfer.spec.17 progress should work with gzip encoding", function() {
+
+           //lengthComputable false on bb10 when downloading gzip 
+           if (cordova.platformId === 'blackberry10') {
+                return;
+           }
+
+           var downloadFail = createDoNotCallSpy('downloadFail');
+           var remoteFile = "http://www.apache.org/";
+           var localFileName = "index.html";
+           var lastProgressEvent = null;
+           
+           var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
+               expect(entry.name).toBe(localFileName);
+               expect(lastProgressEvent.loaded).toBeGreaterThan(1, 'loaded');
+               expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+               expect(lastProgressEvent.lengthComputable).toBe(true, 'lengthComputable');
+           });
+
+           this.after(function() {
+                      deleteFile(localFileName);
+                      });
+           runs(function() {
+               var ft = new FileTransfer();
+               ft.onprogress = function(e) {
+                   lastProgressEvent = e;
+               };
+               ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, downloadFail);
+           });
+           waitsForAny(downloadWin, downloadFail);
+        });
+    });
+    describe('upload method', function() {
+        it("filetransfer.spec.18 should be able to upload a file", function() {
+            var remoteFile = server + "/upload";
+            var localFileName = "upload.txt";
+            var fileContents = 'This file should upload';
+
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
+            var lastProgressEvent = null;
+
+            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
+                expect(uploadResult.bytesSent).toBeGreaterThan(0);
+                expect(uploadResult.responseCode).toBe(200);
+                var obj = null;
+                try {
+                    obj = JSON.parse(uploadResult.response);
+                    expect(obj.fields).toBeDefined();
+                    expect(obj.fields.value1).toBe("test");
+                    expect(obj.fields.value2).toBe("param");
+                } catch (e) {
+                    expect(obj).not.toBeNull('returned data from server should be valid json');
+                }
+                expect(lastProgressEvent).not.toBeNull('expected progress events');
+                if (cordova.platformId == 'ios') {
+                    expect(uploadResult.headers && uploadResult.headers['Content-Type']).toBeDefined('Expected content-type header to be defined.');
+                }
+            });
+
+            var fileWin = function(fileEntry) {
+                ft = new FileTransfer();
+
+                var options = new FileUploadOptions();
+                options.fileKey = "file";
+                options.fileName = localFileName;
+                options.mimeType = "text/plain";
+
+                var params = new Object();
+                params.value1 = "test";
+                params.value2 = "param";
+                options.params = params;
+
+                ft.onprogress = function(e) {
+                    lastProgressEvent = e;
+                    expect(e.lengthComputable).toBe(true);
+                    expect(e.total).toBeGreaterThan(0);
+                    expect(e.loaded).toBeGreaterThan(0);
+                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+                };
+
+                // removing options cause Android to timeout
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, fileContents, fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail);
+        });
+        it("filetransfer.spec.19 should be able to upload a file with http basic auth", function() {
+            var remoteFile = server_with_credentials + "/upload_basic_auth";
+            var localFileName = "upload.txt";
+            var fileContents = 'This file should upload';
+
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
+            var lastProgressEvent = null;
+
+            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
+                expect(uploadResult.bytesSent).toBeGreaterThan(0);
+                expect(uploadResult.responseCode).toBe(200);
+                var obj = null;
+                try {
+                    obj = JSON.parse(uploadResult.response);
+                    expect(obj.fields).toBeDefined();
+                    expect(obj.fields.value1).toBe("test");
+                    expect(obj.fields.value2).toBe("param");
+                } catch (e) {
+                    expect(obj).not.toBeNull('returned data from server should be valid json');
+                }
+            });
+
+            var fileWin = function(fileEntry) {
+                ft = new FileTransfer();
+
+                var options = new FileUploadOptions();
+                options.fileKey = "file";
+                options.fileName = localFileName;
+                options.mimeType = "text/plain";
+
+                var params = new Object();
+                params.value1 = "test";
+                params.value2 = "param";
+                options.params = params;
+
+                ft.onprogress = function(e) {
+                    expect(e.lengthComputable).toBe(true);
+                    expect(e.total).toBeGreaterThan(0);
+                    expect(e.loaded).toBeGreaterThan(0);
+                    lastProgressEvent = e;
+                };
+
+                // removing options cause Android to timeout
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, fileContents, fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail);
+            runs(function() {
+                expect(lastProgressEvent).not.toBeNull('expected progress events');
+                expect(lastProgressEvent.loaded).toBeGreaterThan(1, 'loaded');
+                expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+            });
+        });
+        it("filetransfer.spec.6 should get http status on basic auth failure", function() {
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadWin = createDoNotCallSpy('uploadWin');
+
+            var remoteFile = server + "/upload_basic_auth";
+            var localFileName = "upload_expect_fail.txt";
+            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.http_status).toBe(401);
+                expect(error.http_status).not.toBe(404, "Ensure " + remoteFile + " is in the white list");
+            });
+
+            var fileWin = function(fileEntry) {
+                var ft = new FileTransfer();
+
+                var options = new FileUploadOptions();
+                options.fileKey="file";
+                options.fileName=fileEntry.name;
+                options.mimeType="text/plain";
+
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, "this file should fail to upload", fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail);
+        });
+        it("filetransfer.spec.21 should be stopped by abort() right away.", function() {
+            var remoteFile = server + "/upload";
+            var localFileName = "upload.txt";
+
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadWin = createDoNotCallSpy('uploadWin', 'Should have been aborted');
+            var startTime;
+
+            var uploadFail = jasmine.createSpy().andCallFake(function(e) {
+                expect(e.code).toBe(FileTransferError.ABORT_ERR);
+                expect(new Date() - startTime).toBeLessThan(300);
+            });
+
+            var fileWin = function(fileEntry) {
+                ft = new FileTransfer();
+
+                var options = new FileUploadOptions();
+                options.fileKey = "file";
+                options.fileName = localFileName;
+                options.mimeType = "text/plain";
+
+                startTime = +new Date();
+                // removing options cause Android to timeout
+                ft.abort(); // should be a no-op.
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
+                ft.abort();
+                ft.abort(); // should be a no-op.
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, new Array(10000).join('aborttest!'), fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail);
+        });
+        it("filetransfer.spec.12 should get http status on failure", function() {
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadWin = createDoNotCallSpy('uploadWin');
+
+            var remoteFile = server + "/403";
+            var localFileName = "upload_expect_fail.txt";
+            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.http_status).toBe(403);
+                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
+            });
+
+            var fileWin = function(fileEntry) {
+                var ft = new FileTransfer();
+
+                var options = new FileUploadOptions();
+                options.fileKey="file";
+                options.fileName=fileEntry.name;
+                options.mimeType="text/plain";
+
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, "this file should fail to upload", fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail);
+        });
+        it("filetransfer.spec.14 should handle malformed urls", function() {
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadWin = createDoNotCallSpy('uploadWin');
+
+            var remoteFile = getMalformedUrl();
+            var localFileName = "malformed_url.txt";
+            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
+                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
+            });
+            var fileWin = function(fileEntry) {
+                var ft = new FileTransfer();
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, {});
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, "Some content", fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail);
+        });
+        it("filetransfer.spec.15 should handle unknown host", function() {
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadWin = createDoNotCallSpy('uploadWin');
+
+            var remoteFile = "http://foobar.apache.org/robots.txt";
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
+                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
+            });
+            var fileWin = function(fileEntry) {
+                var ft = new FileTransfer();
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, {});
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, "# allow all", fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail);
+        });
+        it("filetransfer.spec.25 should handle missing file", function() {
+            var uploadWin = createDoNotCallSpy('uploadWin');
+
+            var remoteFile = server + "/upload";
+            var localFileName = "does_not_exist.txt";
+
+            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
+                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
+            });
+
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.upload(root.toURL() + "/" + localFileName, remoteFile, uploadWin, uploadFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail);
+        });
+        it("filetransfer.spec.16 should handle bad file path", function() {
+            var uploadWin = createDoNotCallSpy('uploadWin');
+
+            var remoteFile = server + "/upload";
+
+            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
+                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
+            });
+
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.upload("/usr/local/bad/file/path.txt", remoteFile, uploadWin, uploadFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail);
+        });
+        it("filetransfer.spec.27 should be able to set custom headers", function() {
+            var remoteFile = "http://whatheaders.com";
+            var localFileName = "upload.txt";
+
+            var fileFail = function() {};
+            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list and that Content-Length header is being set.");
+
+            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
+                expect(uploadResult.bytesSent).toBeGreaterThan(0);
+                expect(uploadResult.responseCode).toBe(200);
+                expect(uploadResult.response).toBeDefined();
+                var responseHtml = decodeURIComponent(uploadResult.response);
+                expect(responseHtml).toMatch(/CustomHeader1[\s\S]*CustomValue1/i);
+                expect(responseHtml).toMatch(/CustomHeader2[\s\S]*CustomValue2[\s\S]*CustomValue3/i, "Should allow array values");
+            });
+
+            var fileWin = function(fileEntry) {
+                ft = new FileTransfer();
+
+                var options = new FileUploadOptions();
+                options.fileKey = "file";
+                options.fileName = localFileName;
+                options.mimeType = "text/plain";
+
+                var params = new Object();
+                params.value1 = "test";
+                params.value2 = "param";
+                options.params = params;
+                options.headers = {
+                    "CustomHeader1": "CustomValue1",
+                    "CustomHeader2": ["CustomValue2", "CustomValue3"],
+                };
+
+                // removing options cause Android to timeout
+                ft.upload(fileEntry.toURL(), remoteFile, uploadWin, uploadFail, options);
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, "this file should upload", fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail);
+        });
+    });
+    describe('Backwards compatibility', function() {
+        /* These specs exist to test that the previously supported API still works with
+         * the new version of file-transfer.
+         * They rely on an undocumented interface to File which provides absolute file
+         * paths, which are not used internally anymore.
+         * If that interface is not present, then these tests will silently succeed.
+         */
+        it("filetransfer.spec.28 should be able to download a file using local paths", function() {
+            var fail = createDoNotCallSpy('downloadFail');
+            var remoteFile = server + "/robots.txt"
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
+            var localURL = root.toURL() + "/" + localFileName;
+            var lastProgressEvent = null;
+
+            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
+                expect(entry.name).toBe(localFileName);
+                expect(lastProgressEvent.loaded).toBeGreaterThan(1);
+            });
+            var unsupportedOperation = jasmine.createSpy("Operation not supported");
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                /* This is an undocumented interface to File which exists only for testing
+                 * backwards compatibilty. By obtaining the raw filesystem path of the download
+                 * location, we can pass that to ft.download() to make sure that previously-stored
+                 * paths are still valid.
+                 */
+                cordova.exec(function(localPath) {
+                    var ft = new FileTransfer();
+                    ft.onprogress = function(e) {
+                        lastProgressEvent = e;
+                        if (lastProgressEvent.lengthComputable) {
+                            expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+                        } else {
+                            expect(lastProgressEvent.total).toBe(0);
+                        }
+                    };
+                    ft.download(remoteFile, localPath, downloadWin, fail);
+                }, unsupportedOperation, 'File', '_getLocalFilesystemPath', [localURL]);
+            });
+
+            waitsForAny(downloadWin, fail, unsupportedOperation);
+        });
+        it("filetransfer.spec.29 should be able to upload a file using local paths", function() {
+            var remoteFile = server + "/upload";
+            var localFileName = "upload.txt";
+            var fileContents = 'This file should upload';
+
+            var fileFail = createDoNotCallSpy('fileFail');
+            var uploadFail = createDoNotCallSpy('uploadFail', "Ensure " + remoteFile + " is in the white list");
+            var unsupportedOperation = jasmine.createSpy("Operation not supported");
+            var lastProgressEvent = null;
+
+            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
+                expect(uploadResult.bytesSent).toBeGreaterThan(0);
+                expect(uploadResult.responseCode).toBe(200);
+                var obj = null;
+                try {
+                    obj = JSON.parse(uploadResult.response);
+                    expect(obj.fields).toBeDefined();
+                    expect(obj.fields.value1).toBe("test");
+                    expect(obj.fields.value2).toBe("param");
+                } catch (e) {
+                    expect(obj).not.toBeNull('returned data from server should be valid json');
+                }
+            });
+
+            var fileWin = function(fileEntry) {
+                ft = new FileTransfer();
+
+                var options = new FileUploadOptions();
+                options.fileKey = "file";
+                options.fileName = localFileName;
+                options.mimeType = "text/plain";
+
+                var params = new Object();
+                params.value1 = "test";
+                params.value2 = "param";
+                options.params = params;
+
+                ft.onprogress = function(e) {
+                    expect(e.lengthComputable).toBe(true);
+                    expect(e.total).toBeGreaterThan(0);
+                    expect(e.loaded).toBeGreaterThan(0);
+                    lastProgressEvent = e;
+                };
+
+                // removing options cause Android to timeout
+
+                /* This is an undocumented interface to File which exists only for testing
+                 * backwards compatibilty. By obtaining the raw filesystem path of the download
+                 * location, we can pass that to ft.download() to make sure that previously-stored
+                 * paths are still valid.
+                 */
+                cordova.exec(function(localPath) {
+                    ft.upload(localPath, remoteFile, uploadWin, uploadFail, options);
+                }, unsupportedOperation, 'File', '_getLocalFilesystemPath', [fileEntry.toURL()]);
+
+            };
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                writeFile(localFileName, fileContents, fileWin, fileFail);
+            });
+
+            waitsForAny(uploadWin, uploadFail, fileFail, unsupportedOperation);
+            runs(function() {
+                if (!unsupportedOperation.wasCalled) {
+                    expect(lastProgressEvent).not.toBeNull('expected progress events');
+                    expect(lastProgressEvent.loaded).toBeGreaterThan(1);
+                    expect(lastProgressEvent.total).not.toBeLessThan(lastProgressEvent.loaded);
+                }
+            });
+        });
+    });
+    describe('native URL interface', function() {
+        it("filetransfer.spec.30 downloaded file entries should have a toNativeURL method", function() {
+            var fail = createDoNotCallSpy('downloadFail');
+            var remoteFile = server + "/robots.txt";
+            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1)+".spec30";
+
+            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
+                expect(entry.toNativeURL).toBeDefined();
+                expect(typeof entry.toNativeURL).toBe("function");
+                var nativeURL = entry.toNativeURL();
+                expect(typeof nativeURL).toBe("string");
+                expect(nativeURL.substring(0,7)).toBe('file://');
+            });
+
+            this.after(function() {
+                deleteFile(localFileName);
+            });
+            runs(function() {
+                var ft = new FileTransfer();
+                ft.download(remoteFile, root.toURL() + "/" + localFileName, downloadWin, fail);
+            });
+
+            waitsForAny(downloadWin, fail);
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/geolocation.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/geolocation.tests.js b/www/autotest/tests/geolocation.tests.js
new file mode 100644
index 0000000..bdb0b53
--- /dev/null
+++ b/www/autotest/tests/geolocation.tests.js
@@ -0,0 +1,160 @@
+/*
+ *
+ * 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('Geolocation (navigator.geolocation)', function () {
+    it("geolocation.spec.1 should exist", function() {
+        expect(navigator.geolocation).toBeDefined();
+    });
+
+    it("geolocation.spec.2 should contain a getCurrentPosition function", function() {
+        expect(typeof navigator.geolocation.getCurrentPosition).toBeDefined();
+        expect(typeof navigator.geolocation.getCurrentPosition == 'function').toBe(true);
+    });
+
+    it("geolocation.spec.3 should contain a watchPosition function", function() {
+        expect(typeof navigator.geolocation.watchPosition).toBeDefined();
+        expect(typeof navigator.geolocation.watchPosition == 'function').toBe(true);
+    });
+
+    it("geolocation.spec.4 should contain a clearWatch function", function() {
+        expect(typeof navigator.geolocation.clearWatch).toBeDefined();
+        expect(typeof navigator.geolocation.clearWatch == 'function').toBe(true);
+    });
+
+    describe('getCurrentPosition method', function() {
+        // this api requires manual user confirmation on windows8 so skip it
+        if (cordova.platformId == 'windows8') return;
+        
+        describe('error callback', function() {
+            it("geolocation.spec.5 should be called if we set timeout to 0 and maximumAge to a very small number", function() {
+                console.log("Here I am");
+                var win = jasmine.createSpy(),
+                    fail = jasmine.createSpy();
+
+                runs(function () {
+                    navigator.geolocation.getCurrentPosition(win, fail, {
+                        maximumAge: 0,
+                        timeout: 0
+                    });
+                });
+
+                waitsFor(function () { return fail.wasCalled; }, "fail never called", 250); //small timeout as this should fire very fast
+
+                runs(function () {
+                    expect(win).not.toHaveBeenCalled();
+                });
+            });
+        });
+
+        describe('success callback', function() {
+            it("geolocation.spec.6 should be called with a Position object", function() {
+                var providerAvailable=true;
+                var win = jasmine.createSpy().andCallFake(function(p) {
+                          expect(p.coords).toBeDefined();
+                          expect(p.timestamp).toBeDefined();
+                      }),
+                      fail = jasmine.createSpy().andCallFake(function(e) {
+                          if(e.code == 2) {
+                              providerAvailable=false;
+                          }
+                      });
+
+                runs(function () {
+                    navigator.geolocation.getCurrentPosition(win, fail, {
+                        maximumAge:300000 // 5 minutes maximum age of cached position
+                    });
+                });
+
+                waitsFor(function () { return (win.wasCalled || fail.wasCalled); }, "win/fail never called", 20000);
+
+                runs(function () {
+                    if(providerAvailable) {
+                        expect(fail).not.toHaveBeenCalled();
+                    }
+                });
+            });
+        });
+    });
+
+    describe('watchPosition method', function() {
+        // this api requires manual user confirmation on windows8 so skip it
+        if (cordova.platformId == 'windows8') return;
+        
+        describe('error callback', function() {
+            var errorWatch = null;
+
+            afterEach(function() {
+                navigator.geolocation.clearWatch(errorWatch);
+            });
+            it("geolocation.spec.7 should be called if we set timeout to 0 and maximumAge to a very small number", function() {
+                var win = jasmine.createSpy(),
+                    fail = jasmine.createSpy();
+
+                runs(function () {
+                    errorWatch = navigator.geolocation.watchPosition(win, fail, {
+                        maximumAge: 0,
+                        timeout: 0
+                    });
+                });
+
+                waitsFor(function () { return fail.wasCalled; }, "fail never called", 250); // small timeout as this should fire very quickly
+
+                runs(function () {
+                    expect(win).not.toHaveBeenCalled();
+                });
+            });
+        });
+
+        describe('success callback', function() {
+            var successWatch = null;
+ 
+            afterEach(function() {
+                navigator.geolocation.clearWatch(successWatch);
+            });
+            it("geolocation.spec.8 should be called with a Position object", function() {
+                var providerAvailable=true;
+                var win = jasmine.createSpy().andCallFake(function(p) {
+                          expect(p.coords).toBeDefined();
+                          expect(p.timestamp).toBeDefined();
+                      }),
+                      fail = jasmine.createSpy().andCallFake(function(e) {
+                          if(e.code ==2) {
+                              providerAvailable=false;
+                          }
+                      });
+
+                runs(function () {
+                    successWatch = navigator.geolocation.watchPosition(win, fail, {
+                        maximumAge:(5 * 60 * 1000) // 5 minutes maximum age of cached position
+                    });
+                });
+
+                waitsFor(function () { return (win.wasCalled || fail.wasCalled); }, "win/fail never called", 20000);
+
+                runs(function () {
+                    if(providerAvailable) {
+                        expect(fail).not.toHaveBeenCalled();
+                    }
+                });
+            });
+        });
+    });
+});


[09/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/jasmine.js
----------------------------------------------------------------------
diff --git a/www/autotest/jasmine.js b/www/autotest/jasmine.js
new file mode 100644
index 0000000..bccb66c
--- /dev/null
+++ b/www/autotest/jasmine.js
@@ -0,0 +1,2530 @@
+var isCommonJS = typeof window == "undefined";
+
+/**
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
+ *
+ * @namespace
+ */
+var jasmine = {};
+if (isCommonJS) exports.jasmine = jasmine;
+/**
+ * @private
+ */
+jasmine.unimplementedMethod_ = function() {
+  throw new Error("unimplemented method");
+};
+
+/**
+ * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
+ * a plain old variable and may be redefined by somebody else.
+ *
+ * @private
+ */
+jasmine.undefined = jasmine.___undefined___;
+
+/**
+ * Show diagnostic messages in the console if set to true
+ *
+ */
+jasmine.VERBOSE = false;
+
+/**
+ * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
+ *
+ */
+jasmine.DEFAULT_UPDATE_INTERVAL = 250;
+
+/**
+ * Default timeout interval in milliseconds for waitsFor() blocks.
+ */
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
+
+jasmine.getGlobal = function() {
+  function getGlobal() {
+    return this;
+  }
+
+  return getGlobal();
+};
+
+/**
+ * Allows for bound functions to be compared.  Internal use only.
+ *
+ * @ignore
+ * @private
+ * @param base {Object} bound 'this' for the function
+ * @param name {Function} function to find
+ */
+jasmine.bindOriginal_ = function(base, name) {
+  var original = base[name];
+  if (original.apply) {
+    return function() {
+      return original.apply(base, arguments);
+    };
+  } else {
+    // IE support
+    return jasmine.getGlobal()[name];
+  }
+};
+
+jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
+jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
+jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
+jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
+
+jasmine.MessageResult = function(values) {
+  this.type = 'log';
+  this.values = values;
+  this.trace = new Error(); // todo: test better
+};
+
+jasmine.MessageResult.prototype.toString = function() {
+  var text = "";
+  for (var i = 0; i < this.values.length; i++) {
+    if (i > 0) text += " ";
+    if (jasmine.isString_(this.values[i])) {
+      text += this.values[i];
+    } else {
+      text += jasmine.pp(this.values[i]);
+    }
+  }
+  return text;
+};
+
+jasmine.ExpectationResult = function(params) {
+  this.type = 'expect';
+  this.matcherName = params.matcherName;
+  this.passed_ = params.passed;
+  this.expected = params.expected;
+  this.actual = params.actual;
+  this.message = this.passed_ ? 'Passed.' : params.message;
+
+  var trace = (params.trace || new Error(this.message));
+  this.trace = this.passed_ ? '' : trace;
+};
+
+jasmine.ExpectationResult.prototype.toString = function () {
+  return this.message;
+};
+
+jasmine.ExpectationResult.prototype.passed = function () {
+  return this.passed_;
+};
+
+/**
+ * Getter for the Jasmine environment. Ensures one gets created
+ */
+jasmine.getEnv = function() {
+  var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
+  return env;
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isArray_ = function(value) {
+  return jasmine.isA_("Array", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isString_ = function(value) {
+  return jasmine.isA_("String", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isNumber_ = function(value) {
+  return jasmine.isA_("Number", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param {String} typeName
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isA_ = function(typeName, value) {
+  return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
+};
+
+/**
+ * Pretty printer for expecations.  Takes any object and turns it into a human-readable string.
+ *
+ * @param value {Object} an object to be outputted
+ * @returns {String}
+ */
+jasmine.pp = function(value) {
+  var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
+  stringPrettyPrinter.format(value);
+  return stringPrettyPrinter.string;
+};
+
+/**
+ * Returns true if the object is a DOM Node.
+ *
+ * @param {Object} obj object to check
+ * @returns {Boolean}
+ */
+jasmine.isDomNode = function(obj) {
+  return obj.nodeType > 0;
+};
+
+/**
+ * Returns a matchable 'generic' object of the class type.  For use in expecations of type when values don't matter.
+ *
+ * @example
+ * // don't care about which function is passed in, as long as it's a function
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
+ *
+ * @param {Class} clazz
+ * @returns matchable object of the type clazz
+ */
+jasmine.any = function(clazz) {
+  return new jasmine.Matchers.Any(clazz);
+};
+
+/**
+ * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
+ * attributes on the object.
+ *
+ * @example
+ * // don't care about any other attributes than foo.
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
+ *
+ * @param sample {Object} sample
+ * @returns matchable object for the sample
+ */
+jasmine.objectContaining = function (sample) {
+    return new jasmine.Matchers.ObjectContaining(sample);
+};
+
+/**
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
+ *
+ * Spies should be created in test setup, before expectations.  They can then be checked, using the standard Jasmine
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
+ *
+ * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
+ *
+ * Spies are torn down at the end of every spec.
+ *
+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
+ *
+ * @example
+ * // a stub
+ * var myStub = jasmine.createSpy('myStub');  // can be used anywhere
+ *
+ * // spy example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ *
+ * // actual foo.not will not be called, execution stops
+ * spyOn(foo, 'not');
+
+ // foo.not spied upon, execution will continue to implementation
+ * spyOn(foo, 'not').andCallThrough();
+ *
+ * // fake example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ *
+ * // foo.not(val) will return val
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
+ *
+ * // mock example
+ * foo.not(7 == 7);
+ * expect(foo.not).toHaveBeenCalled();
+ * expect(foo.not).toHaveBeenCalledWith(true);
+ *
+ * @constructor
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
+ * @param {String} name
+ */
+jasmine.Spy = function(name) {
+  /**
+   * The name of the spy, if provided.
+   */
+  this.identity = name || 'unknown';
+  /**
+   *  Is this Object a spy?
+   */
+  this.isSpy = true;
+  /**
+   * The actual function this spy stubs.
+   */
+  this.plan = function() {
+  };
+  /**
+   * Tracking of the most recent call to the spy.
+   * @example
+   * var mySpy = jasmine.createSpy('foo');
+   * mySpy(1, 2);
+   * mySpy.mostRecentCall.args = [1, 2];
+   */
+  this.mostRecentCall = {};
+
+  /**
+   * Holds arguments for each call to the spy, indexed by call count
+   * @example
+   * var mySpy = jasmine.createSpy('foo');
+   * mySpy(1, 2);
+   * mySpy(7, 8);
+   * mySpy.mostRecentCall.args = [7, 8];
+   * mySpy.argsForCall[0] = [1, 2];
+   * mySpy.argsForCall[1] = [7, 8];
+   */
+  this.argsForCall = [];
+  this.calls = [];
+};
+
+/**
+ * Tells a spy to call through to the actual implemenatation.
+ *
+ * @example
+ * var foo = {
+ *   bar: function() { // do some stuff }
+ * }
+ *
+ * // defining a spy on an existing property: foo.bar
+ * spyOn(foo, 'bar').andCallThrough();
+ */
+jasmine.Spy.prototype.andCallThrough = function() {
+  this.plan = this.originalValue;
+  return this;
+};
+
+/**
+ * For setting the return value of a spy.
+ *
+ * @example
+ * // defining a spy from scratch: foo() returns 'baz'
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
+ * spyOn(foo, 'bar').andReturn('baz');
+ *
+ * @param {Object} value
+ */
+jasmine.Spy.prototype.andReturn = function(value) {
+  this.plan = function() {
+    return value;
+  };
+  return this;
+};
+
+/**
+ * For throwing an exception when a spy is called.
+ *
+ * @example
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
+ * spyOn(foo, 'bar').andThrow('baz');
+ *
+ * @param {String} exceptionMsg
+ */
+jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
+  this.plan = function() {
+    throw exceptionMsg;
+  };
+  return this;
+};
+
+/**
+ * Calls an alternate implementation when a spy is called.
+ *
+ * @example
+ * var baz = function() {
+ *   // do some stuff, return something
+ * }
+ * // defining a spy from scratch: foo() calls the function baz
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
+ *
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
+ *
+ * @param {Function} fakeFunc
+ */
+jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
+  this.plan = fakeFunc;
+  return this;
+};
+
+/**
+ * Resets all of a spy's the tracking variables so that it can be used again.
+ *
+ * @example
+ * spyOn(foo, 'bar');
+ *
+ * foo.bar();
+ *
+ * expect(foo.bar.callCount).toEqual(1);
+ *
+ * foo.bar.reset();
+ *
+ * expect(foo.bar.callCount).toEqual(0);
+ */
+jasmine.Spy.prototype.reset = function() {
+  this.wasCalled = false;
+  this.callCount = 0;
+  this.argsForCall = [];
+  this.calls = [];
+  this.mostRecentCall = {};
+};
+
+jasmine.createSpy = function(name) {
+
+  var spyObj = function() {
+    spyObj.wasCalled = true;
+    spyObj.callCount++;
+    var args = jasmine.util.argsToArray(arguments);
+    spyObj.mostRecentCall.object = this;
+    spyObj.mostRecentCall.args = args;
+    spyObj.argsForCall.push(args);
+    spyObj.calls.push({object: this, args: args});
+    return spyObj.plan.apply(this, arguments);
+  };
+
+  var spy = new jasmine.Spy(name);
+
+  for (var prop in spy) {
+    spyObj[prop] = spy[prop];
+  }
+
+  spyObj.reset();
+
+  return spyObj;
+};
+
+/**
+ * Determines whether an object is a spy.
+ *
+ * @param {jasmine.Spy|Object} putativeSpy
+ * @returns {Boolean}
+ */
+jasmine.isSpy = function(putativeSpy) {
+  return putativeSpy && putativeSpy.isSpy;
+};
+
+/**
+ * Creates a more complicated spy: an Object that has every property a function that is a spy.  Used for stubbing something
+ * large in one call.
+ *
+ * @param {String} baseName name of spy class
+ * @param {Array} methodNames array of names of methods to make spies
+ */
+jasmine.createSpyObj = function(baseName, methodNames) {
+  if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
+    throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
+  }
+  var obj = {};
+  for (var i = 0; i < methodNames.length; i++) {
+    obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
+  }
+  return obj;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
+ *
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
+ */
+jasmine.log = function() {
+  var spec = jasmine.getEnv().currentSpec;
+  spec.log.apply(spec, arguments);
+};
+
+/**
+ * Function that installs a spy on an existing object's method name.  Used within a Spec to create a spy.
+ *
+ * @example
+ * // spy example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
+ *
+ * @see jasmine.createSpy
+ * @param obj
+ * @param methodName
+ * @returns a Jasmine spy that can be chained with all spy methods
+ */
+var spyOn = function(obj, methodName) {
+  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
+};
+if (isCommonJS) exports.spyOn = spyOn;
+
+/**
+ * Creates a Jasmine spec that will be added to the current suite.
+ *
+ * // TODO: pending tests
+ *
+ * @example
+ * it('should be true', function() {
+ *   expect(true).toEqual(true);
+ * });
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var it = function(desc, func) {
+  return jasmine.getEnv().it(desc, func);
+};
+if (isCommonJS) exports.it = it;
+
+/**
+ * Creates a <em>disabled</em> Jasmine spec.
+ *
+ * A convenience method that allows existing specs to be disabled temporarily during development.
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var xit = function(desc, func) {
+  return jasmine.getEnv().xit(desc, func);
+};
+if (isCommonJS) exports.xit = xit;
+
+/**
+ * Starts a chain for a Jasmine expectation.
+ *
+ * It is passed an Object that is the actual value and should chain to one of the many
+ * jasmine.Matchers functions.
+ *
+ * @param {Object} actual Actual value to test against and expected value
+ */
+var expect = function(actual) {
+  return jasmine.getEnv().currentSpec.expect(actual);
+};
+if (isCommonJS) exports.expect = expect;
+
+/**
+ * Defines part of a jasmine spec.  Used in cominbination with waits or waitsFor in asynchrnous specs.
+ *
+ * @param {Function} func Function that defines part of a jasmine spec.
+ */
+var runs = function(func) {
+  jasmine.getEnv().currentSpec.runs(func);
+};
+if (isCommonJS) exports.runs = runs;
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+var waits = function(timeout) {
+  jasmine.getEnv().currentSpec.waits(timeout);
+};
+if (isCommonJS) exports.waits = waits;
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
+};
+if (isCommonJS) exports.waitsFor = waitsFor;
+
+/**
+ * A function that is called before each spec in a suite.
+ *
+ * Used for spec setup, including validating assumptions.
+ *
+ * @param {Function} beforeEachFunction
+ */
+var beforeEach = function(beforeEachFunction) {
+  jasmine.getEnv().beforeEach(beforeEachFunction);
+};
+if (isCommonJS) exports.beforeEach = beforeEach;
+
+/**
+ * A function that is called after each spec in a suite.
+ *
+ * Used for restoring any state that is hijacked during spec execution.
+ *
+ * @param {Function} afterEachFunction
+ */
+var afterEach = function(afterEachFunction) {
+  jasmine.getEnv().afterEach(afterEachFunction);
+};
+if (isCommonJS) exports.afterEach = afterEach;
+
+/**
+ * Defines a suite of specifications.
+ *
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
+ * of setup in some tests.
+ *
+ * @example
+ * // TODO: a simple suite
+ *
+ * // TODO: a simple suite with a nested describe block
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var describe = function(description, specDefinitions) {
+  return jasmine.getEnv().describe(description, specDefinitions);
+};
+if (isCommonJS) exports.describe = describe;
+
+/**
+ * Disables a suite of specifications.  Used to disable some suites in a file, or files, temporarily during development.
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var xdescribe = function(description, specDefinitions) {
+  return jasmine.getEnv().xdescribe(description, specDefinitions);
+};
+if (isCommonJS) exports.xdescribe = xdescribe;
+
+
+// Provide the XMLHttpRequest class for IE 5.x-6.x:
+jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
+  function tryIt(f) {
+    try {
+      return f();
+    } catch(e) {
+    }
+    return null;
+  }
+
+  var xhr = tryIt(function() {
+    return new ActiveXObject("Msxml2.XMLHTTP.6.0");
+  }) ||
+    tryIt(function() {
+      return new ActiveXObject("Msxml2.XMLHTTP.3.0");
+    }) ||
+    tryIt(function() {
+      return new ActiveXObject("Msxml2.XMLHTTP");
+    }) ||
+    tryIt(function() {
+      return new ActiveXObject("Microsoft.XMLHTTP");
+    });
+
+  if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
+
+  return xhr;
+} : XMLHttpRequest;
+/**
+ * @namespace
+ */
+jasmine.util = {};
+
+/**
+ * Declare that a child class inherit it's prototype from the parent class.
+ *
+ * @private
+ * @param {Function} childClass
+ * @param {Function} parentClass
+ */
+jasmine.util.inherit = function(childClass, parentClass) {
+  /**
+   * @private
+   */
+  var subclass = function() {
+  };
+  subclass.prototype = parentClass.prototype;
+  childClass.prototype = new subclass();
+};
+
+jasmine.util.formatException = function(e) {
+  var lineNumber;
+  if (e.line) {
+    lineNumber = e.line;
+  }
+  else if (e.lineNumber) {
+    lineNumber = e.lineNumber;
+  }
+
+  var file;
+
+  if (e.sourceURL) {
+    file = e.sourceURL;
+  }
+  else if (e.fileName) {
+    file = e.fileName;
+  }
+
+  var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
+
+  if (file && lineNumber) {
+    message += ' in ' + file + ' (line ' + lineNumber + ')';
+  }
+
+  return message;
+};
+
+jasmine.util.htmlEscape = function(str) {
+  if (!str) return str;
+  return str.replace(/&/g, '&amp;')
+    .replace(/</g, '&lt;')
+    .replace(/>/g, '&gt;');
+};
+
+jasmine.util.argsToArray = function(args) {
+  var arrayOfArgs = [];
+  for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
+  return arrayOfArgs;
+};
+
+jasmine.util.extend = function(destination, source) {
+  for (var property in source) destination[property] = source[property];
+  return destination;
+};
+
+/**
+ * Environment for Jasmine
+ *
+ * @constructor
+ */
+jasmine.Env = function() {
+  this.currentSpec = null;
+  this.currentSuite = null;
+  this.currentRunner_ = new jasmine.Runner(this);
+
+  this.reporter = new jasmine.MultiReporter();
+
+  this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
+  this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+  this.lastUpdate = 0;
+  this.specFilter = function() {
+    return true;
+  };
+
+  this.nextSpecId_ = 0;
+  this.nextSuiteId_ = 0;
+  this.equalityTesters_ = [];
+
+  // wrap matchers
+  this.matchersClass = function() {
+    jasmine.Matchers.apply(this, arguments);
+  };
+  jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
+
+  jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
+};
+
+
+jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
+jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
+jasmine.Env.prototype.setInterval = jasmine.setInterval;
+jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
+
+/**
+ * @returns an object containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.version = function () {
+  if (jasmine.version_) {
+    return jasmine.version_;
+  } else {
+    throw new Error('Version not set');
+  }
+};
+
+/**
+ * @returns string containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.versionString = function() {
+  if (!jasmine.version_) {
+    return "version unknown";
+  }
+
+  var version = this.version();
+  var versionString = version.major + "." + version.minor + "." + version.build;
+  if (version.release_candidate) {
+    versionString += ".rc" + version.release_candidate;
+  }
+  versionString += " revision " + version.revision;
+  return versionString;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSpecId = function () {
+  return this.nextSpecId_++;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSuiteId = function () {
+  return this.nextSuiteId_++;
+};
+
+/**
+ * Register a reporter to receive status updates from Jasmine.
+ * @param {jasmine.Reporter} reporter An object which will receive status updates.
+ */
+jasmine.Env.prototype.addReporter = function(reporter) {
+  this.reporter.addReporter(reporter);
+};
+
+jasmine.Env.prototype.execute = function() {
+  this.currentRunner_.execute();
+};
+
+jasmine.Env.prototype.describe = function(description, specDefinitions) {
+  var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
+
+  var parentSuite = this.currentSuite;
+  if (parentSuite) {
+    parentSuite.add(suite);
+  } else {
+    this.currentRunner_.add(suite);
+  }
+
+  this.currentSuite = suite;
+
+  var declarationError = null;
+  try {
+    specDefinitions.call(suite);
+  } catch(e) {
+    declarationError = e;
+  }
+
+  if (declarationError) {
+    this.it("encountered a declaration exception", function() {
+      throw declarationError;
+    });
+  }
+
+  this.currentSuite = parentSuite;
+
+  return suite;
+};
+
+jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
+  if (this.currentSuite) {
+    this.currentSuite.beforeEach(beforeEachFunction);
+  } else {
+    this.currentRunner_.beforeEach(beforeEachFunction);
+  }
+};
+
+jasmine.Env.prototype.currentRunner = function () {
+  return this.currentRunner_;
+};
+
+jasmine.Env.prototype.afterEach = function(afterEachFunction) {
+  if (this.currentSuite) {
+    this.currentSuite.afterEach(afterEachFunction);
+  } else {
+    this.currentRunner_.afterEach(afterEachFunction);
+  }
+
+};
+
+jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
+  return {
+    execute: function() {
+    }
+  };
+};
+
+jasmine.Env.prototype.it = function(description, func) {
+  var spec = new jasmine.Spec(this, this.currentSuite, description);
+  this.currentSuite.add(spec);
+  this.currentSpec = spec;
+
+  if (func) {
+    spec.runs(func);
+  }
+
+  return spec;
+};
+
+jasmine.Env.prototype.xit = function(desc, func) {
+  return {
+    id: this.nextSpecId(),
+    runs: function() {
+    }
+  };
+};
+
+jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
+  if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
+    return true;
+  }
+
+  a.__Jasmine_been_here_before__ = b;
+  b.__Jasmine_been_here_before__ = a;
+
+  var hasKey = function(obj, keyName) {
+    return obj !== null && obj[keyName] !== jasmine.undefined;
+  };
+
+  for (var property in b) {
+    if (!hasKey(a, property) && hasKey(b, property)) {
+      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+    }
+  }
+  for (property in a) {
+    if (!hasKey(b, property) && hasKey(a, property)) {
+      mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
+    }
+  }
+  for (property in b) {
+    if (property == '__Jasmine_been_here_before__') continue;
+    if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
+      mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
+    }
+  }
+
+  if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
+    mismatchValues.push("arrays were not the same length");
+  }
+
+  delete a.__Jasmine_been_here_before__;
+  delete b.__Jasmine_been_here_before__;
+  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+};
+
+jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
+  mismatchKeys = mismatchKeys || [];
+  mismatchValues = mismatchValues || [];
+
+  for (var i = 0; i < this.equalityTesters_.length; i++) {
+    var equalityTester = this.equalityTesters_[i];
+    var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
+    if (result !== jasmine.undefined) return result;
+  }
+
+  if (a === b) return true;
+
+  if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
+    return (a == jasmine.undefined && b == jasmine.undefined);
+  }
+
+  if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
+    return a === b;
+  }
+
+  if (a instanceof Date && b instanceof Date) {
+    return a.getTime() == b.getTime();
+  }
+
+  if (a.jasmineMatches) {
+    return a.jasmineMatches(b);
+  }
+
+  if (b.jasmineMatches) {
+    return b.jasmineMatches(a);
+  }
+
+  if (a instanceof jasmine.Matchers.ObjectContaining) {
+    return a.matches(b);
+  }
+
+  if (b instanceof jasmine.Matchers.ObjectContaining) {
+    return b.matches(a);
+  }
+
+  if (jasmine.isString_(a) && jasmine.isString_(b)) {
+    return (a == b);
+  }
+
+  if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
+    return (a == b);
+  }
+
+  if (typeof a === "object" && typeof b === "object") {
+    return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
+  }
+
+  //Straight check
+  return (a === b);
+};
+
+jasmine.Env.prototype.contains_ = function(haystack, needle) {
+  if (jasmine.isArray_(haystack)) {
+    for (var i = 0; i < haystack.length; i++) {
+      if (this.equals_(haystack[i], needle)) return true;
+    }
+    return false;
+  }
+  return haystack.indexOf(needle) >= 0;
+};
+
+jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
+  this.equalityTesters_.push(equalityTester);
+};
+/** No-op base class for Jasmine reporters.
+ *
+ * @constructor
+ */
+jasmine.Reporter = function() {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecResults = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.log = function(str) {
+};
+
+/**
+ * Blocks are functions with executable code that make up a spec.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {Function} func
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Block = function(env, func, spec) {
+  this.env = env;
+  this.func = func;
+  this.spec = spec;
+};
+
+jasmine.Block.prototype.execute = function(onComplete) {  
+  try {
+    this.func.apply(this.spec);
+  } catch (e) {
+    this.spec.fail(e);
+  }
+  onComplete();
+};
+/** JavaScript API reporter.
+ *
+ * @constructor
+ */
+jasmine.JsApiReporter = function() {
+  this.started = false;
+  this.finished = false;
+  this.suites_ = [];
+  this.results_ = {};
+};
+
+jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
+  this.started = true;
+  var suites = runner.topLevelSuites();
+  for (var i = 0; i < suites.length; i++) {
+    var suite = suites[i];
+    this.suites_.push(this.summarize_(suite));
+  }
+};
+
+jasmine.JsApiReporter.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
+  var isSuite = suiteOrSpec instanceof jasmine.Suite;
+  var summary = {
+    id: suiteOrSpec.id,
+    name: suiteOrSpec.description,
+    type: isSuite ? 'suite' : 'spec',
+    children: []
+  };
+  
+  if (isSuite) {
+    var children = suiteOrSpec.children();
+    for (var i = 0; i < children.length; i++) {
+      summary.children.push(this.summarize_(children[i]));
+    }
+  }
+  return summary;
+};
+
+jasmine.JsApiReporter.prototype.results = function() {
+  return this.results_;
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
+  return this.results_[specId];
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
+  this.finished = true;
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
+  this.results_[spec.id] = {
+    messages: spec.results().getItems(),
+    result: spec.results().failedCount > 0 ? "failed" : "passed"
+  };
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.log = function(str) {
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
+  var results = {};
+  for (var i = 0; i < specIds.length; i++) {
+    var specId = specIds[i];
+    results[specId] = this.summarizeResult_(this.results_[specId]);
+  }
+  return results;
+};
+
+jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
+  var summaryMessages = [];
+  var messagesLength = result.messages.length;
+  for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
+    var resultMessage = result.messages[messageIndex];
+    summaryMessages.push({
+      text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
+      passed: resultMessage.passed ? resultMessage.passed() : true,
+      type: resultMessage.type,
+      message: resultMessage.message,
+      trace: {
+        stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
+      }
+    });
+  }
+
+  return {
+    result : result.result,
+    messages : summaryMessages
+  };
+};
+
+/**
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param actual
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Matchers = function(env, actual, spec, opt_isNot) {
+  this.env = env;
+  this.actual = actual;
+  this.spec = spec;
+  this.isNot = opt_isNot || false;
+  this.reportWasCalled_ = false;
+};
+
+// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
+jasmine.Matchers.pp = function(str) {
+  throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
+};
+
+// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
+jasmine.Matchers.prototype.report = function(result, failing_message, details) {
+  throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
+};
+
+jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
+  for (var methodName in prototype) {
+    if (methodName == 'report') continue;
+    var orig = prototype[methodName];
+    matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
+  }
+};
+
+jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
+  return function() {
+    var matcherArgs = jasmine.util.argsToArray(arguments);
+    var result = matcherFunction.apply(this, arguments);
+
+    if (this.isNot) {
+      result = !result;
+    }
+
+    if (this.reportWasCalled_) return result;
+
+    var message;
+    if (!result) {
+      if (this.message) {
+        message = this.message.apply(this, arguments);
+        if (jasmine.isArray_(message)) {
+          message = message[this.isNot ? 1 : 0];
+        }
+      } else {
+        var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
+        message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
+        if (matcherArgs.length > 0) {
+          for (var i = 0; i < matcherArgs.length; i++) {
+            if (i > 0) message += ",";
+            message += " " + jasmine.pp(matcherArgs[i]);
+          }
+        }
+        message += ".";
+      }
+    }
+    var expectationResult = new jasmine.ExpectationResult({
+      matcherName: matcherName,
+      passed: result,
+      expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
+      actual: this.actual,
+      message: message
+    });
+    this.spec.addMatcherResult(expectationResult);
+    return jasmine.undefined;
+  };
+};
+
+
+
+
+/**
+ * toBe: compares the actual to the expected using ===
+ * @param expected
+ */
+jasmine.Matchers.prototype.toBe = function(expected) {
+  return this.actual === expected;
+};
+
+/**
+ * toNotBe: compares the actual to the expected using !==
+ * @param expected
+ * @deprecated as of 1.0. Use not.toBe() instead.
+ */
+jasmine.Matchers.prototype.toNotBe = function(expected) {
+  return this.actual !== expected;
+};
+
+/**
+ * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toEqual = function(expected) {
+  return this.env.equals_(this.actual, expected);
+};
+
+/**
+ * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
+ * @param expected
+ * @deprecated as of 1.0. Use not.toEqual() instead.
+ */
+jasmine.Matchers.prototype.toNotEqual = function(expected) {
+  return !this.env.equals_(this.actual, expected);
+};
+
+/**
+ * Matcher that compares the actual to the expected using a regular expression.  Constructs a RegExp, so takes
+ * a pattern or a String.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toMatch = function(expected) {
+  return new RegExp(expected).test(this.actual);
+};
+
+/**
+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
+ * @param expected
+ * @deprecated as of 1.0. Use not.toMatch() instead.
+ */
+jasmine.Matchers.prototype.toNotMatch = function(expected) {
+  return !(new RegExp(expected).test(this.actual));
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeDefined = function() {
+  return (this.actual !== jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeUndefined = function() {
+  return (this.actual === jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to null.
+ */
+jasmine.Matchers.prototype.toBeNull = function() {
+  return (this.actual === null);
+};
+
+/**
+ * Matcher that boolean not-nots the actual.
+ */
+jasmine.Matchers.prototype.toBeTruthy = function() {
+  return !!this.actual;
+};
+
+
+/**
+ * Matcher that boolean nots the actual.
+ */
+jasmine.Matchers.prototype.toBeFalsy = function() {
+  return !this.actual;
+};
+
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called.
+ */
+jasmine.Matchers.prototype.toHaveBeenCalled = function() {
+  if (arguments.length > 0) {
+    throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
+  }
+
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy " + this.actual.identity + " to have been called.",
+      "Expected spy " + this.actual.identity + " not to have been called."
+    ];
+  };
+
+  return this.actual.wasCalled;
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
+jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was not called.
+ *
+ * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
+ */
+jasmine.Matchers.prototype.wasNotCalled = function() {
+  if (arguments.length > 0) {
+    throw new Error('wasNotCalled does not take arguments');
+  }
+
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy " + this.actual.identity + " to not have been called.",
+      "Expected spy " + this.actual.identity + " to have been called."
+    ];
+  };
+
+  return !this.actual.wasCalled;
+};
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
+ *
+ * @example
+ *
+ */
+jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
+  var expectedArgs = jasmine.util.argsToArray(arguments);
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+  this.message = function() {
+    if (this.actual.callCount === 0) {
+      // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
+      return [
+        "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
+        "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
+      ];
+    } else {
+      return [
+        "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
+        "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
+      ];
+    }
+  };
+
+  return this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
+
+/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasNotCalledWith = function() {
+  var expectedArgs = jasmine.util.argsToArray(arguments);
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
+      "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
+    ];
+  };
+
+  return !this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/**
+ * Matcher that checks that the expected item is an element in the actual Array.
+ *
+ * @param {Object} expected
+ */
+jasmine.Matchers.prototype.toContain = function(expected) {
+  return this.env.contains_(this.actual, expected);
+};
+
+/**
+ * Matcher that checks that the expected item is NOT an element in the actual Array.
+ *
+ * @param {Object} expected
+ * @deprecated as of 1.0. Use not.toContain() instead.
+ */
+jasmine.Matchers.prototype.toNotContain = function(expected) {
+  return !this.env.contains_(this.actual, expected);
+};
+
+jasmine.Matchers.prototype.toBeLessThan = function(expected) {
+  return this.actual < expected;
+};
+
+jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
+  return this.actual > expected;
+};
+
+/**
+ * Matcher that checks that the expected item is equal to the actual item
+ * up to a given level of decimal precision (default 2).
+ *
+ * @param {Number} expected
+ * @param {Number} precision
+ */
+jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
+  if (!(precision === 0)) {
+    precision = precision || 2;
+  }
+  var multiplier = Math.pow(10, precision);
+  var actual = Math.round(this.actual * multiplier);
+  expected = Math.round(expected * multiplier);
+  return expected == actual;
+};
+
+/**
+ * Matcher that checks that the expected exception was thrown by the actual.
+ *
+ * @param {String} expected
+ */
+jasmine.Matchers.prototype.toThrow = function(expected) {
+  var result = false;
+  var exception;
+  if (typeof this.actual != 'function') {
+    throw new Error('Actual is not a function');
+  }
+  try {
+    this.actual();
+  } catch (e) {
+    exception = e;
+  }
+  if (exception) {
+    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
+  }
+
+  var not = this.isNot ? "not " : "";
+
+  this.message = function() {
+    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
+      return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
+    } else {
+      return "Expected function to throw an exception.";
+    }
+  };
+
+  return result;
+};
+
+jasmine.Matchers.Any = function(expectedClass) {
+  this.expectedClass = expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
+  if (this.expectedClass == String) {
+    return typeof other == 'string' || other instanceof String;
+  }
+
+  if (this.expectedClass == Number) {
+    return typeof other == 'number' || other instanceof Number;
+  }
+
+  if (this.expectedClass == Function) {
+    return typeof other == 'function' || other instanceof Function;
+  }
+
+  if (this.expectedClass == Object) {
+    return typeof other == 'object';
+  }
+
+  return other instanceof this.expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.jasmineToString = function() {
+  return '<jasmine.any(' + this.expectedClass + ')>';
+};
+
+jasmine.Matchers.ObjectContaining = function (sample) {
+  this.sample = sample;
+};
+
+jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
+  mismatchKeys = mismatchKeys || [];
+  mismatchValues = mismatchValues || [];
+
+  var env = jasmine.getEnv();
+
+  var hasKey = function(obj, keyName) {
+    return obj != null && obj[keyName] !== jasmine.undefined;
+  };
+
+  for (var property in this.sample) {
+    if (!hasKey(other, property) && hasKey(this.sample, property)) {
+      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+    }
+    else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
+      mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
+    }
+  }
+
+  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+};
+
+jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
+  return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
+};
+// Mock setTimeout, clearTimeout
+// Contributed by Pivotal Computer Systems, www.pivotalsf.com
+
+jasmine.FakeTimer = function() {
+  this.reset();
+
+  var self = this;
+  self.setTimeout = function(funcToCall, millis) {
+    self.timeoutsMade++;
+    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
+    return self.timeoutsMade;
+  };
+
+  self.setInterval = function(funcToCall, millis) {
+    self.timeoutsMade++;
+    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
+    return self.timeoutsMade;
+  };
+
+  self.clearTimeout = function(timeoutKey) {
+    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+  };
+
+  self.clearInterval = function(timeoutKey) {
+    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+  };
+
+};
+
+jasmine.FakeTimer.prototype.reset = function() {
+  this.timeoutsMade = 0;
+  this.scheduledFunctions = {};
+  this.nowMillis = 0;
+};
+
+jasmine.FakeTimer.prototype.tick = function(millis) {
+  var oldMillis = this.nowMillis;
+  var newMillis = oldMillis + millis;
+  this.runFunctionsWithinRange(oldMillis, newMillis);
+  this.nowMillis = newMillis;
+};
+
+jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
+  var scheduledFunc;
+  var funcsToRun = [];
+  for (var timeoutKey in this.scheduledFunctions) {
+    scheduledFunc = this.scheduledFunctions[timeoutKey];
+    if (scheduledFunc != jasmine.undefined &&
+        scheduledFunc.runAtMillis >= oldMillis &&
+        scheduledFunc.runAtMillis <= nowMillis) {
+      funcsToRun.push(scheduledFunc);
+      this.scheduledFunctions[timeoutKey] = jasmine.undefined;
+    }
+  }
+
+  if (funcsToRun.length > 0) {
+    funcsToRun.sort(function(a, b) {
+      return a.runAtMillis - b.runAtMillis;
+    });
+    for (var i = 0; i < funcsToRun.length; ++i) {
+      try {
+        var funcToRun = funcsToRun[i];
+        this.nowMillis = funcToRun.runAtMillis;
+        funcToRun.funcToCall();
+        if (funcToRun.recurring) {
+          this.scheduleFunction(funcToRun.timeoutKey,
+              funcToRun.funcToCall,
+              funcToRun.millis,
+              true);
+        }
+      } catch(e) {
+      }
+    }
+    this.runFunctionsWithinRange(oldMillis, nowMillis);
+  }
+};
+
+jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
+  this.scheduledFunctions[timeoutKey] = {
+    runAtMillis: this.nowMillis + millis,
+    funcToCall: funcToCall,
+    recurring: recurring,
+    timeoutKey: timeoutKey,
+    millis: millis
+  };
+};
+
+/**
+ * @namespace
+ */
+jasmine.Clock = {
+  defaultFakeTimer: new jasmine.FakeTimer(),
+
+  reset: function() {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.defaultFakeTimer.reset();
+  },
+
+  tick: function(millis) {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.defaultFakeTimer.tick(millis);
+  },
+
+  runFunctionsWithinRange: function(oldMillis, nowMillis) {
+    jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
+  },
+
+  scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
+    jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
+  },
+
+  useMock: function() {
+    if (!jasmine.Clock.isInstalled()) {
+      var spec = jasmine.getEnv().currentSpec;
+      spec.after(jasmine.Clock.uninstallMock);
+
+      jasmine.Clock.installMock();
+    }
+  },
+
+  installMock: function() {
+    jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
+  },
+
+  uninstallMock: function() {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.installed = jasmine.Clock.real;
+  },
+
+  real: {
+    setTimeout: jasmine.getGlobal().setTimeout,
+    clearTimeout: jasmine.getGlobal().clearTimeout,
+    setInterval: jasmine.getGlobal().setInterval,
+    clearInterval: jasmine.getGlobal().clearInterval
+  },
+
+  assertInstalled: function() {
+    if (!jasmine.Clock.isInstalled()) {
+      throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
+    }
+  },
+
+  isInstalled: function() {
+    return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
+  },
+
+  installed: null
+};
+jasmine.Clock.installed = jasmine.Clock.real;
+
+//else for IE support
+jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
+  if (jasmine.Clock.installed.setTimeout.apply) {
+    return jasmine.Clock.installed.setTimeout.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.setTimeout(funcToCall, millis);
+  }
+};
+
+jasmine.getGlobal().setInterval = function(funcToCall, millis) {
+  if (jasmine.Clock.installed.setInterval.apply) {
+    return jasmine.Clock.installed.setInterval.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.setInterval(funcToCall, millis);
+  }
+};
+
+jasmine.getGlobal().clearTimeout = function(timeoutKey) {
+  if (jasmine.Clock.installed.clearTimeout.apply) {
+    return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.clearTimeout(timeoutKey);
+  }
+};
+
+jasmine.getGlobal().clearInterval = function(timeoutKey) {
+  if (jasmine.Clock.installed.clearTimeout.apply) {
+    return jasmine.Clock.installed.clearInterval.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.clearInterval(timeoutKey);
+  }
+};
+
+/**
+ * @constructor
+ */
+jasmine.MultiReporter = function() {
+  this.subReporters_ = [];
+};
+jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
+
+jasmine.MultiReporter.prototype.addReporter = function(reporter) {
+  this.subReporters_.push(reporter);
+};
+
+(function() {
+  var functionNames = [
+    "reportRunnerStarting",
+    "reportRunnerResults",
+    "reportSuiteResults",
+    "reportSpecStarting",
+    "reportSpecResults",
+    "log"
+  ];
+  for (var i = 0; i < functionNames.length; i++) {
+    var functionName = functionNames[i];
+    jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
+      return function() {
+        for (var j = 0; j < this.subReporters_.length; j++) {
+          var subReporter = this.subReporters_[j];
+          if (subReporter[functionName]) {
+            subReporter[functionName].apply(subReporter, arguments);
+          }
+        }
+      };
+    })(functionName);
+  }
+})();
+/**
+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
+ *
+ * @constructor
+ */
+jasmine.NestedResults = function() {
+  /**
+   * The total count of results
+   */
+  this.totalCount = 0;
+  /**
+   * Number of passed results
+   */
+  this.passedCount = 0;
+  /**
+   * Number of failed results
+   */
+  this.failedCount = 0;
+  /**
+   * Was this suite/spec skipped?
+   */
+  this.skipped = false;
+  /**
+   * @ignore
+   */
+  this.items_ = [];
+};
+
+/**
+ * Roll up the result counts.
+ *
+ * @param result
+ */
+jasmine.NestedResults.prototype.rollupCounts = function(result) {
+  this.totalCount += result.totalCount;
+  this.passedCount += result.passedCount;
+  this.failedCount += result.failedCount;
+};
+
+/**
+ * Adds a log message.
+ * @param values Array of message parts which will be concatenated later.
+ */
+jasmine.NestedResults.prototype.log = function(values) {
+  this.items_.push(new jasmine.MessageResult(values));
+};
+
+/**
+ * Getter for the results: message & results.
+ */
+jasmine.NestedResults.prototype.getItems = function() {
+  return this.items_;
+};
+
+/**
+ * Adds a result, tracking counts (total, passed, & failed)
+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
+ */
+jasmine.NestedResults.prototype.addResult = function(result) {
+  if (result.type != 'log') {
+    if (result.items_) {
+      this.rollupCounts(result);
+    } else {
+      this.totalCount++;
+      if (result.passed()) {
+        this.passedCount++;
+      } else {
+        this.failedCount++;
+      }
+    }
+  }
+  this.items_.push(result);
+};
+
+/**
+ * @returns {Boolean} True if <b>everything</b> below passed
+ */
+jasmine.NestedResults.prototype.passed = function() {
+  return this.passedCount === this.totalCount;
+};
+/**
+ * Base class for pretty printing for expectation results.
+ */
+jasmine.PrettyPrinter = function() {
+  this.ppNestLevel_ = 0;
+};
+
+/**
+ * Formats a value in a nice, human-readable string.
+ *
+ * @param value
+ */
+jasmine.PrettyPrinter.prototype.format = function(value) {
+  if (this.ppNestLevel_ > 40) {
+    throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
+  }
+
+  this.ppNestLevel_++;
+  try {
+    if (value === jasmine.undefined) {
+      this.emitScalar('undefined');
+    } else if (value === null) {
+      this.emitScalar('null');
+    } else if (value === jasmine.getGlobal()) {
+      this.emitScalar('<global>');
+    } else if (value.jasmineToString) {
+      this.emitScalar(value.jasmineToString());
+    } else if (typeof value === 'string') {
+      this.emitString(value);
+    } else if (jasmine.isSpy(value)) {
+      this.emitScalar("spy on " + value.identity);
+    } else if (value instanceof RegExp) {
+      this.emitScalar(value.toString());
+    } else if (typeof value === 'function') {
+      this.emitScalar('Function');
+    } else if (typeof value.nodeType === 'number') {
+      this.emitScalar('HTMLNode');
+    } else if (value instanceof Date) {
+      this.emitScalar('Date(' + value + ')');
+    } else if (value.__Jasmine_been_here_before__) {
+      this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
+    } else if (jasmine.isArray_(value) || typeof value == 'object') {
+      value.__Jasmine_been_here_before__ = true;
+      if (jasmine.isArray_(value)) {
+        this.emitArray(value);
+      } else {
+        this.emitObject(value);
+      }
+      delete value.__Jasmine_been_here_before__;
+    } else {
+      this.emitScalar(value.toString());
+    }
+  } finally {
+    this.ppNestLevel_--;
+  }
+};
+
+jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
+  for (var property in obj) {
+    if (property == '__Jasmine_been_here_before__') continue;
+    fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && 
+                                         obj.__lookupGetter__(property) !== null) : false);
+  }
+};
+
+jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
+
+jasmine.StringPrettyPrinter = function() {
+  jasmine.PrettyPrinter.call(this);
+
+  this.string = '';
+};
+jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
+
+jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
+  this.append(value);
+};
+
+jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
+  this.append("'" + value + "'");
+};
+
+jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
+  this.append('[ ');
+  for (var i = 0; i < array.length; i++) {
+    if (i > 0) {
+      this.append(', ');
+    }
+    this.format(array[i]);
+  }
+  this.append(' ]');
+};
+
+jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
+  var self = this;
+  this.append('{ ');
+  var first = true;
+
+  this.iterateObject(obj, function(property, isGetter) {
+    if (first) {
+      first = false;
+    } else {
+      self.append(', ');
+    }
+
+    self.append(property);
+    self.append(' : ');
+    if (isGetter) {
+      self.append('<getter>');
+    } else {
+      self.format(obj[property]);
+    }
+  });
+
+  this.append(' }');
+};
+
+jasmine.StringPrettyPrinter.prototype.append = function(value) {
+  this.string += value;
+};
+jasmine.Queue = function(env) {
+  this.env = env;
+  this.blocks = [];
+  this.running = false;
+  this.index = 0;
+  this.offset = 0;
+  this.abort = false;
+};
+
+jasmine.Queue.prototype.addBefore = function(block) {
+  this.blocks.unshift(block);
+};
+
+jasmine.Queue.prototype.add = function(block) {
+  this.blocks.push(block);
+};
+
+jasmine.Queue.prototype.insertNext = function(block) {
+  this.blocks.splice((this.index + this.offset + 1), 0, block);
+  this.offset++;
+};
+
+jasmine.Queue.prototype.start = function(onComplete) {
+  this.running = true;
+  this.onComplete = onComplete;
+  this.next_();
+};
+
+jasmine.Queue.prototype.isRunning = function() {
+  return this.running;
+};
+
+jasmine.Queue.LOOP_DONT_RECURSE = true;
+
+jasmine.Queue.prototype.next_ = function() {
+  var self = this;
+  var goAgain = true;
+
+  while (goAgain) {
+    goAgain = false;
+    
+    if (self.index < self.blocks.length && !this.abort) {
+      var calledSynchronously = true;
+      var completedSynchronously = false;
+
+      var onComplete = function () {
+        if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
+          completedSynchronously = true;
+          return;
+        }
+
+        if (self.blocks[self.index].abort) {
+          self.abort = true;
+        }
+
+        self.offset = 0;
+        self.index++;
+
+        var now = new Date().getTime();
+        if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
+          self.env.lastUpdate = now;
+          self.env.setTimeout(function() {
+            self.next_();
+          }, 0);
+        } else {
+          if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
+            goAgain = true;
+          } else {
+            self.next_();
+          }
+        }
+      };
+      self.blocks[self.index].execute(onComplete);
+
+      calledSynchronously = false;
+      if (completedSynchronously) {
+        onComplete();
+      }
+      
+    } else {
+      self.running = false;
+      if (self.onComplete) {
+        self.onComplete();
+      }
+    }
+  }
+};
+
+jasmine.Queue.prototype.results = function() {
+  var results = new jasmine.NestedResults();
+  for (var i = 0; i < this.blocks.length; i++) {
+    if (this.blocks[i].results) {
+      results.addResult(this.blocks[i].results());
+    }
+  }
+  return results;
+};
+
+
+/**
+ * Runner
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ */
+jasmine.Runner = function(env) {
+  var self = this;
+  self.env = env;
+  self.queue = new jasmine.Queue(env);
+  self.before_ = [];
+  self.after_ = [];
+  self.suites_ = [];
+};
+
+jasmine.Runner.prototype.execute = function() {
+  var self = this;
+  if (self.env.reporter.reportRunnerStarting) {
+    self.env.reporter.reportRunnerStarting(this);
+  }
+  self.queue.start(function () {
+    self.finishCallback();
+  });
+};
+
+jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
+  beforeEachFunction.typeName = 'beforeEach';
+  this.before_.splice(0,0,beforeEachFunction);
+};
+
+jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
+  afterEachFunction.typeName = 'afterEach';
+  this.after_.splice(0,0,afterEachFunction);
+};
+
+
+jasmine.Runner.prototype.finishCallback = function() {
+  this.env.reporter.reportRunnerResults(this);
+};
+
+jasmine.Runner.prototype.addSuite = function(suite) {
+  this.suites_.push(suite);
+};
+
+jasmine.Runner.prototype.add = function(block) {
+  if (block instanceof jasmine.Suite) {
+    this.addSuite(block);
+  }
+  this.queue.add(block);
+};
+
+jasmine.Runner.prototype.specs = function () {
+  var suites = this.suites();
+  var specs = [];
+  for (var i = 0; i < suites.length; i++) {
+    specs = specs.concat(suites[i].specs());
+  }
+  return specs;
+};
+
+jasmine.Runner.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.Runner.prototype.topLevelSuites = function() {
+  var topLevelSuites = [];
+  for (var i = 0; i < this.suites_.length; i++) {
+    if (!this.suites_[i].parentSuite) {
+      topLevelSuites.push(this.suites_[i]);
+    }
+  }
+  return topLevelSuites;
+};
+
+jasmine.Runner.prototype.results = function() {
+  return this.queue.results();
+};
+/**
+ * Internal representation of a Jasmine specification, or test.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {jasmine.Suite} suite
+ * @param {String} description
+ */
+jasmine.Spec = function(env, suite, description) {
+  if (!env) {
+    throw new Error('jasmine.Env() required');
+  }
+  if (!suite) {
+    throw new Error('jasmine.Suite() required');
+  }
+  var spec = this;
+  spec.id = env.nextSpecId ? env.nextSpecId() : null;
+  spec.env = env;
+  spec.suite = suite;
+  spec.description = description;
+  spec.queue = new jasmine.Queue(env);
+
+  spec.afterCallbacks = [];
+  spec.spies_ = [];
+
+  spec.results_ = new jasmine.NestedResults();
+  spec.results_.description = description;
+  spec.matchersClass = null;
+};
+
+jasmine.Spec.prototype.getFullName = function() {
+  return this.suite.getFullName() + ' ' + this.description + '.';
+};
+
+
+jasmine.Spec.prototype.results = function() {
+  return this.results_;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the spec's output.
+ *
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
+ */
+jasmine.Spec.prototype.log = function() {
+  return this.results_.log(arguments);
+};
+
+jasmine.Spec.prototype.runs = function (func) {
+  var block = new jasmine.Block(this.env, func, this);
+  this.addToQueue(block);
+  return this;
+};
+
+jasmine.Spec.prototype.addToQueue = function (block) {
+  if (this.queue.isRunning()) {
+    this.queue.insertNext(block);
+  } else {
+    this.queue.add(block);
+  }
+};
+
+/**
+ * @param {jasmine.ExpectationResult} result
+ */
+jasmine.Spec.prototype.addMatcherResult = function(result) {
+  this.results_.addResult(result);
+};
+
+jasmine.Spec.prototype.expect = function(actual) {
+  var positive = new (this.getMatchersClass_())(this.env, actual, this);
+  positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
+  return positive;
+};
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+jasmine.Spec.prototype.waits = function(timeout) {
+  var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
+  this.addToQueue(waitsFunc);
+  return this;
+};
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+  var latchFunction_ = null;
+  var optional_timeoutMessage_ = null;
+  var optional_timeout_ = null;
+
+  for (var i = 0; i < arguments.length; i++) {
+    var arg = arguments[i];
+    switch (typeof arg) {
+      case 'function':
+        latchFunction_ = arg;
+        break;
+      case 'string':
+        optional_timeoutMessage_ = arg;
+        break;
+      case 'number':
+        optional_timeout_ = arg;
+        break;
+    }
+  }
+
+  var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
+  this.addToQueue(waitsForFunc);
+  return this;
+};
+
+jasmine.Spec.prototype.fail = function (e) {
+  var expectationResult = new jasmine.ExpectationResult({
+    passed: false,
+    message: e ? jasmine.util.formatException(e) : 'Exception',
+    trace: { stack: e.stack }
+  });
+  this.results_.addResult(expectationResult);
+};
+
+jasmine.Spec.prototype.getMatchersClass_ = function() {
+  return this.matchersClass || this.env.matchersClass;
+};
+
+jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
+  var parent = this.getMatchersClass_();
+  var newMatchersClass = function() {
+    parent.apply(this, arguments);
+  };
+  jasmine.util.inherit(newMatchersClass, parent);
+  jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
+  this.matchersClass = newMatchersClass;
+};
+
+jasmine.Spec.prototype.finishCallback = function() {
+  this.env.reporter.reportSpecResults(this);
+};
+
+jasmine.Spec.prototype.finish = function(onComplete) {
+  this.removeAllSpies();
+  this.finishCallback();
+  if (onComplete) {
+    onComplete();
+  }
+};
+
+jasmine.Spec.prototype.after = function(doAfter) {
+  if (this.queue.isRunning()) {
+    this.queue.add(new jasmine.Block(this.env, doAfter, this));
+  } else {
+    this.afterCallbacks.unshift(doAfter);
+  }
+};
+
+jasmine.Spec.prototype.execute = function(onComplete) {
+  var spec = this;
+  if (!spec.env.specFilter(spec)) {
+    spec.results_.skipped = true;
+    spec.finish(onComplete);
+    return;
+  }
+
+  this.env.reporter.reportSpecStarting(this);
+
+  spec.env.currentSpec = spec;
+
+  spec.addBeforesAndAftersToQueue();
+
+  spec.queue.start(function () {
+    spec.finish(onComplete);
+  });
+};
+
+jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
+  var runner = this.env.currentRunner();
+  var i;
+
+  for (var suite = this.suite; suite; suite = suite.parentSuite) {
+    for (i = 0; i < suite.before_.length; i++) {
+      this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
+    }
+  }
+  for (i = 0; i < runner.before_.length; i++) {
+    this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
+  }
+  for (i = 0; i < this.afterCallbacks.length; i++) {
+    this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));
+  }
+  for (suite = this.suite; suite; suite = suite.parentSuite) {
+    for (i = 0; i < suite.after_.length; i++) {
+      this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));
+    }
+  }
+  for (i = 0; i < runner.after_.length; i++) {
+    this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));
+  }
+};
+
+jasmine.Spec.prototype.explodes = function() {
+  throw 'explodes function should not have been called';
+};
+
+jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
+  if (obj == jasmine.undefined) {
+    throw "spyOn could not find an object to spy upon for " + methodName + "()";
+  }
+
+  if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
+    throw methodName + '() method does not exist';
+  }
+
+  if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
+    throw new Error(methodName + ' has already been spied upon');
+  }
+
+  var spyObj = jasmine.createSpy(methodName);
+
+  this.spies_.push(spyObj);
+  spyObj.baseObj = obj;
+  spyObj.methodName = methodName;
+  spyObj.originalValue = obj[methodName];
+
+  obj[methodName] = spyObj;
+
+  return spyObj;
+};
+
+jasmine.Spec.prototype.removeAllSpies = function() {
+  for (var i = 0; i < this.spies_.length; i++) {
+    var spy = this.spies_[i];
+    spy.baseObj[spy.methodName] = spy.originalValue;
+  }
+  this.spies_ = [];
+};
+
+/**
+ * Internal representation of a Jasmine suite.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {String} description
+ * @param {Function} specDefinitions
+ * @param {jasmine.Suite} parentSuite
+ */
+jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
+  var self = this;
+  self.id = env.nextSuiteId ? env.nextSuiteId() : null;
+  self.description = description;
+  self.queue = new jasmine.Queue(env);
+  self.parentSuite = parentSuite;
+  self.env = env;
+  self.before_ = [];
+  self.after_ = [];
+  self.children_ = [];
+  self.suites_ = [];
+  self.specs_ = [];
+};
+
+jasmine.Suite.prototype.getFullName = function() {
+  var fullName = this.description;
+  for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
+    fullName = parentSuite.description + ' ' + fullName;
+  }
+  return fullName;
+};
+
+jasmine.Suite.prototype.finish = function(onComplete) {
+  this.env.reporter.reportSuiteResults(this);
+  this.finished = true;
+  if (typeof(onComplete) == 'function') {
+    onComplete();
+  }
+};
+
+jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
+  beforeEachFunction.typeName = 'beforeEach';
+  this.before_.unshift(beforeEachFunction);
+};
+
+jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
+  afterEachFunction.typeName = 'afterEach';
+  this.after_.unshift(afterEachFunction);
+};
+
+jasmine.Suite.prototype.results = function() {
+  return this.queue.results();
+};
+
+jasmine.Suite.prototype.add = function(suiteOrSpec) {
+  this.children_.push(suiteOrSpec);
+  if (suiteOrSpec instanceof jasmine.Suite) {
+    this.suites_.push(suiteOrSpec);
+    this.env.currentRunner().addSuite(suiteOrSpec);
+  } else {
+    this.specs_.push(suiteOrSpec);
+  }
+  this.queue.add(suiteOrSpec);
+};
+
+jasmine.Suite.prototype.specs = function() {
+  return this.specs_;
+};
+
+jasmine.Suite.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.Suite.prototype.children = function() {
+  return this.children_;
+};
+
+jasmine.Suite.prototype.execute = function(onComplete) {
+  var self = this;
+  this.queue.start(function () {
+    self.finish(onComplete);
+  });
+};
+jasmine.WaitsBlock = function(env, timeout, spec) {
+  this.timeout = timeout;
+  jasmine.Block.call(this, env, null, spec);
+};
+
+jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
+
+jasmine.WaitsBlock.prototype.execute = function (onComplete) {
+  if (jasmine.VERBOSE) {
+    this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
+  }
+  this.env.setTimeout(function () {
+    onComplete();
+  }, this.timeout);
+};
+/**
+ * A block which waits for some condition to become true, with timeout.
+ *
+ * @constructor
+ * @extends jasmine.Block
+ * @param {jasmine.Env} env The Jasmine environment.
+ * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
+ * @param {Function} latchFunction A function which returns true when the desired condition has been met.
+ * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
+ * @param {jasmine.Spec} spec The Jasmine spec.
+ */
+jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
+  this.timeout = timeout || env.defaultTimeoutInterval;
+  this.latchFunction = latchFunction;
+  this.message = message;
+  this.totalTimeSpentWaitingForLatch = 0;
+  jasmine.Block.call(this, env, null, spec);
+};
+jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
+
+jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
+
+jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
+  if (jasmine.VERBOSE) {
+    this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
+  }
+  var latchFunctionResult;
+  try {
+    latchFunctionResult = this.latchFunction.apply(this.spec);
+  } catch (e) {
+    this.spec.fail(e);
+    onComplete();
+    return;
+  }
+
+  if (latchFunctionResult) {
+    onComplete();
+  } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
+    var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
+    this.spec.fail({
+      name: 'timeout',
+      message: message
+    });
+
+    this.abort = true;
+    onComplete();
+  } else {
+    this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
+    var self = this;
+    this.env.setTimeout(function() {
+      self.execute(onComplete);
+    }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
+  }
+};
+
+jasmine.version_= {
+  "major": 1,
+  "minor": 2,
+  "build": 0,
+  "revision": 1333310630,
+  "release_candidate": 1
+};

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/accelerometer.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/accelerometer.html b/www/autotest/pages/accelerometer.html
new file mode 100644
index 0000000..52b333b
--- /dev/null
+++ b/www/autotest/pages/accelerometer.html
@@ -0,0 +1,54 @@
+<!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>Cordova: Accelerometer API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/accelerometer.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/all.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/all.html b/www/autotest/pages/all.html
new file mode 100644
index 0000000..c006db1
--- /dev/null
+++ b/www/autotest/pages/all.html
@@ -0,0 +1,73 @@
+<!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>Cordova: API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/accelerometer.tests.js"></script>
+  <script type="text/javascript" src="../tests/battery.tests.js"></script>
+  <script type="text/javascript" src="../tests/bridge.tests.js"></script>
+  <script type="text/javascript" src="../tests/capture.tests.js"></script>
+  <script type="text/javascript" src="../tests/compass.tests.js"></script>
+  <script type="text/javascript" src="../tests/contacts.tests.js"></script>
+  <script type="text/javascript" src="../tests/camera.tests.js"></script>
+  <script type="text/javascript" src="../tests/datauri.tests.js"></script>
+  <script type="text/javascript" src="../tests/device.tests.js"></script>
+  <script type="text/javascript" src="../tests/file.tests.js"></script>
+  <script type="text/javascript" src="../tests/filetransfer.tests.js"></script>
+  <script type="text/javascript" src="../tests/geolocation.tests.js"></script>
+  <script type="text/javascript" src="../tests/globalization.tests.js"></script>
+  <script type="text/javascript" src="../tests/media.tests.js"></script>
+  <script type="text/javascript" src="../tests/network.tests.js"></script>
+  <script type="text/javascript" src="../tests/notification.tests.js"></script>
+  <script type="text/javascript" src="../tests/platform.tests.js"></script>
+  <script type="text/javascript" src="../tests/storage.tests.js"></script>
+  <script type="text/javascript" src="../tests/splashscreen.tests.js"></script>
+  <script type="text/javascript" src="../tests/localXHR.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./all.js"></script>      
+</head>
+
+<body>
+  <a class="backBtn">Back</a>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/all.js
----------------------------------------------------------------------
diff --git a/www/autotest/pages/all.js b/www/autotest/pages/all.js
new file mode 100644
index 0000000..bc72b29
--- /dev/null
+++ b/www/autotest/pages/all.js
@@ -0,0 +1,46 @@
+var root, temp_root, persistent_root;
+
+document.addEventListener('deviceready', function () {
+    // one-time retrieval of the root file system entry
+    var onError = function(e) {
+        console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.');
+        console.log(JSON.stringify(e));
+    };
+
+    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
+        function(fileSystem) {
+            console.log('File API test Init: Setting PERSISTENT FS.');
+            root = fileSystem.root; // set in file.tests.js
+            persistent_root = root;
+
+            // Once root is set up, fire off tests
+            var jasmineEnv = jasmine.getEnv();
+            jasmineEnv.updateInterval = 1000;
+
+            var htmlReporter = new jasmine.HtmlReporter();
+            jasmineEnv.addReporter(htmlReporter);
+
+            // the following will only be defined if the Medic plugin is loaded
+            if('medic' in window) {
+                if( medic.isEnabled() ) {
+                    jasmineEnv.addReporter(medic.getJSReporter());
+                }
+            }
+
+            jasmineEnv.specFilter = function(spec) {
+              return htmlReporter.specFilter(spec);
+            };
+
+            jasmineEnv.execute();
+        }, onError);
+    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
+        function(fileSystem) {
+            console.log('File API test Init: Setting TEMPORARY FS.');
+            temp_root = fileSystem.root; // set in file.tests.js
+        }, onError);
+}, false);
+
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+}
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/battery.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/battery.html b/www/autotest/pages/battery.html
new file mode 100644
index 0000000..2063417
--- /dev/null
+++ b/www/autotest/pages/battery.html
@@ -0,0 +1,51 @@
+<!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>Cordova: Battery API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/battery.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a class="backBtn">Back</a>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/bridge.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/bridge.html b/www/autotest/pages/bridge.html
new file mode 100644
index 0000000..822d9ec
--- /dev/null
+++ b/www/autotest/pages/bridge.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Device API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/bridge.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/camera.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/camera.html b/www/autotest/pages/camera.html
new file mode 100644
index 0000000..91843d7
--- /dev/null
+++ b/www/autotest/pages/camera.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Camera API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/camera.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/capture.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/capture.html b/www/autotest/pages/capture.html
new file mode 100644
index 0000000..bac570f
--- /dev/null
+++ b/www/autotest/pages/capture.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Capture API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/capture.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a class="backBtn">Back</a>
+</body>
+</html>
+


[18/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/jasmine.js
----------------------------------------------------------------------
diff --git a/autotest/jasmine.js b/autotest/jasmine.js
deleted file mode 100644
index bccb66c..0000000
--- a/autotest/jasmine.js
+++ /dev/null
@@ -1,2530 +0,0 @@
-var isCommonJS = typeof window == "undefined";
-
-/**
- * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
- *
- * @namespace
- */
-var jasmine = {};
-if (isCommonJS) exports.jasmine = jasmine;
-/**
- * @private
- */
-jasmine.unimplementedMethod_ = function() {
-  throw new Error("unimplemented method");
-};
-
-/**
- * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
- * a plain old variable and may be redefined by somebody else.
- *
- * @private
- */
-jasmine.undefined = jasmine.___undefined___;
-
-/**
- * Show diagnostic messages in the console if set to true
- *
- */
-jasmine.VERBOSE = false;
-
-/**
- * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
- *
- */
-jasmine.DEFAULT_UPDATE_INTERVAL = 250;
-
-/**
- * Default timeout interval in milliseconds for waitsFor() blocks.
- */
-jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
-
-jasmine.getGlobal = function() {
-  function getGlobal() {
-    return this;
-  }
-
-  return getGlobal();
-};
-
-/**
- * Allows for bound functions to be compared.  Internal use only.
- *
- * @ignore
- * @private
- * @param base {Object} bound 'this' for the function
- * @param name {Function} function to find
- */
-jasmine.bindOriginal_ = function(base, name) {
-  var original = base[name];
-  if (original.apply) {
-    return function() {
-      return original.apply(base, arguments);
-    };
-  } else {
-    // IE support
-    return jasmine.getGlobal()[name];
-  }
-};
-
-jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
-jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
-jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
-jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
-
-jasmine.MessageResult = function(values) {
-  this.type = 'log';
-  this.values = values;
-  this.trace = new Error(); // todo: test better
-};
-
-jasmine.MessageResult.prototype.toString = function() {
-  var text = "";
-  for (var i = 0; i < this.values.length; i++) {
-    if (i > 0) text += " ";
-    if (jasmine.isString_(this.values[i])) {
-      text += this.values[i];
-    } else {
-      text += jasmine.pp(this.values[i]);
-    }
-  }
-  return text;
-};
-
-jasmine.ExpectationResult = function(params) {
-  this.type = 'expect';
-  this.matcherName = params.matcherName;
-  this.passed_ = params.passed;
-  this.expected = params.expected;
-  this.actual = params.actual;
-  this.message = this.passed_ ? 'Passed.' : params.message;
-
-  var trace = (params.trace || new Error(this.message));
-  this.trace = this.passed_ ? '' : trace;
-};
-
-jasmine.ExpectationResult.prototype.toString = function () {
-  return this.message;
-};
-
-jasmine.ExpectationResult.prototype.passed = function () {
-  return this.passed_;
-};
-
-/**
- * Getter for the Jasmine environment. Ensures one gets created
- */
-jasmine.getEnv = function() {
-  var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
-  return env;
-};
-
-/**
- * @ignore
- * @private
- * @param value
- * @returns {Boolean}
- */
-jasmine.isArray_ = function(value) {
-  return jasmine.isA_("Array", value);
-};
-
-/**
- * @ignore
- * @private
- * @param value
- * @returns {Boolean}
- */
-jasmine.isString_ = function(value) {
-  return jasmine.isA_("String", value);
-};
-
-/**
- * @ignore
- * @private
- * @param value
- * @returns {Boolean}
- */
-jasmine.isNumber_ = function(value) {
-  return jasmine.isA_("Number", value);
-};
-
-/**
- * @ignore
- * @private
- * @param {String} typeName
- * @param value
- * @returns {Boolean}
- */
-jasmine.isA_ = function(typeName, value) {
-  return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
-};
-
-/**
- * Pretty printer for expecations.  Takes any object and turns it into a human-readable string.
- *
- * @param value {Object} an object to be outputted
- * @returns {String}
- */
-jasmine.pp = function(value) {
-  var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
-  stringPrettyPrinter.format(value);
-  return stringPrettyPrinter.string;
-};
-
-/**
- * Returns true if the object is a DOM Node.
- *
- * @param {Object} obj object to check
- * @returns {Boolean}
- */
-jasmine.isDomNode = function(obj) {
-  return obj.nodeType > 0;
-};
-
-/**
- * Returns a matchable 'generic' object of the class type.  For use in expecations of type when values don't matter.
- *
- * @example
- * // don't care about which function is passed in, as long as it's a function
- * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
- *
- * @param {Class} clazz
- * @returns matchable object of the type clazz
- */
-jasmine.any = function(clazz) {
-  return new jasmine.Matchers.Any(clazz);
-};
-
-/**
- * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
- * attributes on the object.
- *
- * @example
- * // don't care about any other attributes than foo.
- * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
- *
- * @param sample {Object} sample
- * @returns matchable object for the sample
- */
-jasmine.objectContaining = function (sample) {
-    return new jasmine.Matchers.ObjectContaining(sample);
-};
-
-/**
- * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
- *
- * Spies should be created in test setup, before expectations.  They can then be checked, using the standard Jasmine
- * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
- *
- * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
- *
- * Spies are torn down at the end of every spec.
- *
- * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
- *
- * @example
- * // a stub
- * var myStub = jasmine.createSpy('myStub');  // can be used anywhere
- *
- * // spy example
- * var foo = {
- *   not: function(bool) { return !bool; }
- * }
- *
- * // actual foo.not will not be called, execution stops
- * spyOn(foo, 'not');
-
- // foo.not spied upon, execution will continue to implementation
- * spyOn(foo, 'not').andCallThrough();
- *
- * // fake example
- * var foo = {
- *   not: function(bool) { return !bool; }
- * }
- *
- * // foo.not(val) will return val
- * spyOn(foo, 'not').andCallFake(function(value) {return value;});
- *
- * // mock example
- * foo.not(7 == 7);
- * expect(foo.not).toHaveBeenCalled();
- * expect(foo.not).toHaveBeenCalledWith(true);
- *
- * @constructor
- * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
- * @param {String} name
- */
-jasmine.Spy = function(name) {
-  /**
-   * The name of the spy, if provided.
-   */
-  this.identity = name || 'unknown';
-  /**
-   *  Is this Object a spy?
-   */
-  this.isSpy = true;
-  /**
-   * The actual function this spy stubs.
-   */
-  this.plan = function() {
-  };
-  /**
-   * Tracking of the most recent call to the spy.
-   * @example
-   * var mySpy = jasmine.createSpy('foo');
-   * mySpy(1, 2);
-   * mySpy.mostRecentCall.args = [1, 2];
-   */
-  this.mostRecentCall = {};
-
-  /**
-   * Holds arguments for each call to the spy, indexed by call count
-   * @example
-   * var mySpy = jasmine.createSpy('foo');
-   * mySpy(1, 2);
-   * mySpy(7, 8);
-   * mySpy.mostRecentCall.args = [7, 8];
-   * mySpy.argsForCall[0] = [1, 2];
-   * mySpy.argsForCall[1] = [7, 8];
-   */
-  this.argsForCall = [];
-  this.calls = [];
-};
-
-/**
- * Tells a spy to call through to the actual implemenatation.
- *
- * @example
- * var foo = {
- *   bar: function() { // do some stuff }
- * }
- *
- * // defining a spy on an existing property: foo.bar
- * spyOn(foo, 'bar').andCallThrough();
- */
-jasmine.Spy.prototype.andCallThrough = function() {
-  this.plan = this.originalValue;
-  return this;
-};
-
-/**
- * For setting the return value of a spy.
- *
- * @example
- * // defining a spy from scratch: foo() returns 'baz'
- * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
- *
- * // defining a spy on an existing property: foo.bar() returns 'baz'
- * spyOn(foo, 'bar').andReturn('baz');
- *
- * @param {Object} value
- */
-jasmine.Spy.prototype.andReturn = function(value) {
-  this.plan = function() {
-    return value;
-  };
-  return this;
-};
-
-/**
- * For throwing an exception when a spy is called.
- *
- * @example
- * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
- * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
- *
- * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
- * spyOn(foo, 'bar').andThrow('baz');
- *
- * @param {String} exceptionMsg
- */
-jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
-  this.plan = function() {
-    throw exceptionMsg;
-  };
-  return this;
-};
-
-/**
- * Calls an alternate implementation when a spy is called.
- *
- * @example
- * var baz = function() {
- *   // do some stuff, return something
- * }
- * // defining a spy from scratch: foo() calls the function baz
- * var foo = jasmine.createSpy('spy on foo').andCall(baz);
- *
- * // defining a spy on an existing property: foo.bar() calls an anonymnous function
- * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
- *
- * @param {Function} fakeFunc
- */
-jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
-  this.plan = fakeFunc;
-  return this;
-};
-
-/**
- * Resets all of a spy's the tracking variables so that it can be used again.
- *
- * @example
- * spyOn(foo, 'bar');
- *
- * foo.bar();
- *
- * expect(foo.bar.callCount).toEqual(1);
- *
- * foo.bar.reset();
- *
- * expect(foo.bar.callCount).toEqual(0);
- */
-jasmine.Spy.prototype.reset = function() {
-  this.wasCalled = false;
-  this.callCount = 0;
-  this.argsForCall = [];
-  this.calls = [];
-  this.mostRecentCall = {};
-};
-
-jasmine.createSpy = function(name) {
-
-  var spyObj = function() {
-    spyObj.wasCalled = true;
-    spyObj.callCount++;
-    var args = jasmine.util.argsToArray(arguments);
-    spyObj.mostRecentCall.object = this;
-    spyObj.mostRecentCall.args = args;
-    spyObj.argsForCall.push(args);
-    spyObj.calls.push({object: this, args: args});
-    return spyObj.plan.apply(this, arguments);
-  };
-
-  var spy = new jasmine.Spy(name);
-
-  for (var prop in spy) {
-    spyObj[prop] = spy[prop];
-  }
-
-  spyObj.reset();
-
-  return spyObj;
-};
-
-/**
- * Determines whether an object is a spy.
- *
- * @param {jasmine.Spy|Object} putativeSpy
- * @returns {Boolean}
- */
-jasmine.isSpy = function(putativeSpy) {
-  return putativeSpy && putativeSpy.isSpy;
-};
-
-/**
- * Creates a more complicated spy: an Object that has every property a function that is a spy.  Used for stubbing something
- * large in one call.
- *
- * @param {String} baseName name of spy class
- * @param {Array} methodNames array of names of methods to make spies
- */
-jasmine.createSpyObj = function(baseName, methodNames) {
-  if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
-    throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
-  }
-  var obj = {};
-  for (var i = 0; i < methodNames.length; i++) {
-    obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
-  }
-  return obj;
-};
-
-/**
- * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
- *
- * Be careful not to leave calls to <code>jasmine.log</code> in production code.
- */
-jasmine.log = function() {
-  var spec = jasmine.getEnv().currentSpec;
-  spec.log.apply(spec, arguments);
-};
-
-/**
- * Function that installs a spy on an existing object's method name.  Used within a Spec to create a spy.
- *
- * @example
- * // spy example
- * var foo = {
- *   not: function(bool) { return !bool; }
- * }
- * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
- *
- * @see jasmine.createSpy
- * @param obj
- * @param methodName
- * @returns a Jasmine spy that can be chained with all spy methods
- */
-var spyOn = function(obj, methodName) {
-  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
-};
-if (isCommonJS) exports.spyOn = spyOn;
-
-/**
- * Creates a Jasmine spec that will be added to the current suite.
- *
- * // TODO: pending tests
- *
- * @example
- * it('should be true', function() {
- *   expect(true).toEqual(true);
- * });
- *
- * @param {String} desc description of this specification
- * @param {Function} func defines the preconditions and expectations of the spec
- */
-var it = function(desc, func) {
-  return jasmine.getEnv().it(desc, func);
-};
-if (isCommonJS) exports.it = it;
-
-/**
- * Creates a <em>disabled</em> Jasmine spec.
- *
- * A convenience method that allows existing specs to be disabled temporarily during development.
- *
- * @param {String} desc description of this specification
- * @param {Function} func defines the preconditions and expectations of the spec
- */
-var xit = function(desc, func) {
-  return jasmine.getEnv().xit(desc, func);
-};
-if (isCommonJS) exports.xit = xit;
-
-/**
- * Starts a chain for a Jasmine expectation.
- *
- * It is passed an Object that is the actual value and should chain to one of the many
- * jasmine.Matchers functions.
- *
- * @param {Object} actual Actual value to test against and expected value
- */
-var expect = function(actual) {
-  return jasmine.getEnv().currentSpec.expect(actual);
-};
-if (isCommonJS) exports.expect = expect;
-
-/**
- * Defines part of a jasmine spec.  Used in cominbination with waits or waitsFor in asynchrnous specs.
- *
- * @param {Function} func Function that defines part of a jasmine spec.
- */
-var runs = function(func) {
-  jasmine.getEnv().currentSpec.runs(func);
-};
-if (isCommonJS) exports.runs = runs;
-
-/**
- * Waits a fixed time period before moving to the next block.
- *
- * @deprecated Use waitsFor() instead
- * @param {Number} timeout milliseconds to wait
- */
-var waits = function(timeout) {
-  jasmine.getEnv().currentSpec.waits(timeout);
-};
-if (isCommonJS) exports.waits = waits;
-
-/**
- * Waits for the latchFunction to return true before proceeding to the next block.
- *
- * @param {Function} latchFunction
- * @param {String} optional_timeoutMessage
- * @param {Number} optional_timeout
- */
-var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
-  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
-};
-if (isCommonJS) exports.waitsFor = waitsFor;
-
-/**
- * A function that is called before each spec in a suite.
- *
- * Used for spec setup, including validating assumptions.
- *
- * @param {Function} beforeEachFunction
- */
-var beforeEach = function(beforeEachFunction) {
-  jasmine.getEnv().beforeEach(beforeEachFunction);
-};
-if (isCommonJS) exports.beforeEach = beforeEach;
-
-/**
- * A function that is called after each spec in a suite.
- *
- * Used for restoring any state that is hijacked during spec execution.
- *
- * @param {Function} afterEachFunction
- */
-var afterEach = function(afterEachFunction) {
-  jasmine.getEnv().afterEach(afterEachFunction);
-};
-if (isCommonJS) exports.afterEach = afterEach;
-
-/**
- * Defines a suite of specifications.
- *
- * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
- * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
- * of setup in some tests.
- *
- * @example
- * // TODO: a simple suite
- *
- * // TODO: a simple suite with a nested describe block
- *
- * @param {String} description A string, usually the class under test.
- * @param {Function} specDefinitions function that defines several specs.
- */
-var describe = function(description, specDefinitions) {
-  return jasmine.getEnv().describe(description, specDefinitions);
-};
-if (isCommonJS) exports.describe = describe;
-
-/**
- * Disables a suite of specifications.  Used to disable some suites in a file, or files, temporarily during development.
- *
- * @param {String} description A string, usually the class under test.
- * @param {Function} specDefinitions function that defines several specs.
- */
-var xdescribe = function(description, specDefinitions) {
-  return jasmine.getEnv().xdescribe(description, specDefinitions);
-};
-if (isCommonJS) exports.xdescribe = xdescribe;
-
-
-// Provide the XMLHttpRequest class for IE 5.x-6.x:
-jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
-  function tryIt(f) {
-    try {
-      return f();
-    } catch(e) {
-    }
-    return null;
-  }
-
-  var xhr = tryIt(function() {
-    return new ActiveXObject("Msxml2.XMLHTTP.6.0");
-  }) ||
-    tryIt(function() {
-      return new ActiveXObject("Msxml2.XMLHTTP.3.0");
-    }) ||
-    tryIt(function() {
-      return new ActiveXObject("Msxml2.XMLHTTP");
-    }) ||
-    tryIt(function() {
-      return new ActiveXObject("Microsoft.XMLHTTP");
-    });
-
-  if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
-
-  return xhr;
-} : XMLHttpRequest;
-/**
- * @namespace
- */
-jasmine.util = {};
-
-/**
- * Declare that a child class inherit it's prototype from the parent class.
- *
- * @private
- * @param {Function} childClass
- * @param {Function} parentClass
- */
-jasmine.util.inherit = function(childClass, parentClass) {
-  /**
-   * @private
-   */
-  var subclass = function() {
-  };
-  subclass.prototype = parentClass.prototype;
-  childClass.prototype = new subclass();
-};
-
-jasmine.util.formatException = function(e) {
-  var lineNumber;
-  if (e.line) {
-    lineNumber = e.line;
-  }
-  else if (e.lineNumber) {
-    lineNumber = e.lineNumber;
-  }
-
-  var file;
-
-  if (e.sourceURL) {
-    file = e.sourceURL;
-  }
-  else if (e.fileName) {
-    file = e.fileName;
-  }
-
-  var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
-
-  if (file && lineNumber) {
-    message += ' in ' + file + ' (line ' + lineNumber + ')';
-  }
-
-  return message;
-};
-
-jasmine.util.htmlEscape = function(str) {
-  if (!str) return str;
-  return str.replace(/&/g, '&amp;')
-    .replace(/</g, '&lt;')
-    .replace(/>/g, '&gt;');
-};
-
-jasmine.util.argsToArray = function(args) {
-  var arrayOfArgs = [];
-  for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
-  return arrayOfArgs;
-};
-
-jasmine.util.extend = function(destination, source) {
-  for (var property in source) destination[property] = source[property];
-  return destination;
-};
-
-/**
- * Environment for Jasmine
- *
- * @constructor
- */
-jasmine.Env = function() {
-  this.currentSpec = null;
-  this.currentSuite = null;
-  this.currentRunner_ = new jasmine.Runner(this);
-
-  this.reporter = new jasmine.MultiReporter();
-
-  this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
-  this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
-  this.lastUpdate = 0;
-  this.specFilter = function() {
-    return true;
-  };
-
-  this.nextSpecId_ = 0;
-  this.nextSuiteId_ = 0;
-  this.equalityTesters_ = [];
-
-  // wrap matchers
-  this.matchersClass = function() {
-    jasmine.Matchers.apply(this, arguments);
-  };
-  jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
-
-  jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
-};
-
-
-jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
-jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
-jasmine.Env.prototype.setInterval = jasmine.setInterval;
-jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
-
-/**
- * @returns an object containing jasmine version build info, if set.
- */
-jasmine.Env.prototype.version = function () {
-  if (jasmine.version_) {
-    return jasmine.version_;
-  } else {
-    throw new Error('Version not set');
-  }
-};
-
-/**
- * @returns string containing jasmine version build info, if set.
- */
-jasmine.Env.prototype.versionString = function() {
-  if (!jasmine.version_) {
-    return "version unknown";
-  }
-
-  var version = this.version();
-  var versionString = version.major + "." + version.minor + "." + version.build;
-  if (version.release_candidate) {
-    versionString += ".rc" + version.release_candidate;
-  }
-  versionString += " revision " + version.revision;
-  return versionString;
-};
-
-/**
- * @returns a sequential integer starting at 0
- */
-jasmine.Env.prototype.nextSpecId = function () {
-  return this.nextSpecId_++;
-};
-
-/**
- * @returns a sequential integer starting at 0
- */
-jasmine.Env.prototype.nextSuiteId = function () {
-  return this.nextSuiteId_++;
-};
-
-/**
- * Register a reporter to receive status updates from Jasmine.
- * @param {jasmine.Reporter} reporter An object which will receive status updates.
- */
-jasmine.Env.prototype.addReporter = function(reporter) {
-  this.reporter.addReporter(reporter);
-};
-
-jasmine.Env.prototype.execute = function() {
-  this.currentRunner_.execute();
-};
-
-jasmine.Env.prototype.describe = function(description, specDefinitions) {
-  var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
-
-  var parentSuite = this.currentSuite;
-  if (parentSuite) {
-    parentSuite.add(suite);
-  } else {
-    this.currentRunner_.add(suite);
-  }
-
-  this.currentSuite = suite;
-
-  var declarationError = null;
-  try {
-    specDefinitions.call(suite);
-  } catch(e) {
-    declarationError = e;
-  }
-
-  if (declarationError) {
-    this.it("encountered a declaration exception", function() {
-      throw declarationError;
-    });
-  }
-
-  this.currentSuite = parentSuite;
-
-  return suite;
-};
-
-jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
-  if (this.currentSuite) {
-    this.currentSuite.beforeEach(beforeEachFunction);
-  } else {
-    this.currentRunner_.beforeEach(beforeEachFunction);
-  }
-};
-
-jasmine.Env.prototype.currentRunner = function () {
-  return this.currentRunner_;
-};
-
-jasmine.Env.prototype.afterEach = function(afterEachFunction) {
-  if (this.currentSuite) {
-    this.currentSuite.afterEach(afterEachFunction);
-  } else {
-    this.currentRunner_.afterEach(afterEachFunction);
-  }
-
-};
-
-jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
-  return {
-    execute: function() {
-    }
-  };
-};
-
-jasmine.Env.prototype.it = function(description, func) {
-  var spec = new jasmine.Spec(this, this.currentSuite, description);
-  this.currentSuite.add(spec);
-  this.currentSpec = spec;
-
-  if (func) {
-    spec.runs(func);
-  }
-
-  return spec;
-};
-
-jasmine.Env.prototype.xit = function(desc, func) {
-  return {
-    id: this.nextSpecId(),
-    runs: function() {
-    }
-  };
-};
-
-jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
-  if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
-    return true;
-  }
-
-  a.__Jasmine_been_here_before__ = b;
-  b.__Jasmine_been_here_before__ = a;
-
-  var hasKey = function(obj, keyName) {
-    return obj !== null && obj[keyName] !== jasmine.undefined;
-  };
-
-  for (var property in b) {
-    if (!hasKey(a, property) && hasKey(b, property)) {
-      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
-    }
-  }
-  for (property in a) {
-    if (!hasKey(b, property) && hasKey(a, property)) {
-      mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
-    }
-  }
-  for (property in b) {
-    if (property == '__Jasmine_been_here_before__') continue;
-    if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
-      mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
-    }
-  }
-
-  if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
-    mismatchValues.push("arrays were not the same length");
-  }
-
-  delete a.__Jasmine_been_here_before__;
-  delete b.__Jasmine_been_here_before__;
-  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
-};
-
-jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
-  mismatchKeys = mismatchKeys || [];
-  mismatchValues = mismatchValues || [];
-
-  for (var i = 0; i < this.equalityTesters_.length; i++) {
-    var equalityTester = this.equalityTesters_[i];
-    var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
-    if (result !== jasmine.undefined) return result;
-  }
-
-  if (a === b) return true;
-
-  if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
-    return (a == jasmine.undefined && b == jasmine.undefined);
-  }
-
-  if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
-    return a === b;
-  }
-
-  if (a instanceof Date && b instanceof Date) {
-    return a.getTime() == b.getTime();
-  }
-
-  if (a.jasmineMatches) {
-    return a.jasmineMatches(b);
-  }
-
-  if (b.jasmineMatches) {
-    return b.jasmineMatches(a);
-  }
-
-  if (a instanceof jasmine.Matchers.ObjectContaining) {
-    return a.matches(b);
-  }
-
-  if (b instanceof jasmine.Matchers.ObjectContaining) {
-    return b.matches(a);
-  }
-
-  if (jasmine.isString_(a) && jasmine.isString_(b)) {
-    return (a == b);
-  }
-
-  if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
-    return (a == b);
-  }
-
-  if (typeof a === "object" && typeof b === "object") {
-    return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
-  }
-
-  //Straight check
-  return (a === b);
-};
-
-jasmine.Env.prototype.contains_ = function(haystack, needle) {
-  if (jasmine.isArray_(haystack)) {
-    for (var i = 0; i < haystack.length; i++) {
-      if (this.equals_(haystack[i], needle)) return true;
-    }
-    return false;
-  }
-  return haystack.indexOf(needle) >= 0;
-};
-
-jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
-  this.equalityTesters_.push(equalityTester);
-};
-/** No-op base class for Jasmine reporters.
- *
- * @constructor
- */
-jasmine.Reporter = function() {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.reportSpecResults = function(spec) {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.Reporter.prototype.log = function(str) {
-};
-
-/**
- * Blocks are functions with executable code that make up a spec.
- *
- * @constructor
- * @param {jasmine.Env} env
- * @param {Function} func
- * @param {jasmine.Spec} spec
- */
-jasmine.Block = function(env, func, spec) {
-  this.env = env;
-  this.func = func;
-  this.spec = spec;
-};
-
-jasmine.Block.prototype.execute = function(onComplete) {  
-  try {
-    this.func.apply(this.spec);
-  } catch (e) {
-    this.spec.fail(e);
-  }
-  onComplete();
-};
-/** JavaScript API reporter.
- *
- * @constructor
- */
-jasmine.JsApiReporter = function() {
-  this.started = false;
-  this.finished = false;
-  this.suites_ = [];
-  this.results_ = {};
-};
-
-jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
-  this.started = true;
-  var suites = runner.topLevelSuites();
-  for (var i = 0; i < suites.length; i++) {
-    var suite = suites[i];
-    this.suites_.push(this.summarize_(suite));
-  }
-};
-
-jasmine.JsApiReporter.prototype.suites = function() {
-  return this.suites_;
-};
-
-jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
-  var isSuite = suiteOrSpec instanceof jasmine.Suite;
-  var summary = {
-    id: suiteOrSpec.id,
-    name: suiteOrSpec.description,
-    type: isSuite ? 'suite' : 'spec',
-    children: []
-  };
-  
-  if (isSuite) {
-    var children = suiteOrSpec.children();
-    for (var i = 0; i < children.length; i++) {
-      summary.children.push(this.summarize_(children[i]));
-    }
-  }
-  return summary;
-};
-
-jasmine.JsApiReporter.prototype.results = function() {
-  return this.results_;
-};
-
-jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
-  return this.results_[specId];
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
-  this.finished = true;
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
-  this.results_[spec.id] = {
-    messages: spec.results().getItems(),
-    result: spec.results().failedCount > 0 ? "failed" : "passed"
-  };
-};
-
-//noinspection JSUnusedLocalSymbols
-jasmine.JsApiReporter.prototype.log = function(str) {
-};
-
-jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
-  var results = {};
-  for (var i = 0; i < specIds.length; i++) {
-    var specId = specIds[i];
-    results[specId] = this.summarizeResult_(this.results_[specId]);
-  }
-  return results;
-};
-
-jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
-  var summaryMessages = [];
-  var messagesLength = result.messages.length;
-  for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
-    var resultMessage = result.messages[messageIndex];
-    summaryMessages.push({
-      text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
-      passed: resultMessage.passed ? resultMessage.passed() : true,
-      type: resultMessage.type,
-      message: resultMessage.message,
-      trace: {
-        stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
-      }
-    });
-  }
-
-  return {
-    result : result.result,
-    messages : summaryMessages
-  };
-};
-
-/**
- * @constructor
- * @param {jasmine.Env} env
- * @param actual
- * @param {jasmine.Spec} spec
- */
-jasmine.Matchers = function(env, actual, spec, opt_isNot) {
-  this.env = env;
-  this.actual = actual;
-  this.spec = spec;
-  this.isNot = opt_isNot || false;
-  this.reportWasCalled_ = false;
-};
-
-// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
-jasmine.Matchers.pp = function(str) {
-  throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
-};
-
-// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
-jasmine.Matchers.prototype.report = function(result, failing_message, details) {
-  throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
-};
-
-jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
-  for (var methodName in prototype) {
-    if (methodName == 'report') continue;
-    var orig = prototype[methodName];
-    matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
-  }
-};
-
-jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
-  return function() {
-    var matcherArgs = jasmine.util.argsToArray(arguments);
-    var result = matcherFunction.apply(this, arguments);
-
-    if (this.isNot) {
-      result = !result;
-    }
-
-    if (this.reportWasCalled_) return result;
-
-    var message;
-    if (!result) {
-      if (this.message) {
-        message = this.message.apply(this, arguments);
-        if (jasmine.isArray_(message)) {
-          message = message[this.isNot ? 1 : 0];
-        }
-      } else {
-        var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
-        message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
-        if (matcherArgs.length > 0) {
-          for (var i = 0; i < matcherArgs.length; i++) {
-            if (i > 0) message += ",";
-            message += " " + jasmine.pp(matcherArgs[i]);
-          }
-        }
-        message += ".";
-      }
-    }
-    var expectationResult = new jasmine.ExpectationResult({
-      matcherName: matcherName,
-      passed: result,
-      expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
-      actual: this.actual,
-      message: message
-    });
-    this.spec.addMatcherResult(expectationResult);
-    return jasmine.undefined;
-  };
-};
-
-
-
-
-/**
- * toBe: compares the actual to the expected using ===
- * @param expected
- */
-jasmine.Matchers.prototype.toBe = function(expected) {
-  return this.actual === expected;
-};
-
-/**
- * toNotBe: compares the actual to the expected using !==
- * @param expected
- * @deprecated as of 1.0. Use not.toBe() instead.
- */
-jasmine.Matchers.prototype.toNotBe = function(expected) {
-  return this.actual !== expected;
-};
-
-/**
- * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
- *
- * @param expected
- */
-jasmine.Matchers.prototype.toEqual = function(expected) {
-  return this.env.equals_(this.actual, expected);
-};
-
-/**
- * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
- * @param expected
- * @deprecated as of 1.0. Use not.toEqual() instead.
- */
-jasmine.Matchers.prototype.toNotEqual = function(expected) {
-  return !this.env.equals_(this.actual, expected);
-};
-
-/**
- * Matcher that compares the actual to the expected using a regular expression.  Constructs a RegExp, so takes
- * a pattern or a String.
- *
- * @param expected
- */
-jasmine.Matchers.prototype.toMatch = function(expected) {
-  return new RegExp(expected).test(this.actual);
-};
-
-/**
- * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
- * @param expected
- * @deprecated as of 1.0. Use not.toMatch() instead.
- */
-jasmine.Matchers.prototype.toNotMatch = function(expected) {
-  return !(new RegExp(expected).test(this.actual));
-};
-
-/**
- * Matcher that compares the actual to jasmine.undefined.
- */
-jasmine.Matchers.prototype.toBeDefined = function() {
-  return (this.actual !== jasmine.undefined);
-};
-
-/**
- * Matcher that compares the actual to jasmine.undefined.
- */
-jasmine.Matchers.prototype.toBeUndefined = function() {
-  return (this.actual === jasmine.undefined);
-};
-
-/**
- * Matcher that compares the actual to null.
- */
-jasmine.Matchers.prototype.toBeNull = function() {
-  return (this.actual === null);
-};
-
-/**
- * Matcher that boolean not-nots the actual.
- */
-jasmine.Matchers.prototype.toBeTruthy = function() {
-  return !!this.actual;
-};
-
-
-/**
- * Matcher that boolean nots the actual.
- */
-jasmine.Matchers.prototype.toBeFalsy = function() {
-  return !this.actual;
-};
-
-
-/**
- * Matcher that checks to see if the actual, a Jasmine spy, was called.
- */
-jasmine.Matchers.prototype.toHaveBeenCalled = function() {
-  if (arguments.length > 0) {
-    throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
-  }
-
-  if (!jasmine.isSpy(this.actual)) {
-    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
-  }
-
-  this.message = function() {
-    return [
-      "Expected spy " + this.actual.identity + " to have been called.",
-      "Expected spy " + this.actual.identity + " not to have been called."
-    ];
-  };
-
-  return this.actual.wasCalled;
-};
-
-/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
-jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
-
-/**
- * Matcher that checks to see if the actual, a Jasmine spy, was not called.
- *
- * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
- */
-jasmine.Matchers.prototype.wasNotCalled = function() {
-  if (arguments.length > 0) {
-    throw new Error('wasNotCalled does not take arguments');
-  }
-
-  if (!jasmine.isSpy(this.actual)) {
-    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
-  }
-
-  this.message = function() {
-    return [
-      "Expected spy " + this.actual.identity + " to not have been called.",
-      "Expected spy " + this.actual.identity + " to have been called."
-    ];
-  };
-
-  return !this.actual.wasCalled;
-};
-
-/**
- * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
- *
- * @example
- *
- */
-jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
-  var expectedArgs = jasmine.util.argsToArray(arguments);
-  if (!jasmine.isSpy(this.actual)) {
-    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
-  }
-  this.message = function() {
-    if (this.actual.callCount === 0) {
-      // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
-      return [
-        "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
-        "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
-      ];
-    } else {
-      return [
-        "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
-        "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
-      ];
-    }
-  };
-
-  return this.env.contains_(this.actual.argsForCall, expectedArgs);
-};
-
-/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
-jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
-
-/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
-jasmine.Matchers.prototype.wasNotCalledWith = function() {
-  var expectedArgs = jasmine.util.argsToArray(arguments);
-  if (!jasmine.isSpy(this.actual)) {
-    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
-  }
-
-  this.message = function() {
-    return [
-      "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
-      "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
-    ];
-  };
-
-  return !this.env.contains_(this.actual.argsForCall, expectedArgs);
-};
-
-/**
- * Matcher that checks that the expected item is an element in the actual Array.
- *
- * @param {Object} expected
- */
-jasmine.Matchers.prototype.toContain = function(expected) {
-  return this.env.contains_(this.actual, expected);
-};
-
-/**
- * Matcher that checks that the expected item is NOT an element in the actual Array.
- *
- * @param {Object} expected
- * @deprecated as of 1.0. Use not.toContain() instead.
- */
-jasmine.Matchers.prototype.toNotContain = function(expected) {
-  return !this.env.contains_(this.actual, expected);
-};
-
-jasmine.Matchers.prototype.toBeLessThan = function(expected) {
-  return this.actual < expected;
-};
-
-jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
-  return this.actual > expected;
-};
-
-/**
- * Matcher that checks that the expected item is equal to the actual item
- * up to a given level of decimal precision (default 2).
- *
- * @param {Number} expected
- * @param {Number} precision
- */
-jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
-  if (!(precision === 0)) {
-    precision = precision || 2;
-  }
-  var multiplier = Math.pow(10, precision);
-  var actual = Math.round(this.actual * multiplier);
-  expected = Math.round(expected * multiplier);
-  return expected == actual;
-};
-
-/**
- * Matcher that checks that the expected exception was thrown by the actual.
- *
- * @param {String} expected
- */
-jasmine.Matchers.prototype.toThrow = function(expected) {
-  var result = false;
-  var exception;
-  if (typeof this.actual != 'function') {
-    throw new Error('Actual is not a function');
-  }
-  try {
-    this.actual();
-  } catch (e) {
-    exception = e;
-  }
-  if (exception) {
-    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
-  }
-
-  var not = this.isNot ? "not " : "";
-
-  this.message = function() {
-    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
-      return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
-    } else {
-      return "Expected function to throw an exception.";
-    }
-  };
-
-  return result;
-};
-
-jasmine.Matchers.Any = function(expectedClass) {
-  this.expectedClass = expectedClass;
-};
-
-jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
-  if (this.expectedClass == String) {
-    return typeof other == 'string' || other instanceof String;
-  }
-
-  if (this.expectedClass == Number) {
-    return typeof other == 'number' || other instanceof Number;
-  }
-
-  if (this.expectedClass == Function) {
-    return typeof other == 'function' || other instanceof Function;
-  }
-
-  if (this.expectedClass == Object) {
-    return typeof other == 'object';
-  }
-
-  return other instanceof this.expectedClass;
-};
-
-jasmine.Matchers.Any.prototype.jasmineToString = function() {
-  return '<jasmine.any(' + this.expectedClass + ')>';
-};
-
-jasmine.Matchers.ObjectContaining = function (sample) {
-  this.sample = sample;
-};
-
-jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
-  mismatchKeys = mismatchKeys || [];
-  mismatchValues = mismatchValues || [];
-
-  var env = jasmine.getEnv();
-
-  var hasKey = function(obj, keyName) {
-    return obj != null && obj[keyName] !== jasmine.undefined;
-  };
-
-  for (var property in this.sample) {
-    if (!hasKey(other, property) && hasKey(this.sample, property)) {
-      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
-    }
-    else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
-      mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
-    }
-  }
-
-  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
-};
-
-jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
-  return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
-};
-// Mock setTimeout, clearTimeout
-// Contributed by Pivotal Computer Systems, www.pivotalsf.com
-
-jasmine.FakeTimer = function() {
-  this.reset();
-
-  var self = this;
-  self.setTimeout = function(funcToCall, millis) {
-    self.timeoutsMade++;
-    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
-    return self.timeoutsMade;
-  };
-
-  self.setInterval = function(funcToCall, millis) {
-    self.timeoutsMade++;
-    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
-    return self.timeoutsMade;
-  };
-
-  self.clearTimeout = function(timeoutKey) {
-    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
-  };
-
-  self.clearInterval = function(timeoutKey) {
-    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
-  };
-
-};
-
-jasmine.FakeTimer.prototype.reset = function() {
-  this.timeoutsMade = 0;
-  this.scheduledFunctions = {};
-  this.nowMillis = 0;
-};
-
-jasmine.FakeTimer.prototype.tick = function(millis) {
-  var oldMillis = this.nowMillis;
-  var newMillis = oldMillis + millis;
-  this.runFunctionsWithinRange(oldMillis, newMillis);
-  this.nowMillis = newMillis;
-};
-
-jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
-  var scheduledFunc;
-  var funcsToRun = [];
-  for (var timeoutKey in this.scheduledFunctions) {
-    scheduledFunc = this.scheduledFunctions[timeoutKey];
-    if (scheduledFunc != jasmine.undefined &&
-        scheduledFunc.runAtMillis >= oldMillis &&
-        scheduledFunc.runAtMillis <= nowMillis) {
-      funcsToRun.push(scheduledFunc);
-      this.scheduledFunctions[timeoutKey] = jasmine.undefined;
-    }
-  }
-
-  if (funcsToRun.length > 0) {
-    funcsToRun.sort(function(a, b) {
-      return a.runAtMillis - b.runAtMillis;
-    });
-    for (var i = 0; i < funcsToRun.length; ++i) {
-      try {
-        var funcToRun = funcsToRun[i];
-        this.nowMillis = funcToRun.runAtMillis;
-        funcToRun.funcToCall();
-        if (funcToRun.recurring) {
-          this.scheduleFunction(funcToRun.timeoutKey,
-              funcToRun.funcToCall,
-              funcToRun.millis,
-              true);
-        }
-      } catch(e) {
-      }
-    }
-    this.runFunctionsWithinRange(oldMillis, nowMillis);
-  }
-};
-
-jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
-  this.scheduledFunctions[timeoutKey] = {
-    runAtMillis: this.nowMillis + millis,
-    funcToCall: funcToCall,
-    recurring: recurring,
-    timeoutKey: timeoutKey,
-    millis: millis
-  };
-};
-
-/**
- * @namespace
- */
-jasmine.Clock = {
-  defaultFakeTimer: new jasmine.FakeTimer(),
-
-  reset: function() {
-    jasmine.Clock.assertInstalled();
-    jasmine.Clock.defaultFakeTimer.reset();
-  },
-
-  tick: function(millis) {
-    jasmine.Clock.assertInstalled();
-    jasmine.Clock.defaultFakeTimer.tick(millis);
-  },
-
-  runFunctionsWithinRange: function(oldMillis, nowMillis) {
-    jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
-  },
-
-  scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
-    jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
-  },
-
-  useMock: function() {
-    if (!jasmine.Clock.isInstalled()) {
-      var spec = jasmine.getEnv().currentSpec;
-      spec.after(jasmine.Clock.uninstallMock);
-
-      jasmine.Clock.installMock();
-    }
-  },
-
-  installMock: function() {
-    jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
-  },
-
-  uninstallMock: function() {
-    jasmine.Clock.assertInstalled();
-    jasmine.Clock.installed = jasmine.Clock.real;
-  },
-
-  real: {
-    setTimeout: jasmine.getGlobal().setTimeout,
-    clearTimeout: jasmine.getGlobal().clearTimeout,
-    setInterval: jasmine.getGlobal().setInterval,
-    clearInterval: jasmine.getGlobal().clearInterval
-  },
-
-  assertInstalled: function() {
-    if (!jasmine.Clock.isInstalled()) {
-      throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
-    }
-  },
-
-  isInstalled: function() {
-    return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
-  },
-
-  installed: null
-};
-jasmine.Clock.installed = jasmine.Clock.real;
-
-//else for IE support
-jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
-  if (jasmine.Clock.installed.setTimeout.apply) {
-    return jasmine.Clock.installed.setTimeout.apply(this, arguments);
-  } else {
-    return jasmine.Clock.installed.setTimeout(funcToCall, millis);
-  }
-};
-
-jasmine.getGlobal().setInterval = function(funcToCall, millis) {
-  if (jasmine.Clock.installed.setInterval.apply) {
-    return jasmine.Clock.installed.setInterval.apply(this, arguments);
-  } else {
-    return jasmine.Clock.installed.setInterval(funcToCall, millis);
-  }
-};
-
-jasmine.getGlobal().clearTimeout = function(timeoutKey) {
-  if (jasmine.Clock.installed.clearTimeout.apply) {
-    return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
-  } else {
-    return jasmine.Clock.installed.clearTimeout(timeoutKey);
-  }
-};
-
-jasmine.getGlobal().clearInterval = function(timeoutKey) {
-  if (jasmine.Clock.installed.clearTimeout.apply) {
-    return jasmine.Clock.installed.clearInterval.apply(this, arguments);
-  } else {
-    return jasmine.Clock.installed.clearInterval(timeoutKey);
-  }
-};
-
-/**
- * @constructor
- */
-jasmine.MultiReporter = function() {
-  this.subReporters_ = [];
-};
-jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
-
-jasmine.MultiReporter.prototype.addReporter = function(reporter) {
-  this.subReporters_.push(reporter);
-};
-
-(function() {
-  var functionNames = [
-    "reportRunnerStarting",
-    "reportRunnerResults",
-    "reportSuiteResults",
-    "reportSpecStarting",
-    "reportSpecResults",
-    "log"
-  ];
-  for (var i = 0; i < functionNames.length; i++) {
-    var functionName = functionNames[i];
-    jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
-      return function() {
-        for (var j = 0; j < this.subReporters_.length; j++) {
-          var subReporter = this.subReporters_[j];
-          if (subReporter[functionName]) {
-            subReporter[functionName].apply(subReporter, arguments);
-          }
-        }
-      };
-    })(functionName);
-  }
-})();
-/**
- * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
- *
- * @constructor
- */
-jasmine.NestedResults = function() {
-  /**
-   * The total count of results
-   */
-  this.totalCount = 0;
-  /**
-   * Number of passed results
-   */
-  this.passedCount = 0;
-  /**
-   * Number of failed results
-   */
-  this.failedCount = 0;
-  /**
-   * Was this suite/spec skipped?
-   */
-  this.skipped = false;
-  /**
-   * @ignore
-   */
-  this.items_ = [];
-};
-
-/**
- * Roll up the result counts.
- *
- * @param result
- */
-jasmine.NestedResults.prototype.rollupCounts = function(result) {
-  this.totalCount += result.totalCount;
-  this.passedCount += result.passedCount;
-  this.failedCount += result.failedCount;
-};
-
-/**
- * Adds a log message.
- * @param values Array of message parts which will be concatenated later.
- */
-jasmine.NestedResults.prototype.log = function(values) {
-  this.items_.push(new jasmine.MessageResult(values));
-};
-
-/**
- * Getter for the results: message & results.
- */
-jasmine.NestedResults.prototype.getItems = function() {
-  return this.items_;
-};
-
-/**
- * Adds a result, tracking counts (total, passed, & failed)
- * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
- */
-jasmine.NestedResults.prototype.addResult = function(result) {
-  if (result.type != 'log') {
-    if (result.items_) {
-      this.rollupCounts(result);
-    } else {
-      this.totalCount++;
-      if (result.passed()) {
-        this.passedCount++;
-      } else {
-        this.failedCount++;
-      }
-    }
-  }
-  this.items_.push(result);
-};
-
-/**
- * @returns {Boolean} True if <b>everything</b> below passed
- */
-jasmine.NestedResults.prototype.passed = function() {
-  return this.passedCount === this.totalCount;
-};
-/**
- * Base class for pretty printing for expectation results.
- */
-jasmine.PrettyPrinter = function() {
-  this.ppNestLevel_ = 0;
-};
-
-/**
- * Formats a value in a nice, human-readable string.
- *
- * @param value
- */
-jasmine.PrettyPrinter.prototype.format = function(value) {
-  if (this.ppNestLevel_ > 40) {
-    throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
-  }
-
-  this.ppNestLevel_++;
-  try {
-    if (value === jasmine.undefined) {
-      this.emitScalar('undefined');
-    } else if (value === null) {
-      this.emitScalar('null');
-    } else if (value === jasmine.getGlobal()) {
-      this.emitScalar('<global>');
-    } else if (value.jasmineToString) {
-      this.emitScalar(value.jasmineToString());
-    } else if (typeof value === 'string') {
-      this.emitString(value);
-    } else if (jasmine.isSpy(value)) {
-      this.emitScalar("spy on " + value.identity);
-    } else if (value instanceof RegExp) {
-      this.emitScalar(value.toString());
-    } else if (typeof value === 'function') {
-      this.emitScalar('Function');
-    } else if (typeof value.nodeType === 'number') {
-      this.emitScalar('HTMLNode');
-    } else if (value instanceof Date) {
-      this.emitScalar('Date(' + value + ')');
-    } else if (value.__Jasmine_been_here_before__) {
-      this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
-    } else if (jasmine.isArray_(value) || typeof value == 'object') {
-      value.__Jasmine_been_here_before__ = true;
-      if (jasmine.isArray_(value)) {
-        this.emitArray(value);
-      } else {
-        this.emitObject(value);
-      }
-      delete value.__Jasmine_been_here_before__;
-    } else {
-      this.emitScalar(value.toString());
-    }
-  } finally {
-    this.ppNestLevel_--;
-  }
-};
-
-jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
-  for (var property in obj) {
-    if (property == '__Jasmine_been_here_before__') continue;
-    fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && 
-                                         obj.__lookupGetter__(property) !== null) : false);
-  }
-};
-
-jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
-jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
-jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
-jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
-
-jasmine.StringPrettyPrinter = function() {
-  jasmine.PrettyPrinter.call(this);
-
-  this.string = '';
-};
-jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
-
-jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
-  this.append(value);
-};
-
-jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
-  this.append("'" + value + "'");
-};
-
-jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
-  this.append('[ ');
-  for (var i = 0; i < array.length; i++) {
-    if (i > 0) {
-      this.append(', ');
-    }
-    this.format(array[i]);
-  }
-  this.append(' ]');
-};
-
-jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
-  var self = this;
-  this.append('{ ');
-  var first = true;
-
-  this.iterateObject(obj, function(property, isGetter) {
-    if (first) {
-      first = false;
-    } else {
-      self.append(', ');
-    }
-
-    self.append(property);
-    self.append(' : ');
-    if (isGetter) {
-      self.append('<getter>');
-    } else {
-      self.format(obj[property]);
-    }
-  });
-
-  this.append(' }');
-};
-
-jasmine.StringPrettyPrinter.prototype.append = function(value) {
-  this.string += value;
-};
-jasmine.Queue = function(env) {
-  this.env = env;
-  this.blocks = [];
-  this.running = false;
-  this.index = 0;
-  this.offset = 0;
-  this.abort = false;
-};
-
-jasmine.Queue.prototype.addBefore = function(block) {
-  this.blocks.unshift(block);
-};
-
-jasmine.Queue.prototype.add = function(block) {
-  this.blocks.push(block);
-};
-
-jasmine.Queue.prototype.insertNext = function(block) {
-  this.blocks.splice((this.index + this.offset + 1), 0, block);
-  this.offset++;
-};
-
-jasmine.Queue.prototype.start = function(onComplete) {
-  this.running = true;
-  this.onComplete = onComplete;
-  this.next_();
-};
-
-jasmine.Queue.prototype.isRunning = function() {
-  return this.running;
-};
-
-jasmine.Queue.LOOP_DONT_RECURSE = true;
-
-jasmine.Queue.prototype.next_ = function() {
-  var self = this;
-  var goAgain = true;
-
-  while (goAgain) {
-    goAgain = false;
-    
-    if (self.index < self.blocks.length && !this.abort) {
-      var calledSynchronously = true;
-      var completedSynchronously = false;
-
-      var onComplete = function () {
-        if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
-          completedSynchronously = true;
-          return;
-        }
-
-        if (self.blocks[self.index].abort) {
-          self.abort = true;
-        }
-
-        self.offset = 0;
-        self.index++;
-
-        var now = new Date().getTime();
-        if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
-          self.env.lastUpdate = now;
-          self.env.setTimeout(function() {
-            self.next_();
-          }, 0);
-        } else {
-          if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
-            goAgain = true;
-          } else {
-            self.next_();
-          }
-        }
-      };
-      self.blocks[self.index].execute(onComplete);
-
-      calledSynchronously = false;
-      if (completedSynchronously) {
-        onComplete();
-      }
-      
-    } else {
-      self.running = false;
-      if (self.onComplete) {
-        self.onComplete();
-      }
-    }
-  }
-};
-
-jasmine.Queue.prototype.results = function() {
-  var results = new jasmine.NestedResults();
-  for (var i = 0; i < this.blocks.length; i++) {
-    if (this.blocks[i].results) {
-      results.addResult(this.blocks[i].results());
-    }
-  }
-  return results;
-};
-
-
-/**
- * Runner
- *
- * @constructor
- * @param {jasmine.Env} env
- */
-jasmine.Runner = function(env) {
-  var self = this;
-  self.env = env;
-  self.queue = new jasmine.Queue(env);
-  self.before_ = [];
-  self.after_ = [];
-  self.suites_ = [];
-};
-
-jasmine.Runner.prototype.execute = function() {
-  var self = this;
-  if (self.env.reporter.reportRunnerStarting) {
-    self.env.reporter.reportRunnerStarting(this);
-  }
-  self.queue.start(function () {
-    self.finishCallback();
-  });
-};
-
-jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
-  beforeEachFunction.typeName = 'beforeEach';
-  this.before_.splice(0,0,beforeEachFunction);
-};
-
-jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
-  afterEachFunction.typeName = 'afterEach';
-  this.after_.splice(0,0,afterEachFunction);
-};
-
-
-jasmine.Runner.prototype.finishCallback = function() {
-  this.env.reporter.reportRunnerResults(this);
-};
-
-jasmine.Runner.prototype.addSuite = function(suite) {
-  this.suites_.push(suite);
-};
-
-jasmine.Runner.prototype.add = function(block) {
-  if (block instanceof jasmine.Suite) {
-    this.addSuite(block);
-  }
-  this.queue.add(block);
-};
-
-jasmine.Runner.prototype.specs = function () {
-  var suites = this.suites();
-  var specs = [];
-  for (var i = 0; i < suites.length; i++) {
-    specs = specs.concat(suites[i].specs());
-  }
-  return specs;
-};
-
-jasmine.Runner.prototype.suites = function() {
-  return this.suites_;
-};
-
-jasmine.Runner.prototype.topLevelSuites = function() {
-  var topLevelSuites = [];
-  for (var i = 0; i < this.suites_.length; i++) {
-    if (!this.suites_[i].parentSuite) {
-      topLevelSuites.push(this.suites_[i]);
-    }
-  }
-  return topLevelSuites;
-};
-
-jasmine.Runner.prototype.results = function() {
-  return this.queue.results();
-};
-/**
- * Internal representation of a Jasmine specification, or test.
- *
- * @constructor
- * @param {jasmine.Env} env
- * @param {jasmine.Suite} suite
- * @param {String} description
- */
-jasmine.Spec = function(env, suite, description) {
-  if (!env) {
-    throw new Error('jasmine.Env() required');
-  }
-  if (!suite) {
-    throw new Error('jasmine.Suite() required');
-  }
-  var spec = this;
-  spec.id = env.nextSpecId ? env.nextSpecId() : null;
-  spec.env = env;
-  spec.suite = suite;
-  spec.description = description;
-  spec.queue = new jasmine.Queue(env);
-
-  spec.afterCallbacks = [];
-  spec.spies_ = [];
-
-  spec.results_ = new jasmine.NestedResults();
-  spec.results_.description = description;
-  spec.matchersClass = null;
-};
-
-jasmine.Spec.prototype.getFullName = function() {
-  return this.suite.getFullName() + ' ' + this.description + '.';
-};
-
-
-jasmine.Spec.prototype.results = function() {
-  return this.results_;
-};
-
-/**
- * All parameters are pretty-printed and concatenated together, then written to the spec's output.
- *
- * Be careful not to leave calls to <code>jasmine.log</code> in production code.
- */
-jasmine.Spec.prototype.log = function() {
-  return this.results_.log(arguments);
-};
-
-jasmine.Spec.prototype.runs = function (func) {
-  var block = new jasmine.Block(this.env, func, this);
-  this.addToQueue(block);
-  return this;
-};
-
-jasmine.Spec.prototype.addToQueue = function (block) {
-  if (this.queue.isRunning()) {
-    this.queue.insertNext(block);
-  } else {
-    this.queue.add(block);
-  }
-};
-
-/**
- * @param {jasmine.ExpectationResult} result
- */
-jasmine.Spec.prototype.addMatcherResult = function(result) {
-  this.results_.addResult(result);
-};
-
-jasmine.Spec.prototype.expect = function(actual) {
-  var positive = new (this.getMatchersClass_())(this.env, actual, this);
-  positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
-  return positive;
-};
-
-/**
- * Waits a fixed time period before moving to the next block.
- *
- * @deprecated Use waitsFor() instead
- * @param {Number} timeout milliseconds to wait
- */
-jasmine.Spec.prototype.waits = function(timeout) {
-  var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
-  this.addToQueue(waitsFunc);
-  return this;
-};
-
-/**
- * Waits for the latchFunction to return true before proceeding to the next block.
- *
- * @param {Function} latchFunction
- * @param {String} optional_timeoutMessage
- * @param {Number} optional_timeout
- */
-jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
-  var latchFunction_ = null;
-  var optional_timeoutMessage_ = null;
-  var optional_timeout_ = null;
-
-  for (var i = 0; i < arguments.length; i++) {
-    var arg = arguments[i];
-    switch (typeof arg) {
-      case 'function':
-        latchFunction_ = arg;
-        break;
-      case 'string':
-        optional_timeoutMessage_ = arg;
-        break;
-      case 'number':
-        optional_timeout_ = arg;
-        break;
-    }
-  }
-
-  var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
-  this.addToQueue(waitsForFunc);
-  return this;
-};
-
-jasmine.Spec.prototype.fail = function (e) {
-  var expectationResult = new jasmine.ExpectationResult({
-    passed: false,
-    message: e ? jasmine.util.formatException(e) : 'Exception',
-    trace: { stack: e.stack }
-  });
-  this.results_.addResult(expectationResult);
-};
-
-jasmine.Spec.prototype.getMatchersClass_ = function() {
-  return this.matchersClass || this.env.matchersClass;
-};
-
-jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
-  var parent = this.getMatchersClass_();
-  var newMatchersClass = function() {
-    parent.apply(this, arguments);
-  };
-  jasmine.util.inherit(newMatchersClass, parent);
-  jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
-  this.matchersClass = newMatchersClass;
-};
-
-jasmine.Spec.prototype.finishCallback = function() {
-  this.env.reporter.reportSpecResults(this);
-};
-
-jasmine.Spec.prototype.finish = function(onComplete) {
-  this.removeAllSpies();
-  this.finishCallback();
-  if (onComplete) {
-    onComplete();
-  }
-};
-
-jasmine.Spec.prototype.after = function(doAfter) {
-  if (this.queue.isRunning()) {
-    this.queue.add(new jasmine.Block(this.env, doAfter, this));
-  } else {
-    this.afterCallbacks.unshift(doAfter);
-  }
-};
-
-jasmine.Spec.prototype.execute = function(onComplete) {
-  var spec = this;
-  if (!spec.env.specFilter(spec)) {
-    spec.results_.skipped = true;
-    spec.finish(onComplete);
-    return;
-  }
-
-  this.env.reporter.reportSpecStarting(this);
-
-  spec.env.currentSpec = spec;
-
-  spec.addBeforesAndAftersToQueue();
-
-  spec.queue.start(function () {
-    spec.finish(onComplete);
-  });
-};
-
-jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
-  var runner = this.env.currentRunner();
-  var i;
-
-  for (var suite = this.suite; suite; suite = suite.parentSuite) {
-    for (i = 0; i < suite.before_.length; i++) {
-      this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
-    }
-  }
-  for (i = 0; i < runner.before_.length; i++) {
-    this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
-  }
-  for (i = 0; i < this.afterCallbacks.length; i++) {
-    this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));
-  }
-  for (suite = this.suite; suite; suite = suite.parentSuite) {
-    for (i = 0; i < suite.after_.length; i++) {
-      this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));
-    }
-  }
-  for (i = 0; i < runner.after_.length; i++) {
-    this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));
-  }
-};
-
-jasmine.Spec.prototype.explodes = function() {
-  throw 'explodes function should not have been called';
-};
-
-jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
-  if (obj == jasmine.undefined) {
-    throw "spyOn could not find an object to spy upon for " + methodName + "()";
-  }
-
-  if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
-    throw methodName + '() method does not exist';
-  }
-
-  if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
-    throw new Error(methodName + ' has already been spied upon');
-  }
-
-  var spyObj = jasmine.createSpy(methodName);
-
-  this.spies_.push(spyObj);
-  spyObj.baseObj = obj;
-  spyObj.methodName = methodName;
-  spyObj.originalValue = obj[methodName];
-
-  obj[methodName] = spyObj;
-
-  return spyObj;
-};
-
-jasmine.Spec.prototype.removeAllSpies = function() {
-  for (var i = 0; i < this.spies_.length; i++) {
-    var spy = this.spies_[i];
-    spy.baseObj[spy.methodName] = spy.originalValue;
-  }
-  this.spies_ = [];
-};
-
-/**
- * Internal representation of a Jasmine suite.
- *
- * @constructor
- * @param {jasmine.Env} env
- * @param {String} description
- * @param {Function} specDefinitions
- * @param {jasmine.Suite} parentSuite
- */
-jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
-  var self = this;
-  self.id = env.nextSuiteId ? env.nextSuiteId() : null;
-  self.description = description;
-  self.queue = new jasmine.Queue(env);
-  self.parentSuite = parentSuite;
-  self.env = env;
-  self.before_ = [];
-  self.after_ = [];
-  self.children_ = [];
-  self.suites_ = [];
-  self.specs_ = [];
-};
-
-jasmine.Suite.prototype.getFullName = function() {
-  var fullName = this.description;
-  for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
-    fullName = parentSuite.description + ' ' + fullName;
-  }
-  return fullName;
-};
-
-jasmine.Suite.prototype.finish = function(onComplete) {
-  this.env.reporter.reportSuiteResults(this);
-  this.finished = true;
-  if (typeof(onComplete) == 'function') {
-    onComplete();
-  }
-};
-
-jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
-  beforeEachFunction.typeName = 'beforeEach';
-  this.before_.unshift(beforeEachFunction);
-};
-
-jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
-  afterEachFunction.typeName = 'afterEach';
-  this.after_.unshift(afterEachFunction);
-};
-
-jasmine.Suite.prototype.results = function() {
-  return this.queue.results();
-};
-
-jasmine.Suite.prototype.add = function(suiteOrSpec) {
-  this.children_.push(suiteOrSpec);
-  if (suiteOrSpec instanceof jasmine.Suite) {
-    this.suites_.push(suiteOrSpec);
-    this.env.currentRunner().addSuite(suiteOrSpec);
-  } else {
-    this.specs_.push(suiteOrSpec);
-  }
-  this.queue.add(suiteOrSpec);
-};
-
-jasmine.Suite.prototype.specs = function() {
-  return this.specs_;
-};
-
-jasmine.Suite.prototype.suites = function() {
-  return this.suites_;
-};
-
-jasmine.Suite.prototype.children = function() {
-  return this.children_;
-};
-
-jasmine.Suite.prototype.execute = function(onComplete) {
-  var self = this;
-  this.queue.start(function () {
-    self.finish(onComplete);
-  });
-};
-jasmine.WaitsBlock = function(env, timeout, spec) {
-  this.timeout = timeout;
-  jasmine.Block.call(this, env, null, spec);
-};
-
-jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
-
-jasmine.WaitsBlock.prototype.execute = function (onComplete) {
-  if (jasmine.VERBOSE) {
-    this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
-  }
-  this.env.setTimeout(function () {
-    onComplete();
-  }, this.timeout);
-};
-/**
- * A block which waits for some condition to become true, with timeout.
- *
- * @constructor
- * @extends jasmine.Block
- * @param {jasmine.Env} env The Jasmine environment.
- * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
- * @param {Function} latchFunction A function which returns true when the desired condition has been met.
- * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
- * @param {jasmine.Spec} spec The Jasmine spec.
- */
-jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
-  this.timeout = timeout || env.defaultTimeoutInterval;
-  this.latchFunction = latchFunction;
-  this.message = message;
-  this.totalTimeSpentWaitingForLatch = 0;
-  jasmine.Block.call(this, env, null, spec);
-};
-jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
-
-jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
-
-jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
-  if (jasmine.VERBOSE) {
-    this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
-  }
-  var latchFunctionResult;
-  try {
-    latchFunctionResult = this.latchFunction.apply(this.spec);
-  } catch (e) {
-    this.spec.fail(e);
-    onComplete();
-    return;
-  }
-
-  if (latchFunctionResult) {
-    onComplete();
-  } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
-    var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
-    this.spec.fail({
-      name: 'timeout',
-      message: message
-    });
-
-    this.abort = true;
-    onComplete();
-  } else {
-    this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
-    var self = this;
-    this.env.setTimeout(function() {
-      self.execute(onComplete);
-    }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
-  }
-};
-
-jasmine.version_= {
-  "major": 1,
-  "minor": 2,
-  "build": 0,
-  "revision": 1333310630,
-  "release_candidate": 1
-};

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/accelerometer.html
----------------------------------------------------------------------
diff --git a/autotest/pages/accelerometer.html b/autotest/pages/accelerometer.html
deleted file mode 100644
index 52b333b..0000000
--- a/autotest/pages/accelerometer.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!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>Cordova: Accelerometer API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/accelerometer.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/all.html
----------------------------------------------------------------------
diff --git a/autotest/pages/all.html b/autotest/pages/all.html
deleted file mode 100644
index c006db1..0000000
--- a/autotest/pages/all.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!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>Cordova: API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/accelerometer.tests.js"></script>
-  <script type="text/javascript" src="../tests/battery.tests.js"></script>
-  <script type="text/javascript" src="../tests/bridge.tests.js"></script>
-  <script type="text/javascript" src="../tests/capture.tests.js"></script>
-  <script type="text/javascript" src="../tests/compass.tests.js"></script>
-  <script type="text/javascript" src="../tests/contacts.tests.js"></script>
-  <script type="text/javascript" src="../tests/camera.tests.js"></script>
-  <script type="text/javascript" src="../tests/datauri.tests.js"></script>
-  <script type="text/javascript" src="../tests/device.tests.js"></script>
-  <script type="text/javascript" src="../tests/file.tests.js"></script>
-  <script type="text/javascript" src="../tests/filetransfer.tests.js"></script>
-  <script type="text/javascript" src="../tests/geolocation.tests.js"></script>
-  <script type="text/javascript" src="../tests/globalization.tests.js"></script>
-  <script type="text/javascript" src="../tests/media.tests.js"></script>
-  <script type="text/javascript" src="../tests/network.tests.js"></script>
-  <script type="text/javascript" src="../tests/notification.tests.js"></script>
-  <script type="text/javascript" src="../tests/platform.tests.js"></script>
-  <script type="text/javascript" src="../tests/storage.tests.js"></script>
-  <script type="text/javascript" src="../tests/splashscreen.tests.js"></script>
-  <script type="text/javascript" src="../tests/localXHR.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./all.js"></script>      
-</head>
-
-<body>
-  <a class="backBtn">Back</a>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/all.js
----------------------------------------------------------------------
diff --git a/autotest/pages/all.js b/autotest/pages/all.js
deleted file mode 100644
index bc72b29..0000000
--- a/autotest/pages/all.js
+++ /dev/null
@@ -1,46 +0,0 @@
-var root, temp_root, persistent_root;
-
-document.addEventListener('deviceready', function () {
-    // one-time retrieval of the root file system entry
-    var onError = function(e) {
-        console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.');
-        console.log(JSON.stringify(e));
-    };
-
-    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
-        function(fileSystem) {
-            console.log('File API test Init: Setting PERSISTENT FS.');
-            root = fileSystem.root; // set in file.tests.js
-            persistent_root = root;
-
-            // Once root is set up, fire off tests
-            var jasmineEnv = jasmine.getEnv();
-            jasmineEnv.updateInterval = 1000;
-
-            var htmlReporter = new jasmine.HtmlReporter();
-            jasmineEnv.addReporter(htmlReporter);
-
-            // the following will only be defined if the Medic plugin is loaded
-            if('medic' in window) {
-                if( medic.isEnabled() ) {
-                    jasmineEnv.addReporter(medic.getJSReporter());
-                }
-            }
-
-            jasmineEnv.specFilter = function(spec) {
-              return htmlReporter.specFilter(spec);
-            };
-
-            jasmineEnv.execute();
-        }, onError);
-    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
-        function(fileSystem) {
-            console.log('File API test Init: Setting TEMPORARY FS.');
-            temp_root = fileSystem.root; // set in file.tests.js
-        }, onError);
-}, false);
-
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/battery.html
----------------------------------------------------------------------
diff --git a/autotest/pages/battery.html b/autotest/pages/battery.html
deleted file mode 100644
index 2063417..0000000
--- a/autotest/pages/battery.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!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>Cordova: Battery API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/battery.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a class="backBtn">Back</a>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/bridge.html
----------------------------------------------------------------------
diff --git a/autotest/pages/bridge.html b/autotest/pages/bridge.html
deleted file mode 100644
index 822d9ec..0000000
--- a/autotest/pages/bridge.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Device API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/bridge.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/camera.html
----------------------------------------------------------------------
diff --git a/autotest/pages/camera.html b/autotest/pages/camera.html
deleted file mode 100644
index 91843d7..0000000
--- a/autotest/pages/camera.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Camera API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/camera.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a href="javascript:" class="backBtn">Back</a>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/pages/capture.html
----------------------------------------------------------------------
diff --git a/autotest/pages/capture.html b/autotest/pages/capture.html
deleted file mode 100644
index bac570f..0000000
--- a/autotest/pages/capture.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!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>Cordova: Capture API Specs</title>
-
-  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-  <!-- Load jasmine -->
-  <link href="../jasmine.css" rel="stylesheet"/>
-  <script type="text/javascript" src="../jasmine.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
-  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
-  <script type="text/javascript" src="../html/ReporterView.js"></script>
-  <script type="text/javascript" src="../html/SpecView.js"></script>
-  <script type="text/javascript" src="../html/SuiteView.js"></script>
-  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
-
-  <!-- Source -->
-  <script type="text/javascript" src="../../cordova-incl.js"></script>
-
-  <!-- Load Test Runner -->
-  <script type="text/javascript" src="../test-runner.js"></script>
-
-  <!-- Tests -->
-  <script type="text/javascript" src="../tests/capture.tests.js"></script>
-  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
-</head>
-
-<body>
-  <a class="backBtn">Back</a>
-</body>
-</html>
-


[15/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/file.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/file.tests.js b/autotest/tests/file.tests.js
deleted file mode 100644
index 50c9e8e..0000000
--- a/autotest/tests/file.tests.js
+++ /dev/null
@@ -1,4451 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('File API', function() {
-    // Adding a Jasmine helper matcher, to report errors when comparing to FileError better.
-    var fileErrorMap = {
-        1: 'NOT_FOUND_ERR',
-        2: 'SECURITY_ERR',
-        3: 'ABORT_ERR',
-        4: 'NOT_READABLE_ERR',
-        5: 'ENCODING_ERR',
-        6: 'NO_MODIFICATION_ALLOWED_ERR',
-        7: 'INVALID_STATE_ERR',
-        8: 'SYNTAX_ERR',
-        9: 'INVALID_MODIFICATION_ERR',
-        10:'QUOTA_EXCEEDED_ERR',
-        11:'TYPE_MISMATCH_ERR',
-        12:'PATH_EXISTS_ERR'
-    };
-    beforeEach(function() {
-        this.addMatchers({
-            toBeFileError: function(code) {
-                var error = this.actual;
-                this.message = function(){
-                    return "Expected FileError with code " + fileErrorMap[error.code] + " (" + error.code + ") to be " + fileErrorMap[code] + "(" + code + ")";
-                };
-                return (error.code == code);
-            },
-            toCanonicallyMatch:function(path){
-                this.message = function(){
-                    return "Expected paths to match : " + path + " should be " + this.actual;
-                };
-
-                var a = path.split("/").join("").split("\\").join("");
-                var b = this.actual.split("/").join("").split("\\").join("");
-
-                return a == b;
-            }
-        });
-    });
-
-    // HELPER FUNCTIONS
-
-    // deletes specified file or directory
-    var deleteEntry = function(name, success, error) {
-        // deletes entry, if it exists
-        window.resolveLocalFileSystemURI(root.toURL() + '/' + name,
-            function(entry) {
-                if (entry.isDirectory === true) {
-                    entry.removeRecursively(success, error);
-                } else {
-                    entry.remove(success, error);
-                }
-            }, success);
-    };
-    // deletes file, if it exists, then invokes callback
-    var deleteFile = function(fileName, callback) {
-        root.getFile(fileName, null,
-                // remove file system entry
-                function(entry) {
-                    entry.remove(callback, function() { console.log('[ERROR] deleteFile cleanup method invoked fail callback.'); });
-                },
-                // doesn't exist
-                callback);
-    };
-    // deletes and re-creates the specified file
-    var createFile = function(fileName, success, error) {
-        deleteEntry(fileName, function() {
-            root.getFile(fileName, {create: true}, success, error);
-        }, error);
-    };
-    // deletes and re-creates the specified directory
-    var createDirectory = function(dirName, success, error) {
-        deleteEntry(dirName, function() {
-           root.getDirectory(dirName, {create: true}, success, error);
-        }, error);
-    };
-
-    var createFail = function(module) {
-        return jasmine.createSpy("Fail").andCallFake(function(err) {
-            console.log('[ERROR ' + module + '] ' + JSON.stringify(err));
-        });
-    };
-
-    var joinURL = function(base, extension) {
-        if (base.charAt(base.length-1) !== '/' && extension.charAt(0) !== '/') {
-            return base + '/' + extension;
-        }
-        if (base.charAt(base.length-1) === '/' && extension.charAt(0) === '/') {
-            return base + exension.substring(1);
-        }
-        return base + extension;
-    };
-
-    var createWin = function(module) {
-        return jasmine.createSpy("Win").andCallFake(function() {
-            console.log('[ERROR ' + module + '] Unexpected success callback');
-        });
-    };
-
-    describe('FileError object', function() {
-        it("file.spec.1 should define FileError constants", function() {
-            expect(FileError.NOT_FOUND_ERR).toBe(1);
-            expect(FileError.SECURITY_ERR).toBe(2);
-            expect(FileError.ABORT_ERR).toBe(3);
-            expect(FileError.NOT_READABLE_ERR).toBe(4);
-            expect(FileError.ENCODING_ERR).toBe(5);
-            expect(FileError.NO_MODIFICATION_ALLOWED_ERR).toBe(6);
-            expect(FileError.INVALID_STATE_ERR).toBe(7);
-            expect(FileError.SYNTAX_ERR).toBe(8);
-            expect(FileError.INVALID_MODIFICATION_ERR).toBe(9);
-            expect(FileError.QUOTA_EXCEEDED_ERR).toBe(10);
-            expect(FileError.TYPE_MISMATCH_ERR).toBe(11);
-            expect(FileError.PATH_EXISTS_ERR).toBe(12);
-        });
-    });
-
-    describe('LocalFileSystem', function() {
-
-        it("file.spec.2 should define LocalFileSystem constants", function() {
-            expect(LocalFileSystem.TEMPORARY).toBe(0);
-            expect(LocalFileSystem.PERSISTENT).toBe(1);
-        });
-
-        describe('window.requestFileSystem', function() {
-            it("file.spec.3 should be defined", function() {
-                expect(window.requestFileSystem).toBeDefined();
-            });
-            it("file.spec.4 should be able to retrieve a PERSISTENT file system", function() {
-                var win = jasmine.createSpy().andCallFake(function(fileSystem) {
-                    expect(fileSystem).toBeDefined();
-                    expect(fileSystem.name).toBeDefined();
-                    expect(fileSystem.name).toBe("persistent");
-                    expect(fileSystem.root).toBeDefined();
-                    expect(fileSystem.root.filesystem).toBeDefined();
-                    // Shouldn't use cdvfile by default.
-                    expect(fileSystem.root.toURL()).not.toMatch(/^cdvfile:/);
-                    // All DirectoryEntry URLs should always have a trailing slash.
-                    expect(fileSystem.root.toURL()).toMatch(/\/$/);
-                }),
-                fail = createFail('window.requestFileSystem');
-
-                // retrieve PERSISTENT file system
-                runs(function() {
-                    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, win, fail);
-                });
-
-                waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(fail).not.toHaveBeenCalled();
-                    expect(win).toHaveBeenCalled();
-                });
-            });
-            it("file.spec.5 should be able to retrieve a TEMPORARY file system", function() {
-                var win = jasmine.createSpy().andCallFake(function(fileSystem) {
-                    expect(fileSystem).toBeDefined();
-                    expect(fileSystem.name).toBeDefined();
-                    expect(fileSystem.name).toBe("temporary");
-                    expect(fileSystem.root).toBeDefined();
-                    expect(fileSystem.root.filesystem).toBeDefined();
-                    expect(fileSystem.root.filesystem).toBe(fileSystem);
-                }),
-                fail = createFail('window.requestFileSystem');
-
-                // Request the file system
-                runs(function() {
-                    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, win, fail);
-                });
-
-                waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(fail).not.toHaveBeenCalled();
-                    expect(win).toHaveBeenCalled();
-                });
-            });
-            it("file.spec.6 should error if you request a file system that is too large", function() {
-                var fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.QUOTA_EXCEEDED_ERR);
-                }),
-                win = createWin('window.requestFileSystem');
-
-                // Request the file system
-                runs(function() {
-                    window.requestFileSystem(LocalFileSystem.TEMPORARY, 1000000000000000, win, fail);
-                });
-
-                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(win).not.toHaveBeenCalled();
-                    expect(fail).toHaveBeenCalled();
-                });
-            });
-            it("file.spec.7 should error out if you request a file system that does not exist", function() {
-                var fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.SYNTAX_ERR);
-                }),
-                win = createWin('window.requestFileSystem');
-
-                // Request the file system
-                runs(function() {
-                    window.requestFileSystem(-1, 0, win, fail);
-                });
-
-                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(win).not.toHaveBeenCalled();
-                    expect(fail).toHaveBeenCalled();
-                });
-            });
-        });
-
-        describe('window.resolveLocalFileSystemURI', function() {
-            it("file.spec.3 should be defined", function() {
-                expect(window.resolveLocalFileSystemURI).toBeDefined();
-            });
-            it("file.spec.9 should resolve a valid file name", function() {
-                var createDirectoryFail = createFail('createDirectory');
-                var resolveFail = createFail('resolveLocalFileSystemURI');
-                var fileName = 'file.spec.9';
-                var win = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    expect(fileEntry).toBeDefined();
-                    expect(fileEntry.name).toCanonicallyMatch(fileName);
-                    expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
-                    expect(fileEntry.toURL()).not.toMatch(/\/$/, 'URL should not end with a slash');
-
-                    // cleanup
-                    deleteEntry(fileName);
-                });
-                function gotDirectory(entry) {
-                    // lookup file system entry
-                    window.resolveLocalFileSystemURL(entry.toURL(), win, resolveFail);
-                }
-                createFile(fileName, gotDirectory, createDirectoryFail, createDirectoryFail);
-                waitsForAny(win, resolveFail, createDirectoryFail);
-            });
-            it("file.spec.9.5 should resolve a directory", function() {
-                var createDirectoryFail = createFail('createDirectory');
-                var resolveFail = createFail('resolveLocalFileSystemURI');
-                var fileName = 'file.spec.9.5';
-                var win = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    expect(fileEntry).toBeDefined();
-                    expect(fileEntry.name).toCanonicallyMatch(fileName);
-                    expect(fileEntry.toURL()).not.toMatch(/^cdvfile:/, 'should not use cdvfile URL');
-                    expect(fileEntry.toURL()).toMatch(/\/$/, 'URL end with a slash');
-
-                    // cleanup
-                    deleteEntry(fileName);
-                });
-                function gotDirectory(entry) {
-                    // lookup file system entry
-                    window.resolveLocalFileSystemURL(entry.toURL(), win, resolveFail);
-                }
-                createDirectory(fileName, gotDirectory, createDirectoryFail, createDirectoryFail);
-                waitsForAny(win, resolveFail, createDirectoryFail);
-            });
-            it("file.spec.10 resolve valid file name with parameters", function() {
-                var fileName = "resolve.file.uri.params",
-                win = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    expect(fileEntry).toBeDefined();
-                    if (fileEntry.toURL().toLowerCase().substring(0,10) === "cdvfile://") {
-                        expect(fileEntry.fullPath).toBe("/" + fileName + "?1234567890");
-                    }
-                    expect(fileEntry.name).toBe(fileName);
-
-                    // cleanup
-                    deleteEntry(fileName);
-                }),
-                fail = createFail('window.resolveLocalFileSystemURI');
-                resolveCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    // lookup file system entry
-                    runs(function() {
-                        window.resolveLocalFileSystemURI(entry.toURL() + "?1234567890", win, fail);
-                    });
-
-                    waitsFor(function() { return win.wasCalled; }, "resolveLocalFileSystemURI callback never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(win).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                });
-
-                // create a new file entry
-                runs(function() {
-                    createFile(fileName, resolveCallback, fail);
-                });
-
-                waitsFor(function() { return resolveCallback.wasCalled; }, "createFile callback never called", Tests.TEST_TIMEOUT);
-            });
-            it("file.spec.11 should error (NOT_FOUND_ERR) when resolving (non-existent) invalid file name", function() {
-                var fileName = joinURL(root.toURL(), "this.is.not.a.valid.file.txt");
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                }),
-                win = createWin('window.resolveLocalFileSystemURI');
-
-                // lookup file system entry
-                runs(function() {
-                    window.resolveLocalFileSystemURI(fileName, win, fail);
-                });
-
-                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(fail).toHaveBeenCalled();
-                    expect(win).not.toHaveBeenCalled();
-                });
-            });
-            it("file.spec.12 should error (ENCODING_ERR) when resolving invalid URI with leading /", function() {
-                var fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.ENCODING_ERR);
-                }),
-                win = createWin('window.resolveLocalFileSystemURI');
-
-                // lookup file system entry
-                runs(function() {
-                    window.resolveLocalFileSystemURI("/this.is.not.a.valid.url", win, fail);
-                });
-
-                waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(fail).toHaveBeenCalled();
-                    expect(win).not.toHaveBeenCalled();
-                });
-            });
-        });
-    });
-
-    describe('Metadata interface', function() {
-        it("file.spec.13 should exist and have the right properties", function() {
-            var metadata = new Metadata();
-            expect(metadata).toBeDefined();
-            expect(metadata.modificationTime).toBeDefined();
-        });
-    });
-
-    describe('Flags interface', function() {
-        it("file.spec.13 should exist and have the right properties", function() {
-            var flags = new Flags(false, true);
-            expect(flags).toBeDefined();
-            expect(flags.create).toBeDefined();
-            expect(flags.create).toBe(false);
-            expect(flags.exclusive).toBeDefined();
-            expect(flags.exclusive).toBe(true);
-        });
-    });
-
-    describe('FileSystem interface', function() {
-        it("file.spec.15 should have a root that is a DirectoryEntry", function() {
-            var win = jasmine.createSpy().andCallFake(function(entry) {
-                expect(entry).toBeDefined();
-                expect(entry.isFile).toBe(false);
-                expect(entry.isDirectory).toBe(true);
-                expect(entry.name).toBeDefined();
-                expect(entry.fullPath).toBeDefined();
-                expect(entry.getMetadata).toBeDefined();
-                expect(entry.moveTo).toBeDefined();
-                expect(entry.copyTo).toBeDefined();
-                expect(entry.toURL).toBeDefined();
-                expect(entry.remove).toBeDefined();
-                expect(entry.getParent).toBeDefined();
-                expect(entry.createReader).toBeDefined();
-                expect(entry.getFile).toBeDefined();
-                expect(entry.getDirectory).toBeDefined();
-                expect(entry.removeRecursively).toBeDefined();
-            }),
-            fail = createFail('FileSystem');
-
-            runs(function() {
-                window.resolveLocalFileSystemURI(root.toURL(), win, fail);
-            });
-
-            waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(fail).not.toHaveBeenCalled();
-                expect(win).toHaveBeenCalled();
-            });
-        });
-    });
-
-    describe('DirectoryEntry', function() {
-        it("file.spec.16 getFile: get Entry for file that does not exist", function() {
-            var fileName = "de.no.file",
-                filePath = joinURL(root.fullPath, fileName),
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create:false, exclusive:false, file does not exist
-            runs(function() {
-                root.getFile(fileName, {create:false}, win, fail);
-            });
-
-            waitsFor(function() { return fail.wasCalled; }, "error callback never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(fail).toHaveBeenCalled();
-                expect(win).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.17 getFile: create new file", function() {
-            var fileName = "de.create.file",
-                filePath = joinURL(root.fullPath, fileName),
-                win = jasmine.createSpy().andCallFake(function(entry) {
-                    expect(entry).toBeDefined();
-                    expect(entry.isFile).toBe(true);
-                    expect(entry.isDirectory).toBe(false);
-                    expect(entry.name).toCanonicallyMatch(fileName);
-                    expect(entry.fullPath).toCanonicallyMatch(filePath);
-                    // cleanup
-                    entry.remove(null, null);
-                }),
-                fail = createFail('DirectoryEntry');
-
-            // create:true, exclusive:false, file does not exist
-            runs(function() {
-                root.getFile(fileName, {create: true}, win, fail);
-            });
-
-            waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(win).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.18 getFile: create new file (exclusive)", function() {
-            var fileName = "de.create.exclusive.file",
-                filePath = joinURL(root.fullPath, fileName),
-                win = jasmine.createSpy().andCallFake(function(entry) {
-                    expect(entry).toBeDefined();
-                    expect(entry.isFile).toBe(true);
-                    expect(entry.isDirectory).toBe(false);
-                    expect(entry.name).toBe(fileName);
-                    expect(entry.fullPath).toCanonicallyMatch(filePath);
-
-                    // cleanup
-                    entry.remove(null, null);
-                }),
-                fail = createFail('DirectoryEntry');
-
-            // create:true, exclusive:true, file does not exist
-            runs(function() {
-                root.getFile(fileName, {create: true, exclusive:true}, win, fail);
-            });
-
-            waitsFor(function() { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(win).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.19 getFile: create file that already exists", function() {
-            var fileName = "de.create.existing.file",
-                filePath = joinURL(root.fullPath, fileName),
-                getFile = jasmine.createSpy().andCallFake(function(file) {
-                    // create:true, exclusive:false, file exists
-                    runs(function() {
-                        root.getFile(fileName, {create:true}, win, fail);
-                    });
-
-                    waitsFor(function() { return win.wasCalled; }, "win was never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(win).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = createFail('DirectoryEntry'),
-                win = jasmine.createSpy().andCallFake(function(entry) {
-                    expect(entry).toBeDefined();
-                    expect(entry.isFile).toBe(true);
-                    expect(entry.isDirectory).toBe(false);
-                    expect(entry.name).toCanonicallyMatch(fileName);
-                    expect(entry.fullPath).toCanonicallyMatch(filePath);
-
-                    // cleanup
-                    entry.remove(null, fail);
-                });
-            // create file to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, getFile, fail);
-            });
-
-            waitsFor(function() { return getFile.wasCalled; }, "getFile was never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.20 getFile: create file that already exists (exclusive)", function() {
-            var fileName = "de.create.exclusive.existing.file",
-                filePath = joinURL(root.fullPath, fileName),
-                existingFile,
-                getFile = jasmine.createSpy().andCallFake(function(file) {
-                    existingFile = file;
-                    // create:true, exclusive:true, file exists
-                    runs(function() {
-                        root.getFile(fileName, {create:true, exclusive:true}, win, fail);
-                    });
-
-                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(fail).toHaveBeenCalled();
-                        expect(win).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);
-
-                    // cleanup
-                    existingFile.remove(null, fail);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create file to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, getFile, fail);
-            });
-
-            waitsFor(function() { return getFile.wasCalled; }, "getFile never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.21 DirectoryEntry.getFile: get Entry for existing file", function() {
-            var fileName = "de.get.file",
-                filePath = joinURL(root.fullPath, fileName),
-                win = jasmine.createSpy().andCallFake(function(entry) {
-                    expect(entry).toBeDefined();
-                    expect(entry.isFile).toBe(true);
-                    expect(entry.isDirectory).toBe(false);
-                    expect(entry.name).toCanonicallyMatch(fileName);
-                    expect(entry.fullPath).toCanonicallyMatch(filePath);
-                    expect(entry.filesystem).toBeDefined();
-                    expect(entry.filesystem).toBe(root.filesystem);
-                    entry.remove(null, fail); //clean up
-                }),
-                fail = createFail('DirectoryEntry'),
-                getFile = jasmine.createSpy().andCallFake(function(file) {
-                    // create:false, exclusive:false, file exists
-                    runs(function() {
-                        root.getFile(fileName, {create:false}, win, fail);
-                    });
-
-                    waitsFor(function() { return win.wasCalled; }, "getFile success callback", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(win).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                });
-
-            // create file to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, getFile, fail);
-            });
-
-            waitsFor(function() { return getFile.wasCalled; }, "file creation", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.22 DirectoryEntry.getFile: get FileEntry for invalid path", function() {
-            var fileName = "de:invalid:path",
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.ENCODING_ERR);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create:false, exclusive:false, invalid path
-            runs(function() {
-                root.getFile(fileName, {create:false}, win, fail);
-            });
-
-            waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(fail).toHaveBeenCalled();
-                expect(win).not.toHaveBeenCalled();
-            });
-
-        });
-        it("file.spec.23 DirectoryEntry.getDirectory: get Entry for directory that does not exist", function() {
-            var dirName = "de.no.dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create:false, exclusive:false, directory does not exist
-            runs(function() {
-                root.getDirectory(dirName, {create:false}, win, fail);
-            });
-
-            waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(fail).toHaveBeenCalled();
-                expect(win).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.24 DirectoryEntry.getDirectory: create new dir with space then resolveFileSystemURI", function() {
-            var dirName = "de create dir",
-                dirPath = joinURL(root.fullPath, encodeURIComponent(dirName)),
-                getDir = jasmine.createSpy().andCallFake(function(dirEntry) {
-                    expect(dirEntry.filesystem).toBeDefined();
-                    expect(dirEntry.filesystem).toBe(root.filesystem);
-                    var dirURI = dirEntry.toURL();
-                    // now encode URI and try to resolve
-                    window.resolveLocalFileSystemURI(dirURI, win, fail);
-                }),
-                win = jasmine.createSpy().andCallFake(function(directory) {
-
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.name).toCanonicallyMatch(dirName);
-                    expect(directory.fullPath).toCanonicallyMatch(joinURL(root.fullPath, dirName));
-
-                    // cleanup
-                    directory.remove(null, fail);
-                }),
-                fail = createFail('DirectoryEntry');
-
-            // create:true, exclusive:false, directory does not exist
-            root.getDirectory(dirName, {create: true}, getDir, fail);
-
-            waitsForAny(fail, win);
-        });
-
-        // This test is excluded, and should probably be removed. Filesystem
-        // should always be properly encoded URLs, and *not* raw paths, and it
-        // doesn't make sense to double-encode the URLs and expect that to be
-        // handled by the implementation.
-        // If a particular platform uses paths internally rather than URLs,
-        // then that platform should careful to pass them correctly to its
-        // backend.
-        xit("file.spec.25 DirectoryEntry.getDirectory: create new dir with space resolveFileSystemURI with encoded URI", function() {
-            var dirName = "de create dir2",
-                dirPath = joinURL(root.fullPath, dirName),
-                getDir = jasmine.createSpy().andCallFake(function(dirEntry) {
-                    var dirURI = dirEntry.toURL();
-                    // now encode URI and try to resolve
-                    runs(function() {
-                        window.resolveLocalFileSystemURI(encodeURI(dirURI), win, fail);
-                    });
-
-                    waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(win).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                win = jasmine.createSpy().andCallFake(function(directory) {
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.name).toCanonicallyMatch(dirName);
-                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
-                    // cleanup
-                    directory.remove(null, fail);
-                }),
-                fail = createFail('DirectoryEntry');
-
-            // create:true, exclusive:false, directory does not exist
-            runs(function() {
-                root.getDirectory(dirName, {create: true}, getDir, fail);
-            });
-
-            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
-        });
-
-        it("file.spec.26 DirectoryEntry.getDirectory: create new directory", function() {
-            var dirName = "de.create.dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                win = jasmine.createSpy().andCallFake(function(directory) {
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.name).toCanonicallyMatch(dirName);
-                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
-                    expect(directory.filesystem).toBeDefined();
-                    expect(directory.filesystem).toBe(root.filesystem);
-
-                    // cleanup
-                    directory.remove(null, fail);
-                }),
-                fail = createFail('DirectoryEntry');
-
-            // create:true, exclusive:false, directory does not exist
-            runs(function() {
-                root.getDirectory(dirName, {create: true}, win, fail);
-            });
-
-            waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(win).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-
-        it("file.spec.27 DirectoryEntry.getDirectory: create new directory (exclusive)", function() {
-            var dirName = "de.create.exclusive.dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                win = jasmine.createSpy().andCallFake(function(directory) {
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.name).toCanonicallyMatch(dirName);
-                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
-                    expect(directory.filesystem).toBeDefined();
-                    expect(directory.filesystem).toBe(root.filesystem);
-
-                    // cleanup
-                    directory.remove(null, fail);
-                }),
-                fail = createFail('DirectoryEntry');
-            // create:true, exclusive:true, directory does not exist
-            runs(function() {
-                root.getDirectory(dirName, {create: true, exclusive:true}, win, fail);
-            });
-
-            waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(win).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.28 DirectoryEntry.getDirectory: create directory that already exists", function() {
-            var dirName = "de.create.existing.dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                getDir = jasmine.createSpy().andCallFake(function(directory) {
-                    // create:true, exclusive:false, directory exists
-                    runs(function() {
-                        root.getDirectory(dirName, {create:true}, win, fail);
-                    });
-
-                    waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(win).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                win = jasmine.createSpy().andCallFake(function(directory) {
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.name).toCanonicallyMatch(dirName);
-                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
-
-                    // cleanup
-                    directory.remove(null, fail);
-                }),
-                fail = createFail('DirectoryEntry');
-
-            // create directory to kick off it
-            runs(function() {
-                root.getDirectory(dirName, {create:true}, getDir, this.fail);
-            });
-
-            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.29 DirectoryEntry.getDirectory: create directory that already exists (exclusive)", function() {
-            var dirName = "de.create.exclusive.existing.dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                existingDir,
-                getDir = jasmine.createSpy().andCallFake(function(directory) {
-                    existingDir = directory;
-                    // create:true, exclusive:true, directory exists
-                    runs(function() {
-                        root.getDirectory(dirName, {create:true, exclusive:true}, win, fail);
-                    });
-
-                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(fail).toHaveBeenCalled();
-                        expect(win).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.PATH_EXISTS_ERR);
-
-                    // cleanup
-                    existingDir.remove(null, fail);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create directory to kick off it
-            runs(function() {
-                root.getDirectory(dirName, {create:true}, getDir, fail);
-            });
-
-            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.30 DirectoryEntry.getDirectory: get Entry for existing directory", function() {
-            var dirName = "de.get.dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                getDir = jasmine.createSpy().andCallFake(function(directory) {
-                    // create:false, exclusive:false, directory exists
-                    runs(function() {
-                        root.getDirectory(dirName, {create:false}, win, fail);
-                    });
-
-                    waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(win).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                win = jasmine.createSpy().andCallFake(function(directory) {
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.name).toCanonicallyMatch(dirName);
-
-                    expect(directory.fullPath).toCanonicallyMatch(dirPath);
-
-                    // cleanup
-                    directory.remove(null, fail);
-                }),
-                fail = createFail('DirectoryEntry');
-
-            // create directory to kick it off
-            runs(function() {
-                root.getDirectory(dirName, {create:true}, getDir, fail);
-            });
-            waitsFor(function() { return getDir.wasCalled; }, "getDir never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.31 DirectoryEntry.getDirectory: get DirectoryEntry for invalid path", function() {
-            var dirName = "de:invalid:path",
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.ENCODING_ERR);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create:false, exclusive:false, invalid path
-            runs(function() {
-                root.getDirectory(dirName, {create:false}, win, fail);
-            });
-
-            waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(fail).toHaveBeenCalled();
-                expect(win).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.32 DirectoryEntry.getDirectory: get DirectoryEntry for existing file", function() {
-            var fileName = "de.existing.file",
-                existingFile,
-                filePath = joinURL(root.fullPath, fileName),
-                getDir = jasmine.createSpy().andCallFake(function(file) {
-                    existingFile = file;
-                    // create:false, exclusive:false, existing file
-                    runs(function() {
-                        root.getDirectory(fileName, {create:false}, win, fail);
-                    });
-
-                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(fail).toHaveBeenCalled();
-                        expect(win).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);
-
-                    // cleanup
-                    existingFile.remove(null, null);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create file to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, getDir, fail);
-            });
-
-            waitsFor(function() { return getDir.wasCalled; }, "getDir was never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.33 DirectoryEntry.getFile: get FileEntry for existing directory", function() {
-            var dirName = "de.existing.dir",
-                existingDir,
-                dirPath = joinURL(root.fullPath, dirName),
-                getFile = jasmine.createSpy().andCallFake(function(directory) {
-                    existingDir = directory;
-                    // create:false, exclusive:false, existing directory
-                    runs(function() {
-                        root.getFile(dirName, {create:false}, win, fail);
-                    });
-
-                    waitsFor(function() { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(fail).toHaveBeenCalled();
-                        expect(win).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.TYPE_MISMATCH_ERR);
-
-                    // cleanup
-                    existingDir.remove(null, null);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // create directory to kick off it
-            runs(function() {
-                root.getDirectory(dirName, {create:true}, getFile, fail);
-            });
-
-            waitsFor(function() { return getFile.wasCalled; }, "getFile never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.34 DirectoryEntry.removeRecursively on directory", function() {
-            var dirName = "de.removeRecursively",
-                subDirName = "dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                subDirPath = joinURL(dirPath, subDirName),
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    // delete directory
-                    var deleteDirectory = jasmine.createSpy().andCallFake(function(directory) {
-                        runs(function() {
-                            entry.removeRecursively(remove, fail);
-                        });
-
-                        waitsFor(function() { return remove.wasCalled; }, "remove never called", Tests.TEST_TIMEOUT);
-                    });
-                    // create a sub-directory within directory
-                    runs(function() {
-                        entry.getDirectory(subDirName, {create: true}, deleteDirectory, fail);
-                    });
-
-                    waitsFor(function() { return deleteDirectory.wasCalled; }, "deleteDirectory never called", Tests.TEST_TIMEOUT);
-                }),
-                remove = jasmine.createSpy().andCallFake(function() {
-                    // it that removed directory no longer exists
-                    runs(function() {
-                        root.getDirectory(dirName, {create:false}, win, dirExists);
-                    });
-
-                    waitsFor(function() { return dirExists.wasCalled; }, "dirExists never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(dirExists).toHaveBeenCalled();
-                        expect(win).not.toHaveBeenCalled();
-                    });
-                }),
-                dirExists = jasmine.createSpy().andCallFake(function(error){
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                }),
-                fail = createFail('DirectoryEntry'),
-                win = createWin('DirectoryEntry');
-
-            // create a new directory entry to kick off it
-            runs(function() {
-                root.getDirectory(dirName, {create:true}, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.35 createReader: create reader on existing directory", function() {
-            // create reader for root directory
-            var reader = root.createReader();
-            expect(reader).toBeDefined();
-            expect(typeof reader.readEntries).toBe('function');
-        });
-        it("file.spec.36 removeRecursively on root file system", function() {
-            var remove = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);
-                }),
-                win = createWin('DirectoryEntry');
-
-            // remove root file system
-            runs(function() {
-                root.removeRecursively(win, remove);
-            });
-
-            waitsFor(function() { return remove.wasCalled; }, "remove never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(win).not.toHaveBeenCalled();
-                expect(remove).toHaveBeenCalled();
-            });
-        });
-    });
-
-    describe('DirectoryReader interface', function() {
-        describe("readEntries", function() {
-            it("file.spec.37 should read contents of existing directory", function() {
-                var reader,
-                    win = jasmine.createSpy().andCallFake(function(entries) {
-                        expect(entries).toBeDefined();
-                        expect(entries instanceof Array).toBe(true);
-                    }),
-                    fail = createFail('DirectoryReader');
-
-                // create reader for root directory
-                reader = root.createReader();
-                // read entries
-                runs(function() {
-                    reader.readEntries(win, fail);
-                });
-
-                waitsFor(function() { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(win).toHaveBeenCalled();
-                    expect(fail).not.toHaveBeenCalled();
-                });
-            });
-            it("file.spec.37.1 should read contents of existing directory", function(done) {
-                var fail = createFail('DirectoryReader', done),
-                    dirName = 'readEntries.dir',
-                    fileName = 'readeEntries.file';
-                root.getDirectory(dirName, {create: true}, function(directory) {
-                    directory.getFile(fileName, {create: true}, function(fileEntry) {
-                        var reader = directory.createReader();
-                        reader.readEntries(function(entries) {
-                            expect(entries).toBeDefined();
-                            expect(entries instanceof Array).toBe(true);
-                            expect(entries.length).toBe(1);
-                            expect(entries[0].fullPath).toCanonicallyMatch(fileEntry.fullPath);
-                            expect(entries[0].filesystem).not.toBe(null)
-                            expect(entries[0].filesystem instanceof FileSystem).toBe(true)
-
-                            // cleanup
-                            directory.removeRecursively(done, fail);
-                        }, fail);
-                    }, fail);
-                }, fail);
-            });
-            it("file.spec.109 should return an empty entry list on the second call", function() {
-                var reader,
-                    firstWin = jasmine.createSpy().andCallFake(function(entries) {
-                        expect(entries).toBeDefined();
-                        expect(entries instanceof Array).toBe(true);
-                        expect(entries.length).not.toBe(0);
-                        reader.readEntries(secondWin, fail);
-                    }),
-                    secondWin = jasmine.createSpy().andCallFake(function(entries) {
-                        expect(entries).toBeDefined();
-                        expect(entries instanceof Array).toBe(true);
-                        expect(entries.length).toBe(0);
-                    }),
-                    fail = createFail('DirectoryReader');
-
-                runs(function() {
-                    // Add a file to ensure the root directory is non-empty and then read the contents of the directory.
-                    root.getFile('test109.txt', { create: true }, function() {
-                        reader = root.createReader();
-                        reader.readEntries(firstWin, fail);
-                    }, fail);
-                });
-
-                waitsFor(function() { return secondWin.wasCalled; }, "secondWin never called", Tests.TEST_TIMEOUT);
-
-                runs(function() {
-                    expect(firstWin).toHaveBeenCalled();
-                    expect(secondWin).toHaveBeenCalled();
-                    expect(fail).not.toHaveBeenCalled();
-
-                    // Remove the test file.
-                    root.getFile('test109.txt', { create: false }, function(fileEntry) {
-                        fileEntry.remove();
-                    }, fail);
-                });
-            });
-            it("file.spec.38 should read contents of directory that has been removed", function() {
-                var dirName = "de.createReader.notfound",
-	                dirPath = joinURL(root.fullPath, dirName),
-                    entryCallback = jasmine.createSpy().andCallFake(function(directory) {
-                        // read entries
-                        var readEntries = jasmine.createSpy().andCallFake(function() {
-                            var reader = directory.createReader();
-
-                            runs(function() {
-                                reader.readEntries(win, itReader);
-                            });
-
-                            waitsFor(function() { return itReader.wasCalled; }, "itReader never called", Tests.TEST_TIMEOUT);
-                        });
-                        // delete directory
-                        runs(function() {
-                            directory.removeRecursively(readEntries, fail);
-                        });
-
-                        waitsFor(function() { return readEntries.wasCalled; }, "readEntries never called", Tests.TEST_TIMEOUT);
-                    }),
-                    itReader = jasmine.createSpy().andCallFake(function(error) {
-                        var itDirectoryExists = jasmine.createSpy().andCallFake(function(error) {
-                            expect(error).toBeDefined();
-                            expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                        });
-
-                        expect(error).toBeDefined();
-                        expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-
-                        runs(function() {
-                            root.getDirectory(dirName, {create:false}, win, itDirectoryExists);
-                        });
-
-                        waitsFor(function() { return itDirectoryExists.wasCalled; }, "itDirectoryExists never called", Tests.TEST_TIMEOUT);
-
-                        runs(function() {
-                            expect(itDirectoryExists).toHaveBeenCalled();
-                            expect(win).not.toHaveBeenCalled();
-                        });
-                    }),
-                    fail = createFail('DirectoryReader'),
-                    win = createWin('DirectoryReader');
-
-                // create a new directory entry to kick off it
-                runs(function() {
-                    root.getDirectory(dirName, {create:true}, entryCallback, fail);
-                });
-
-                waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-            });
-        });
-    });
-
-    describe('File', function() {
-        it("file.spec.39 constructor should be defined", function() {
-            expect(File).toBeDefined();
-            expect(typeof File).toBe('function');
-        });
-        it("file.spec.40 should be define File attributes", function() {
-            var file = new File();
-            expect(file.name).toBeDefined();
-            expect(file.type).toBeDefined();
-            expect(file.lastModifiedDate).toBeDefined();
-            expect(file.size).toBeDefined();
-        });
-    });
-
-    describe('FileEntry', function() {
-        it("file.spec.41 should be define FileEntry methods", function() {
-            var fileName = "fe.methods",
-                itFileEntry = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    expect(fileEntry).toBeDefined();
-                    expect(typeof fileEntry.createWriter).toBe('function');
-                    expect(typeof fileEntry.file).toBe('function');
-
-                    // cleanup
-                    fileEntry.remove(null, fail);
-                }),
-                fail = createFail('FileEntry');
-
-            // create a new file entry to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, itFileEntry, fail);
-            });
-
-            waitsFor(function() { return itFileEntry.wasCalled; }, "itFileEntry never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(itFileEntry).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.42 createWriter should return a FileWriter object", function() {
-            var fileName = "fe.createWriter",
-                itFile,
-                entryCallback = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    itFile = fileEntry;
-
-                    runs(function() {
-                        fileEntry.createWriter(itWriter, fail);
-                    });
-
-                    waitsFor(function() { return itWriter.wasCalled; }, "itWriter", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(itWriter).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                itWriter = jasmine.createSpy().andCallFake(function(writer) {
-                    expect(writer).toBeDefined();
-                    expect(writer instanceof FileWriter).toBe(true);
-
-                    // cleanup
-                    itFile.remove(null, fail);
-                }),
-                fail = createFail('FileEntry');
-
-            // create a new file entry to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.43 file should return a File object", function() {
-            var fileName = "fe.file",
-                newFile,
-                entryCallback = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    newFile = fileEntry;
-
-                    runs(function() {
-                        fileEntry.file(itFile, fail);
-                    });
-
-                    waitsFor(function() { return itFile.wasCalled; }, "itFile never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(itFile).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                itFile = jasmine.createSpy().andCallFake(function(file) {
-                    expect(file).toBeDefined();
-                    expect(file instanceof File).toBe(true);
-
-                    // cleanup
-                    newFile.remove(null, fail);
-                }),
-                fail = createFail('FileEntry');
-
-            // create a new file entry to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.44 file: on File that has been removed", function() {
-            var fileName = "fe.no.file",
-                entryCallback = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    // create File object
-                    var getFile = jasmine.createSpy().andCallFake(function() {
-                        runs(function() {
-                            fileEntry.file(win, itFile);
-                        });
-
-                        waitsFor(function() { return itFile.wasCalled; }, "itFile never called", Tests.TEST_TIMEOUT);
-
-                        runs(function() {
-                            expect(itFile).toHaveBeenCalled();
-                            expect(win).not.toHaveBeenCalled();
-                        });
-                    });
-                    // delete file
-                    runs(function() {
-                        fileEntry.remove(getFile, fail);
-                    });
-
-                    waitsFor(function() { return getFile.wasCalled; }, "getFile never called", Tests.TEST_TIMEOUT);
-                }),
-                itFile = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                }),
-                fail = createFail('FileEntry'),
-                win = createWin('FileEntry');
-
-            // create a new file entry to kick off it
-            runs(function() {
-                root.getFile(fileName, {create:true}, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-    });
-    describe('Entry', function() {
-        it("file.spec.45 Entry object", function() {
-            var fileName = "entry",
-                fullPath = joinURL(root.fullPath, fileName),
-                fail = createFail('Entry'),
-                itEntry = jasmine.createSpy().andCallFake(function(entry) {
-                    expect(entry).toBeDefined();
-                    expect(entry.isFile).toBe(true);
-                    expect(entry.isDirectory).toBe(false);
-                    expect(entry.name).toCanonicallyMatch(fileName);
-                    expect(entry.fullPath).toCanonicallyMatch(fullPath);
-                    expect(typeof entry.getMetadata).toBe('function');
-                    expect(typeof entry.setMetadata).toBe('function');
-                    expect(typeof entry.moveTo).toBe('function');
-                    expect(typeof entry.copyTo).toBe('function');
-                    expect(typeof entry.toURL).toBe('function');
-                    expect(typeof entry.remove).toBe('function');
-                    expect(typeof entry.getParent).toBe('function');
-                    expect(typeof entry.createWriter).toBe('function');
-                    expect(typeof entry.file).toBe('function');
-
-                    // cleanup
-                    deleteEntry(fileName);
-                });
-
-            // create a new file entry
-            runs(function() {
-                createFile(fileName, itEntry, fail);
-            });
-
-            waitsFor(function() { return itEntry.wasCalled; }, "itEntry", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(itEntry).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.46 Entry.getMetadata on file", function() {
-            var fileName = "entry.metadata.file",
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    runs(function() {
-                        entry.getMetadata(itMetadata, fail);
-                    });
-
-                    waitsFor(function() { return itMetadata.wasCalled; }, "itMetadata never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(itMetadata).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = createFail('Entry'),
-                itMetadata = jasmine.createSpy().andCallFake(function(metadata) {
-                    expect(metadata).toBeDefined();
-                    expect(metadata.modificationTime instanceof Date).toBe(true);
-                    expect(isNaN(metadata.modificationTime.getTime())).toBe(false);
-                    expect(typeof metadata.size).toBe("number");
-
-                    // cleanup
-                    deleteEntry(fileName);
-                });
-
-            // create a new file entry
-            runs(function() {
-                createFile(fileName, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, 'entryCallback never called', Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.47 Entry.getMetadata on directory", function() {
-            var dirName = "entry.metadata.dir",
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    runs(function() {
-                        entry.getMetadata(itMetadata, fail);
-                    });
-
-                    waitsFor(function() { return itMetadata.wasCalled; }, "itMetadata never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(itMetadata).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = createFail('Entry'),
-                itMetadata = jasmine.createSpy().andCallFake(function(metadata) {
-                    expect(metadata).toBeDefined();
-                    expect(metadata.modificationTime instanceof Date).toBe(true);
-                    expect(isNaN(metadata.modificationTime.getTime())).toBe(false);
-                    expect(typeof metadata.size).toBe("number");
-                    expect(metadata.size).toBe(0);
-
-                    // cleanup
-                    deleteEntry(dirName);
-                });
-
-            // create a new directory entry
-            runs(function() {
-                createDirectory(dirName, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.48 Entry.getParent on file in root file system", function() {
-            var fileName = "entry.parent.file",
-                rootPath = root.fullPath,
-                fail = createFail('Entry'),
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    runs(function() {
-                        entry.getParent(itParent, fail);
-                    });
-
-                    waitsFor(function() { return itParent.wasCalled; }, "itCalled never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(itParent).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                itParent = jasmine.createSpy().andCallFake(function(parent) {
-                    expect(parent).toBeDefined();
-                    expect(parent.fullPath).toCanonicallyMatch(rootPath);
-
-                    // cleanup
-                    deleteEntry(fileName);
-                });
-
-            // create a new file entry
-            runs(function() {
-                createFile(fileName, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.49 Entry.getParent on directory in root file system", function() {
-            var dirName = "entry.parent.dir",
-                rootPath = root.fullPath,
-                fail = createFail('Entry'),
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    runs(function() {
-                        entry.getParent(itParent, fail);
-                    });
-
-                    waitsFor(function() { return itParent.wasCalled; }, "itParent never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(itParent).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                    });
-                }),
-                itParent = jasmine.createSpy().andCallFake(function(parent) {
-                    expect(parent).toBeDefined();
-                    expect(parent.fullPath).toCanonicallyMatch(rootPath);
-
-                    // cleanup
-                    deleteEntry(dirName);
-                });
-
-            // create a new directory entry
-            runs(function() {
-                createDirectory(dirName, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.50 Entry.getParent on root file system", function() {
-            var rootPath = root.fullPath,
-                itParent = jasmine.createSpy().andCallFake(function(parent) {
-                    expect(parent).toBeDefined();
-                    expect(parent.fullPath).toCanonicallyMatch(rootPath);
-                }),
-                fail = createFail('Entry');
-
-            // create a new directory entry
-            runs(function() {
-                root.getParent(itParent, fail);
-            });
-
-            waitsFor(function() { return itParent.wasCalled; }, "itParent never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(itParent).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.51 Entry.toURL on file", function() {
-            var fileName = "entry.uri.file",
-                rootPath = root.fullPath,
-                itURI = jasmine.createSpy().andCallFake(function(entry) {
-                    var uri = entry.toURL();
-                    expect(uri).toBeDefined();
-                    expect(uri.indexOf(rootPath)).not.toBe(-1);
-
-                    // cleanup
-                    deleteEntry(fileName);
-                }),
-                fail = createFail('Entry');
-
-            // create a new file entry
-            runs(function() {
-                createFile(fileName, itURI, fail);
-            });
-
-            waitsFor(function() { return itURI.wasCalled; }, "itURI never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(itURI).toHaveBeenCalled();
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-        it("file.spec.52 Entry.toURL on directory", function() {
-            var dirName1 = "num 1",
-                dirName2 = "num 2",
-                rootPath = root.fullPath,
-                fail = createFail('Entry');
-
-            createDirectory(dirName1, createNext, fail);
-            function createNext(e1) {
-                e1.getDirectory(dirName2, {create: true}, check, fail);
-            }
-            var check = jasmine.createSpy().andCallFake(function(entry) {
-                var uri = entry.toURL();
-                expect(uri).toBeDefined();
-                expect(uri).toContain('/num%201/num%202/');
-                expect(uri.indexOf(rootPath)).not.toBe(-1);
-                // cleanup
-                deleteEntry(dirName1);
-            });
-            waitsForAny(check, fail);
-        });
-        it("file.spec.53 Entry.remove on file", function() {
-            var fileName = "entr .rm.file",
-                fullPath = joinURL(root.fullPath, fileName),
-                win = createWin('Entry'),
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    var checkRemove = jasmine.createSpy().andCallFake(function() {
-                        runs(function() {
-                            root.getFile(fileName, null, win, itRemove);
-                        });
-
-                        waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
-
-                        runs(function() {
-                            expect(win).not.toHaveBeenCalled();
-                            expect(fail).not.toHaveBeenCalled();
-                            expect(itRemove).toHaveBeenCalled();
-                        });
-                    });
-                    expect(entry).toBeDefined();
-
-                    runs(function() {
-                        entry.remove(checkRemove, fail);
-                    });
-
-                    waitsFor(function() { return checkRemove.wasCalled; }, "checkRemove never called", Tests.TEST_TIMEOUT);
-                }),
-                itRemove = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                    // cleanup
-                    deleteEntry(fileName);
-                }),
-                fail = createFail('Entry');
-
-            // create a new file entry
-            runs(function() {
-                createFile(fileName, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.54 remove on empty directory", function() {
-            var dirName = "entry.rm.dir",
-                dirPath = joinURL(root.fullPath, dirName),
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    var checkRemove = jasmine.createSpy().andCallFake(function() {
-                        runs(function() {
-                            root.getDirectory(dirName, null, win, itRemove);
-                        });
-
-                        waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
-
-                        runs(function() {
-                            expect(itRemove).toHaveBeenCalled();
-                            expect(win).not.toHaveBeenCalled();
-                            expect(fail).not.toHaveBeenCalled();
-                        });
-                    });
-
-                    expect(entry).toBeDefined();
-
-                    runs(function() {
-                        entry.remove(checkRemove, fail);
-                    });
-
-                    waitsFor(function() { return checkRemove.wasCalled; }, "checkRemove never called", Tests.TEST_TIMEOUT);
-                }),
-                itRemove = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.NOT_FOUND_ERR);
-                    // cleanup
-                    deleteEntry(dirName);
-                }),
-                win = createWin('Entry'),
-                fail = createFail('Entry');
-
-            // create a new directory entry
-            runs(function() {
-                createDirectory(dirName, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.55 remove on non-empty directory", function() {
-            var dirName = "ent y.rm.dir.not.empty",
-                fileName = "re ove.txt",
-                fullPath = joinURL(root.fullPath, dirName),
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    var checkFile = jasmine.createSpy().andCallFake(function(error) {
-                        expect(error).toBeDefined();
-                        expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
-                        // verify that dir still exists
-                        runs(function() {
-                            root.getDirectory(dirName, null, itRemove, fail);
-                        });
-
-                        waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
-
-                        runs(function() {
-                            expect(win).not.toHaveBeenCalled();
-                            expect(fail).not.toHaveBeenCalled();
-                            expect(itRemove).toHaveBeenCalled();
-                        });
-                    });
-                    // delete directory
-                    var deleteDirectory = jasmine.createSpy().andCallFake(function(fileEntry) {
-                        runs(function() {
-                            entry.remove(win, checkFile);
-                        });
-
-                        waitsFor(function() { return checkFile.wasCalled; }, "checkFile never called", Tests.TEST_TIMEOUT);
-                    });
-                    // create a file within directory, then try to delete directory
-                    runs(function() {
-                        entry.getFile(fileName, {create: true}, deleteDirectory, fail);
-                    });
-
-                    waitsFor(function() { return deleteDirectory.wasCalled; }, "deleteDirectory never called", Tests.TEST_TIMEOUT);
-                }),
-                itRemove = jasmine.createSpy().andCallFake(function(entry) {
-                    expect(entry).toBeDefined();
-                    expect(entry.fullPath).toCanonicallyMatch(fullPath);
-                    // cleanup
-                    deleteEntry(dirName);
-                }),
-                win = createWin('Entry'),
-                fail = createFail('Entry');
-
-            // create a new directory entry
-            runs(function() {
-                createDirectory(dirName, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.56 remove on root file system", function() {
-            var itRemove = jasmine.createSpy().andCallFake(function(error) {
-                expect(error).toBeDefined();
-                expect(error).toBeFileError(FileError.NO_MODIFICATION_ALLOWED_ERR);
-            }),
-            win = createWin('Entry');
-
-            // remove entry that doesn't exist
-            runs(function() {
-                root.remove(win, itRemove);
-            });
-
-            waitsFor(function() { return itRemove.wasCalled; }, "itRemove never called", Tests.TEST_TIMEOUT);
-
-            runs(function() {
-                expect(win).not.toHaveBeenCalled();
-                expect(itRemove).toHaveBeenCalled();
-            });
-        });
-        it("file.spec.57 copyTo: file", function() {
-            var file1 = "entry copy.file1",
-                file2 = "entry copy.file2",
-                fullPath = joinURL(root.fullPath, file2),
-                fail = createFail('Entry'),
-                entryCallback = function(entry) {
-                    // copy file1 to file2
-                    entry.copyTo(root, file2, itCopy, fail);
-                },
-                itCopy = function(entry) {
-                    expect(entry).toBeDefined();
-                    expect(entry.isFile).toBe(true);
-                    expect(entry.isDirectory).toBe(false);
-                    expect(entry.fullPath).toCanonicallyMatch(fullPath);
-                    expect(entry.name).toCanonicallyMatch(file2);
-
-                    root.getFile(file2, {create:false}, itFileExists, fail);
-                },
-                itFileExists = jasmine.createSpy().andCallFake(function(entry2) {
-                    // a bit redundant since copy returned this entry already
-                    expect(entry2).toBeDefined();
-                    expect(entry2.isFile).toBe(true);
-                    expect(entry2.isDirectory).toBe(false);
-                    expect(entry2.fullPath).toCanonicallyMatch(fullPath);
-                    expect(entry2.name).toCanonicallyMatch(file2);
-
-                    // cleanup
-                    deleteEntry(file1);
-                    deleteEntry(file2);
-                });
-
-            // create a new file entry to kick off it
-            deleteEntry(file2, function() {
-                createFile(file1, entryCallback, fail);
-            }, fail);
-
-            waitsForAny(itFileExists, fail);
-        });
-        it("file.spec.58 copyTo: file onto itself", function() {
-            var file1 = "entry.copy.fos.file1",
-                entryCallback = jasmine.createSpy().andCallFake(function(entry) {
-                    // copy file1 onto itself
-                    runs(function() {
-                        entry.copyTo(root, null, win, itCopy);
-                    });
-
-                    waitsFor(function() { return itCopy.wasCalled; }, "itCopy never called", Tests.TEST_TIMEOUT);
-
-                    runs(function() {
-                        expect(itCopy).toHaveBeenCalled();
-                        expect(fail).not.toHaveBeenCalled();
-                        expect(win).not.toHaveBeenCalled();
-                    });
-                }),
-                fail = createFail('Entry'),
-                win = createWin('Entry'),
-                itCopy = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
-
-                    // cleanup
-                    deleteEntry(file1);
-                });
-
-            // create a new file entry to kick off it
-            runs(function() {
-                createFile(file1, entryCallback, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.59 copyTo: directory", function() {
-            var file1 = "file1",
-                srcDir = "entry.copy.srcDir",
-                dstDir = "entry.copy.dstDir",
-                dstPath = joinURL(root.fullPath, dstDir),
-                filePath = joinURL(dstPath, file1),
-                entryCallback = jasmine.createSpy().andCallFake(function(directory) {
-                    var copyDir = jasmine.createSpy().andCallFake(function(fileEntry) {
-                        // copy srcDir to dstDir
-                        runs(function() {
-                            directory.copyTo(root, dstDir, itCopy, fail);
-                        });
-
-                        waitsFor(function() { return itCopy.wasCalled; }, "itCopy never called", Tests.TEST_TIMEOUT);
-                    });
-
-                    // create a file within new directory
-                    runs(function() {
-                        directory.getFile(file1, {create: true}, copyDir, fail);
-                    });
-
-                    waitsFor(function() { return copyDir.wasCalled; }, "copyDir never called", Tests.TEST_TIMEOUT);
-                }),
-                itCopy = jasmine.createSpy().andCallFake(function(directory) {
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.fullPath).toCanonicallyMatch(dstPath);
-                    expect(directory.name).toCanonicallyMatch(dstDir);
-
-                    runs(function() {
-                        root.getDirectory(dstDir, {create:false}, itDirExists, fail);
-                    });
-
-                    waitsFor(function() { return itDirExists.wasCalled; }, "itDirExists never called", Tests.TEST_TIMEOUT);
-                }),
-                itDirExists = jasmine.createSpy().andCallFake(function(dirEntry) {
-                     expect(dirEntry).toBeDefined();
-                     expect(dirEntry.isFile).toBe(false);
-                     expect(dirEntry.isDirectory).toBe(true);
-                     expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
-                     expect(dirEntry.name).toCanonicallyMatch(dstDir);
-
-                     runs(function() {
-                         dirEntry.getFile(file1, {create:false}, itFileExists, fail);
-                     });
-
-                     waitsFor(function() { return itFileExists.wasCalled; }, "itFileExists never called", Tests.TEST_TIMEOUT);
-
-                     runs(function() {
-                         expect(itFileExists).toHaveBeenCalled();
-                         expect(fail).not.toHaveBeenCalled();
-                     });
-                }),
-                itFileExists = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    expect(fileEntry).toBeDefined();
-                    expect(fileEntry.isFile).toBe(true);
-                    expect(fileEntry.isDirectory).toBe(false);
-                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
-                    expect(fileEntry.name).toCanonicallyMatch(file1);
-
-                    // cleanup
-                    deleteEntry(srcDir);
-                    deleteEntry(dstDir);
-                }),
-                fail = createFail('Entry');
-
-            // create a new directory entry to kick off it
-            runs(function() {
-                deleteEntry(dstDir, function() {
-                    createDirectory(srcDir, entryCallback, fail);
-                }, fail);
-            });
-
-            waitsFor(function() { return entryCallback.wasCalled; }, "entryCallback never called", Tests.TEST_TIMEOUT);
-        });
-        it("file.spec.60 copyTo: directory to backup at same root directory", function() {
-            var file1 = "file1",
-                srcDir = "entry.copy srcDirSame",
-                dstDir = "entry.copy srcDirSame-backup",
-                dstPath = joinURL(root.fullPath, dstDir),
-                filePath = joinURL(dstPath, file1),
-                fail = createFail('Entry copyTo: directory to backup at same root'),
-                entryCallback = function(directory) {
-                    var copyDir = function(fileEntry) {
-                        // copy srcDir to dstDir
-                        directory.copyTo(root, dstDir, itCopy, fail);
-                    };
-                    // create a file within new directory
-                    directory.getFile(file1, {create: true}, copyDir, fail);
-                },
-                itCopy = function(directory) {
-                    expect(directory).toBeDefined();
-                    expect(directory.isFile).toBe(false);
-                    expect(directory.isDirectory).toBe(true);
-                    expect(directory.fullPath).toCanonicallyMatch(dstPath);
-                    expect(directory.name).toCanonicallyMatch(dstDir);
-
-                    root.getDirectory(dstDir, {create:false}, itDirExists, fail);
-                },
-                itDirExists = function(dirEntry) {
-                     expect(dirEntry).toBeDefined();
-                     expect(dirEntry.isFile).toBe(false);
-                     expect(dirEntry.isDirectory).toBe(true);
-                     expect(dirEntry.fullPath).toCanonicallyMatch(dstPath);
-                     expect(dirEntry.name).toCanonicallyMatch(dstDir);
-
-                     dirEntry.getFile(file1, {create:false}, itFileExists, fail);
-                },
-                itFileExists = jasmine.createSpy().andCallFake(function(fileEntry) {
-                    var cleanSrc = jasmine.createSpy();
-                    var cleanDst = jasmine.createSpy();
-                    expect(fileEntry).toBeDefined();
-                    expect(fileEntry.isFile).toBe(true);
-                    expect(fileEntry.isDirectory).toBe(false);
-                    expect(fileEntry.fullPath).toCanonicallyMatch(filePath);
-                    expect(fileEntry.name).toCanonicallyMatch(file1);
-                    expect(fail).not.toHaveBeenCalled();
-
-                    // cleanup
-                    deleteEntry(srcDir, cleanSrc);
-                    deleteEntry(dstDir, cleanDst);
-                });
-
-            // create a new directory entry to kick off it
-            deleteEntry(dstDir, function() {
-                createDirectory(srcDir, entryCallback, fail);
-            }, fail);
-
-            waitsForAny(itFileExists, fail);
-        });
-        it("file.spec.61 copyTo: directory onto itself", function() {
-            var file1 = "file1",
-                srcDir = "entry.copy.dos.srcDir",
-                srcPath = joinURL(root.fullPath, srcDir),
-                filePath = joinURL(srcPath, file1),
-                win = createWin('Entry'),
-                fail = createFail('Entry copyTo: directory onto itself'),
-                entryCallback = jasmine.createSpy().andCallFake(function(directory) {
-                    var copyDir = jasmine.createSpy().andCallFake(function(fileEntry) {
-                        // copy srcDir onto itself
-                        runs(function() {
-                            directory.copyTo(root, null, win, itCopy);
-                        });
-
-                        waitsFor(function() { return itCopy.wasCalled; }, "itCopy never called", Tests.TEST_TIMEOUT);
-                    });
-                    // create a file within new directory
-                    runs(function() {
-                        directory.getFile(file1, {create: true}, copyDir, fail);
-                    });
-
-                    waitsFor(function() { return copyDir.wasCalled; }, "copyDir never called", Tests.TEST_TIMEOUT);
-                }),
-                itCopy = jasmine.createSpy().andCallFake(function(error) {
-                    expect(error).toBeDefined();
-                    expect(error).toBeFileError(FileError.INVALID_MODIFICATION_ERR);
-
-                    runs(function() {
-                        root.getDirectory(srcDir, {create:false}, itDirectoryExists, f

<TRUNCATED>

[08/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/compass.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/compass.html b/www/autotest/pages/compass.html
new file mode 100644
index 0000000..80de16f
--- /dev/null
+++ b/www/autotest/pages/compass.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Compass API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/compass.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/contacts.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/contacts.html b/www/autotest/pages/contacts.html
new file mode 100644
index 0000000..e8e5fae
--- /dev/null
+++ b/www/autotest/pages/contacts.html
@@ -0,0 +1,56 @@
+<!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>Cordova: Contacts API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/contacts.tests.js"></script>
+
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn" id="backHome">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/datauri.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/datauri.html b/www/autotest/pages/datauri.html
new file mode 100644
index 0000000..33474dd
--- /dev/null
+++ b/www/autotest/pages/datauri.html
@@ -0,0 +1,53 @@
+<!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>Cordova: Data URI tests</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/datauri.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn" onclick="backHome();">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/device.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/device.html b/www/autotest/pages/device.html
new file mode 100644
index 0000000..b1bed1d
--- /dev/null
+++ b/www/autotest/pages/device.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Device API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/device.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/file.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/file.html b/www/autotest/pages/file.html
new file mode 100644
index 0000000..d201791
--- /dev/null
+++ b/www/autotest/pages/file.html
@@ -0,0 +1,53 @@
+<!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>Cordova: File API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/file.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./file.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/file.js
----------------------------------------------------------------------
diff --git a/www/autotest/pages/file.js b/www/autotest/pages/file.js
new file mode 100644
index 0000000..9b1a67a
--- /dev/null
+++ b/www/autotest/pages/file.js
@@ -0,0 +1,39 @@
+var root, temp_root, persistent_root;
+
+document.addEventListener('deviceready', function () {
+    // one-time retrieval of the root file system entry
+    var onError = function(e) {
+        console.log('[ERROR] Problem setting up root filesystem for test running! Error to follow.');
+        console.log(JSON.stringify(e));
+    };
+
+    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
+        function(fileSystem) {
+            console.log('File API test Init: Setting PERSISTENT FS.');
+            root = fileSystem.root; // set in file.tests.js
+            persistent_root = root;
+
+            // Once root is set up, fire off tests
+            var jasmineEnv = jasmine.getEnv();
+            jasmineEnv.updateInterval = 1000;
+
+            var htmlReporter = new jasmine.HtmlReporter();
+
+            jasmineEnv.addReporter(htmlReporter);
+
+            jasmineEnv.specFilter = function(spec) {
+              return htmlReporter.specFilter(spec);
+            };
+
+            jasmineEnv.execute();
+        }, onError);
+    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
+        function(fileSystem) {
+            console.log('File API test Init: Setting TEMPORARY FS.');
+            temp_root = fileSystem.root; // set in file.tests.js
+        }, onError);
+}, false);
+
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/filetransfer.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/filetransfer.html b/www/autotest/pages/filetransfer.html
new file mode 100644
index 0000000..09809d8
--- /dev/null
+++ b/www/autotest/pages/filetransfer.html
@@ -0,0 +1,54 @@
+<!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>Cordova: File API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/filetransfer.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./file.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/geolocation.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/geolocation.html b/www/autotest/pages/geolocation.html
new file mode 100644
index 0000000..b7a0698
--- /dev/null
+++ b/www/autotest/pages/geolocation.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Geolocation API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/geolocation.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/globalization.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/globalization.html b/www/autotest/pages/globalization.html
new file mode 100644
index 0000000..295067e
--- /dev/null
+++ b/www/autotest/pages/globalization.html
@@ -0,0 +1,54 @@
+<!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>Cordova: Globalization API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/globalization.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/localXHR.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/localXHR.html b/www/autotest/pages/localXHR.html
new file mode 100644
index 0000000..10415f0
--- /dev/null
+++ b/www/autotest/pages/localXHR.html
@@ -0,0 +1,54 @@
+<!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>Cordova: Local XHR Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/localXHR.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/media.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/media.html b/www/autotest/pages/media.html
new file mode 100644
index 0000000..ac1fa75
--- /dev/null
+++ b/www/autotest/pages/media.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Media API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/media.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/network.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/network.html b/www/autotest/pages/network.html
new file mode 100644
index 0000000..6af5521
--- /dev/null
+++ b/www/autotest/pages/network.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Network API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/network.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/notification.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/notification.html b/www/autotest/pages/notification.html
new file mode 100644
index 0000000..50777bf
--- /dev/null
+++ b/www/autotest/pages/notification.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Notification API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/notification.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/platform.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/platform.html b/www/autotest/pages/platform.html
new file mode 100644
index 0000000..3ddecd0
--- /dev/null
+++ b/www/autotest/pages/platform.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Platform API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/platform.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/run-tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/pages/run-tests.js b/www/autotest/pages/run-tests.js
new file mode 100644
index 0000000..8e079ad
--- /dev/null
+++ b/www/autotest/pages/run-tests.js
@@ -0,0 +1,18 @@
+document.addEventListener('deviceready', function () {
+  var jasmineEnv = jasmine.getEnv();
+  jasmineEnv.updateInterval = 1000;
+
+  var htmlReporter = new jasmine.HtmlReporter();
+
+  jasmineEnv.addReporter(htmlReporter);
+
+  jasmineEnv.specFilter = function(spec) {
+    return htmlReporter.specFilter(spec);
+  };
+
+  jasmineEnv.execute();
+}, false);
+
+window.onload = function() {
+  addListenerToClass('backBtn', backHome);
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/splashscreen.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/splashscreen.html b/www/autotest/pages/splashscreen.html
new file mode 100644
index 0000000..6ac1c4d
--- /dev/null
+++ b/www/autotest/pages/splashscreen.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Splashscreen API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/splashscreen.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/storage.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/storage.html b/www/autotest/pages/storage.html
new file mode 100644
index 0000000..0f836e9
--- /dev/null
+++ b/www/autotest/pages/storage.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Storage API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/storage.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/vibration.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/vibration.html b/www/autotest/pages/vibration.html
new file mode 100644
index 0000000..04db2ec
--- /dev/null
+++ b/www/autotest/pages/vibration.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Vibration API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/vibration.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/pages/whitelist.html
----------------------------------------------------------------------
diff --git a/www/autotest/pages/whitelist.html b/www/autotest/pages/whitelist.html
new file mode 100644
index 0000000..ececfa2
--- /dev/null
+++ b/www/autotest/pages/whitelist.html
@@ -0,0 +1,55 @@
+<!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>Cordova: Whitelist API Specs</title>
+
+  <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
+  <!-- Load jasmine -->
+  <link href="../jasmine.css" rel="stylesheet"/>
+  <script type="text/javascript" src="../jasmine.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporterHelpers.js"></script>
+  <script type="text/javascript" src="../html/HtmlReporter.js"></script>
+  <script type="text/javascript" src="../html/ReporterView.js"></script>
+  <script type="text/javascript" src="../html/SpecView.js"></script>
+  <script type="text/javascript" src="../html/SuiteView.js"></script>
+  <script type="text/javascript" src="../html/TrivialReporter.js"></script>
+
+  <!-- Source -->
+  <script type="text/javascript" src="../../cordova-incl.js"></script>
+
+  <!-- Load Test Runner -->
+  <script type="text/javascript" src="../test-runner.js"></script>
+
+  <!-- Tests -->
+  <script type="text/javascript" src="../tests/whitelist.tests.js"></script>
+  <script type="text/javascript" charset="utf-8" src="./run-tests.js"></script>      
+</head>
+
+<body>
+  <a href="javascript:" class="backBtn">Back</a>
+</body>
+</html>
+

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/test-runner.js
----------------------------------------------------------------------
diff --git a/www/autotest/test-runner.js b/www/autotest/test-runner.js
new file mode 100644
index 0000000..a744f81
--- /dev/null
+++ b/www/autotest/test-runner.js
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+if (window.sessionStorage != null) {
+    window.sessionStorage.clear();
+}
+
+// Timeout is 2 seconds to allow physical devices enough
+// time to query the response. This is important for some
+// Android devices.
+var Tests = function() {};
+Tests.TEST_TIMEOUT = 7500;
+
+// Creates a spy that will fail if called.
+function createDoNotCallSpy(name, opt_extraMessage) {
+    return jasmine.createSpy().andCallFake(function() {
+        var errorMessage = "" + name + ' should not have been called.';
+        try {
+            if (arguments.length) {
+                errorMessage += ' Got args: ' + JSON.stringify(arguments);
+            }
+            if (opt_extraMessage) {
+                errorMessage += '\n' + opt_extraMessage;
+            }
+        } catch(e) {
+            errorMessage += " (Cannot print details)";
+        }
+        expect(false).toBe(true, errorMessage);
+    });
+}
+
+// Waits for any of the given spys to be called.
+// Last param may be a custom timeout duration.
+function waitsForAny() {
+    var spys = [].slice.call(arguments);
+    var timeout = Tests.TEST_TIMEOUT;
+    if (typeof spys[spys.length - 1] == 'number') {
+        timeout = spys.pop();
+    }
+    waitsFor(function() {
+        for (var i = 0; i < spys.length; ++i) {
+            if (spys[i].wasCalled) {
+                return true;
+            }
+        }
+        return false;
+    }, "Expecting callbacks to be called.", timeout);
+}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/accelerometer.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/accelerometer.tests.js b/www/autotest/tests/accelerometer.tests.js
new file mode 100644
index 0000000..029db05
--- /dev/null
+++ b/www/autotest/tests/accelerometer.tests.js
@@ -0,0 +1,222 @@
+/*
+ *
+ * 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('Accelerometer (navigator.accelerometer)', function () {
+    it("accelerometer.spec.1 should exist", function () {
+        expect(navigator.accelerometer).toBeDefined();
+    });
+
+    describe("getCurrentAcceleration", function() {
+        afterEach(function(){
+            // wait between testcases to avoid interference
+            var flag=false;
+            runs(function() {
+                setTimeout(function() {flag = true;}, 500);
+            });
+
+            waitsFor(function() {return flag;}, "flag to be true", Tests.TEST_TIMEOUT);
+        });
+
+        it("accelerometer.spec.2 should exist", function() {
+            expect(typeof navigator.accelerometer.getCurrentAcceleration).toBeDefined();
+            expect(typeof navigator.accelerometer.getCurrentAcceleration == 'function').toBe(true);
+        });
+
+        it("accelerometer.spec.3 success callback should be called with an Acceleration object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(a.x).toBeDefined();
+                    expect(typeof a.x == 'number').toBe(true);
+                    expect(a.y).toBeDefined();
+                    expect(typeof a.y == 'number').toBe(true);
+                    expect(a.z).toBeDefined();
+                    expect(typeof a.z == 'number').toBe(true);
+                    expect(a.timestamp).toBeDefined();
+                    expect(typeof a.timestamp).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.accelerometer.getCurrentAcceleration(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+
+        it("accelerometer.spec.4 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function() {
+            var reasonableThreshold = 15;
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a.x).toBeLessThan(reasonableThreshold);
+                    expect(a.x).toBeGreaterThan(reasonableThreshold * -1);
+                    expect(a.y).toBeLessThan(reasonableThreshold);
+                    expect(a.y).toBeGreaterThan(reasonableThreshold * -1);
+                    expect(a.z).toBeLessThan(reasonableThreshold);
+                    expect(a.z).toBeGreaterThan(reasonableThreshold * -1);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.accelerometer.getCurrentAcceleration(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+
+        it("accelerometer.spec.5 success callback Acceleration object should return a recent timestamp", function() {
+            // Check that timestamp returned is within a reasonable window.
+            var veryRecently = (new Date()).getTime()-1000; // lower bound - 1 second prior
+            var reasonableTimeLimit = veryRecently + 6000;  // upper bound - 5 seconds from now
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a.timestamp).toBeGreaterThan(veryRecently);
+                    expect(a.timestamp).toBeLessThan(reasonableTimeLimit);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.accelerometer.getCurrentAcceleration(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe("watchAcceleration", function() {
+        var id;
+
+        afterEach(function() {
+            navigator.accelerometer.clearWatch(id);
+        });
+
+        it("accelerometer.spec.6 should exist", function() {
+            expect(navigator.accelerometer.watchAcceleration).toBeDefined();
+            expect(typeof navigator.accelerometer.watchAcceleration == 'function').toBe(true);
+        });
+        it("accelerometer.spec.7 success callback should be called with an Acceleration object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(a.x).toBeDefined();
+                    expect(typeof a.x == 'number').toBe(true);
+                    expect(a.y).toBeDefined();
+                    expect(typeof a.y == 'number').toBe(true);
+                    expect(a.z).toBeDefined();
+                    expect(typeof a.z == 'number').toBe(true);
+                    expect(a.timestamp).toBeDefined();
+                    expect(typeof a.timestamp).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                id = navigator.accelerometer.watchAcceleration(win, fail, {frequency:500});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+
+        it("accelerometer.spec.8 success callback Acceleration object should have (reasonable) values for x, y and z expressed in m/s^2", function() {
+            var reasonableThreshold = 15;
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a.x).toBeLessThan(reasonableThreshold);
+                    expect(a.x).toBeGreaterThan(reasonableThreshold * -1);
+                    expect(a.y).toBeLessThan(reasonableThreshold);
+                    expect(a.y).toBeGreaterThan(reasonableThreshold * -1);
+                    expect(a.z).toBeLessThan(reasonableThreshold);
+                    expect(a.z).toBeGreaterThan(reasonableThreshold * -1);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                id = navigator.accelerometer.watchAcceleration(win, fail, {frequency:500});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+
+        it("accelerometer.spec.9 success callback Acceleration object should return a recent timestamp", function() {
+            // Check that timestamp returned is within a reasonable window.
+            var veryRecently = (new Date()).getTime()-1000; // lower bound - 1 second prior
+            var reasonableTimeLimit = veryRecently + 6000;  // upper bound - 5 seconds from now
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a.timestamp).toBeGreaterThan(veryRecently);
+                    expect(a.timestamp).toBeLessThan(reasonableTimeLimit);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                id = navigator.accelerometer.watchAcceleration(win, fail, {frequency:500});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe("clearWatch", function() {
+        it("accelerometer.spec.10 should exist", function() {
+            expect(navigator.accelerometer.clearWatch).toBeDefined();
+            expect(typeof navigator.accelerometer.clearWatch == 'function').toBe(true);
+        });
+
+        it("accelerometer.spec.11 should clear an existing watch", function() {
+            var id,
+                win = jasmine.createSpy();
+
+            runs(function() {
+                id = navigator.accelerometer.watchAcceleration(win, function() {}, {frequency:100});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function() {
+                win.reset();
+                navigator.accelerometer.clearWatch(id);
+            });
+
+            waits(201);
+
+            runs(function() {
+                expect(win).not.toHaveBeenCalled();
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/battery.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/battery.tests.js b/www/autotest/tests/battery.tests.js
new file mode 100644
index 0000000..47a86d4
--- /dev/null
+++ b/www/autotest/tests/battery.tests.js
@@ -0,0 +1,187 @@
+/*
+ *
+ * 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('Battery (navigator.battery)', function () {
+
+    // used to keep the count of event listeners > 0, in order to avoid battery level being updated with the real value when adding the first listener during test cases
+    var dummyOnEvent = jasmine.createSpy();
+    beforeEach(function () {
+        window.addEventListener("batterycritical", dummyOnEvent, false);
+    });
+
+    afterEach(function () {
+        window.removeEventListener("batterystatus", dummyOnEvent, false);
+    });
+
+
+    it("battery.spec.1 should exist", function() {
+        expect(navigator.battery).toBeDefined();
+    });
+
+    it("battery.spec.2 should fire batterystatus events", function () {
+
+        // batterystatus
+        var onEvent;
+        
+        runs(function () {
+            onEvent = jasmine.createSpy().andCallFake(function () {
+                window.removeEventListener("batterystatus", onEvent, false);
+            });
+            window.addEventListener("batterystatus", onEvent, false);
+            navigator.battery._status({ level: 30, isPlugged: false });
+        });
+        waitsFor(function () { return onEvent.wasCalled; }, "batterystatus onEvent was not called", 100);
+        runs(function () {
+            expect(onEvent).toHaveBeenCalled();
+        });
+
+    });
+
+    it("battery.spec.3 should fire batterylow events", function () {
+
+        var onEvent;
+        
+        // batterylow 30 -> 20
+        runs(function () {
+            onEvent = jasmine.createSpy().andCallFake(function () {
+                //console.log("batterylow fake callback called");
+                window.removeEventListener("batterylow", onEvent, false);
+            });
+            window.addEventListener("batterylow", onEvent, false);
+            navigator.battery._status({ level: 20, isPlugged: false });
+        });
+        waitsFor(function () { return onEvent.wasCalled; }, "batterylow onEvent was not called when level goes from 30->20", 100);
+        runs(function () {
+            expect(onEvent).toHaveBeenCalled();
+        });
+
+        // batterylow 30 -> 19
+        runs(function () {
+            onEvent = jasmine.createSpy().andCallFake(function () {
+                //console.log("batterylow fake callback called");
+                window.removeEventListener("batterylow", onEvent, false);
+            });
+            navigator.battery._status({ level: 30, isPlugged: false });
+            window.addEventListener("batterylow", onEvent, false);
+            navigator.battery._status({ level: 19, isPlugged: false });
+        });
+        waitsFor(function () { return onEvent.wasCalled; }, "batterylow onEvent was not called when level goes from 30->19", 100);
+        runs(function () {
+            expect(onEvent).toHaveBeenCalled();
+        });
+
+    });
+
+    it("battery.spec.4 should fire batterycritical events", function () {
+
+        var onEvent;
+
+        // batterycritical 19->5
+        runs(function () {
+            onEvent = jasmine.createSpy().andCallFake(function () {
+                window.removeEventListener("batterycritical", onEvent, false);
+            });
+            window.addEventListener("batterycritical", onEvent, false);
+            navigator.battery._status({ level: 5, isPlugged: false });
+        });
+        waitsFor(function () { return onEvent.wasCalled; }, "batterycritical onEvent was not called  when level goes from 19->5", 100);
+        runs(function () {
+            expect(onEvent).toHaveBeenCalled();
+        });
+        
+        // batterycritical 19->4
+        runs(function () {
+            onEvent = jasmine.createSpy().andCallFake(function () {
+                window.removeEventListener("batterycritical", onEvent, false);
+            });
+            navigator.battery._status({ level: 19, isPlugged: false });
+            window.addEventListener("batterycritical", onEvent, false);
+            navigator.battery._status({ level: 4, isPlugged: false });
+        });
+        waitsFor(function () { return onEvent.wasCalled; }, "batterycritical onEvent was not called  when level goes from 19->4", 100);
+        runs(function () {
+            expect(onEvent).toHaveBeenCalled();
+        });
+    });
+
+    it("battery.spec.5 should NOT fire events when charging or level is increasing", function () {
+       var onEvent;
+       // setup: batterycritical should fire when level decreases (100->4) ( CB-4519 )
+       runs(function () {
+            onEvent = jasmine.createSpy("onbatterycritical");
+            navigator.battery._status({ level: 100, isPlugged: false });
+            window.addEventListener("batterycritical", onEvent, false);
+            navigator.battery._status({ level: 4, isPlugged: false });
+            });
+       waits(100);
+       runs(function () {
+            expect(onEvent).toHaveBeenCalled();
+            });
+       
+       // batterycritical should not fire when level increases (4->5)( CB-4519 )
+       runs(function () {
+            onEvent = jasmine.createSpy("onbatterycritical");
+            navigator.battery._status({ level: 4, isPlugged: false });
+            window.addEventListener("batterycritical", onEvent, false);
+            navigator.battery._status({ level: 5, isPlugged: false });
+            });
+       waits(100);
+       runs(function () {
+            expect(onEvent).not.toHaveBeenCalled();
+            });
+        // batterylow should not fire when level increases (5->20) ( CB-4519 )
+        runs(function () {
+            onEvent = jasmine.createSpy("onbatterylow");
+            window.addEventListener("batterylow", onEvent, false);
+            navigator.battery._status({ level: 20, isPlugged: false });
+        });
+        waits(100);
+        runs(function () {
+            expect(onEvent).not.toHaveBeenCalled();
+        });
+
+        // batterylow should NOT fire if we are charging   ( CB-4520 )
+        runs(function () {
+            onEvent = jasmine.createSpy("onbatterylow");
+            navigator.battery._status({ level: 21, isPlugged: true });
+            window.addEventListener("batterylow", onEvent, false);
+            navigator.battery._status({ level: 20, isPlugged: true });
+        });
+        waits(100);
+        runs(function () {
+            expect(onEvent).not.toHaveBeenCalled();
+        });
+
+        // batterycritical should NOT fire if we are charging   ( CB-4520 )
+        runs(function () {
+            onEvent = jasmine.createSpy("onbatterycritical");
+            navigator.battery._status({ level: 6, isPlugged: true });
+            window.addEventListener("batterycritical", onEvent, false);
+            navigator.battery._status({ level: 5, isPlugged: true });
+            
+        });
+        waits(100);
+        runs(function () {
+            expect(onEvent).not.toHaveBeenCalled();
+        });
+    });
+
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/bridge.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/bridge.tests.js b/www/autotest/tests/bridge.tests.js
new file mode 100644
index 0000000..28c44c2
--- /dev/null
+++ b/www/autotest/tests/bridge.tests.js
@@ -0,0 +1,37 @@
+/*
+ *
+ * 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('Bridge', function() {
+    if (cordova.platformId == 'android') {
+        it("bridge.spec.1 should reject bridge from iframe with data: URL", function() {
+            var ifr = document.createElement('iframe');
+            var done = false;
+            ifr.src = 'data:text/html,';
+            ifr.onload = function() {
+                var stolenSecret = ifr.contentWindow.prompt('', 'gap_init:');
+                done = true;
+                expect(stolenSecret).toBe(null);
+            };
+            document.body.appendChild(ifr);
+            waitsFor(function() { return done; });
+        });
+    }
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/camera.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/camera.tests.js b/www/autotest/tests/camera.tests.js
new file mode 100644
index 0000000..ee5bacd
--- /dev/null
+++ b/www/autotest/tests/camera.tests.js
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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('Camera (navigator.camera)', function () {
+	it("should exist", function() {
+        expect(navigator.camera).toBeDefined();
+	});
+
+	it("should contain a getPicture function", function() {
+        expect(navigator.camera.getPicture).toBeDefined();
+		expect(typeof navigator.camera.getPicture == 'function').toBe(true);
+	});
+});
+
+describe('Camera Constants (window.Camera + navigator.camera)', function () {
+    it("camera.spec.1 window.Camera should exist", function() {
+        expect(window.Camera).toBeDefined();
+    });
+
+    it("camera.spec.2 should contain three DestinationType constants", function() {
+        expect(Camera.DestinationType.DATA_URL).toBe(0);
+        expect(Camera.DestinationType.FILE_URI).toBe(1);
+        expect(Camera.DestinationType.NATIVE_URI).toBe(2);
+        expect(navigator.camera.DestinationType.DATA_URL).toBe(0);
+        expect(navigator.camera.DestinationType.FILE_URI).toBe(1);
+        expect(navigator.camera.DestinationType.NATIVE_URI).toBe(2);
+    });
+
+    it("camera.spec.3 should contain two EncodingType constants", function() {
+        expect(Camera.EncodingType.JPEG).toBe(0);
+        expect(Camera.EncodingType.PNG).toBe(1);
+        expect(navigator.camera.EncodingType.JPEG).toBe(0);
+        expect(navigator.camera.EncodingType.PNG).toBe(1);
+    });
+
+    it("camera.spec.4 should contain three MediaType constants", function() {
+        expect(Camera.MediaType.PICTURE).toBe(0);
+        expect(Camera.MediaType.VIDEO).toBe(1);
+        expect(Camera.MediaType.ALLMEDIA).toBe(2);
+        expect(navigator.camera.MediaType.PICTURE).toBe(0);
+        expect(navigator.camera.MediaType.VIDEO).toBe(1);
+        expect(navigator.camera.MediaType.ALLMEDIA).toBe(2);
+    });
+    it("camera.spec.5 should contain three PictureSourceType constants", function() {
+        expect(Camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
+        expect(Camera.PictureSourceType.CAMERA).toBe(1);
+        expect(Camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
+        expect(navigator.camera.PictureSourceType.PHOTOLIBRARY).toBe(0);
+        expect(navigator.camera.PictureSourceType.CAMERA).toBe(1);
+        expect(navigator.camera.PictureSourceType.SAVEDPHOTOALBUM).toBe(2);
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/capture.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/capture.tests.js b/www/autotest/tests/capture.tests.js
new file mode 100644
index 0000000..99ce438
--- /dev/null
+++ b/www/autotest/tests/capture.tests.js
@@ -0,0 +1,112 @@
+/*
+ *
+ * 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('Capture (navigator.device.capture)', function () {
+    it("capture.spec.1 should exist", function() {
+        expect(navigator.device).toBeDefined();
+        expect(navigator.device.capture).toBeDefined();
+    });
+
+    it("capture.spec.2 should have the correct properties ", function() {
+        expect(navigator.device.capture.supportedAudioModes).toBeDefined();
+        expect(navigator.device.capture.supportedImageModes).toBeDefined();
+        expect(navigator.device.capture.supportedVideoModes).toBeDefined();
+    });
+
+    it("capture.spec.3 should contain a captureAudio function", function() {
+        expect(navigator.device.capture.captureAudio).toBeDefined();
+        expect(typeof navigator.device.capture.captureAudio == 'function').toBe(true);
+    });
+
+    it("capture.spec.4 should contain a captureImage function", function() {
+        expect(navigator.device.capture.captureImage).toBeDefined();
+        expect(typeof navigator.device.capture.captureImage == 'function').toBe(true);
+    });
+
+    it("capture.spec.5 should contain a captureVideo function", function() {
+        expect(navigator.device.capture.captureVideo).toBeDefined();
+        expect(typeof navigator.device.capture.captureVideo == 'function').toBe(true);
+    });
+
+    describe('CaptureAudioOptions', function () {
+        it("capture.spec.6 CaptureAudioOptions constructor should exist", function() {
+            var options = new CaptureAudioOptions();
+            expect(options).toBeDefined();
+            expect(options.limit).toBeDefined();
+            expect(options.duration).toBeDefined();
+        });
+    });
+
+    describe('CaptureImageOptions', function () {
+        it("capture.spec.7 CaptureImageOptions constructor should exist", function() {
+            var options = new CaptureImageOptions();
+            expect(options).toBeDefined();
+            expect(options.limit).toBeDefined();
+        });
+    });
+
+    describe('CaptureVideoOptions', function () {
+        it("capture.spec.8 CaptureVideoOptions constructor should exist", function() {
+            var options = new CaptureVideoOptions();
+            expect(options).toBeDefined();
+            expect(options.limit).toBeDefined();
+            expect(options.duration).toBeDefined();
+        });
+    });
+
+    describe('CaptureError interface', function () {
+        it("capture.spec.9 CaptureError constants should be defined", function() {
+            expect(CaptureError.CAPTURE_INTERNAL_ERR).toBe(0);
+            expect(CaptureError.CAPTURE_APPLICATION_BUSY).toBe(1);
+            expect(CaptureError.CAPTURE_INVALID_ARGUMENT).toBe(2);
+            expect(CaptureError.CAPTURE_NO_MEDIA_FILES).toBe(3);
+        });
+
+        it("capture.spec.10 CaptureError properties should exist", function() {
+            var error = new CaptureError();
+            expect(error).toBeDefined();
+            expect(error.code).toBeDefined();
+        });
+    });
+
+    describe('MediaFileData', function () {
+        it("capture.spec.11 MediaFileData constructor should exist", function() {
+            var fileData = new MediaFileData();
+            expect(fileData).toBeDefined();
+            expect(fileData.bitrate).toBeDefined();
+            expect(fileData.codecs).toBeDefined();
+            expect(fileData.duration).toBeDefined();
+            expect(fileData.height).toBeDefined();
+            expect(fileData.width).toBeDefined();
+        });
+    });
+
+    describe('MediaFile', function () {
+        it("capture.spec.12 MediaFile constructor should exist", function() {
+            var fileData = new MediaFile();
+            expect(fileData).toBeDefined();
+            expect(fileData.name).toBeDefined();
+            expect(fileData.type).toBeDefined();
+            expect(fileData.lastModifiedDate).toBeDefined();
+            expect(fileData.size).toBeDefined();
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/compass.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/compass.tests.js b/www/autotest/tests/compass.tests.js
new file mode 100644
index 0000000..332daea
--- /dev/null
+++ b/www/autotest/tests/compass.tests.js
@@ -0,0 +1,136 @@
+/*
+ *
+ * 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('Compass (navigator.compass)', function () {
+	var hardwarefailure = false;
+	beforeEach(function() {
+        this.addMatchers({
+        	// check to see if the device has a compass, if it doesn't fail gracefully 
+            hasHardware: function() {
+        		var toreturn = true;
+        	    
+        		try{
+        			this.actual;
+        			toreturn = true;
+        		} catch (error){
+        			if (error.code == CompassError.COMPASS_NOT_SUPPORTED){
+        				hardwarefailure = true;
+            			toreturn = false;
+        			}
+        		}
+        		this.message = function () {
+        	       return "The device does not have compass support.  The remaining compass tests will be ignored.";
+        	    }
+
+        		return toreturn;
+            }
+        });
+	});
+	
+	afterEach(function () {
+		// We want to gracefully fail if there is a hardware failure
+		if(this.results_.failedCount > 0 && hardwarefailure == true) {
+			//there was a hardware failure, cancelling all tests
+			jasmine.Queue.prototype.next_ = function () { this.onComplete();}
+		}
+	});
+	
+	it("compass.hardwarecheck is compass supported", function() {
+		var f = function(){navigator.compass.getCurrentHeading(function onSuccess(){}, function onError(error) {})};
+		expect(f).hasHardware();
+	}); 
+	
+	it("compass.spec.1 should exist", function() {
+        expect(navigator.compass).toBeDefined();
+    });
+
+    it("compass.spec.2 should contain a getCurrentHeading function", function() {
+        expect(navigator.compass.getCurrentHeading).toBeDefined();
+		expect(typeof navigator.compass.getCurrentHeading == 'function').toBe(true);
+	});
+
+    it("compass.spec.3 getCurrentHeading success callback should be called with a Heading object", function() {
+        var win = jasmine.createSpy().andCallFake(function(a) {
+                expect(a instanceof CompassHeading).toBe(true);
+                expect(a.magneticHeading).toBeDefined();
+                expect(typeof a.magneticHeading == 'number').toBe(true);
+                expect(a.trueHeading).not.toBe(undefined);
+                expect(typeof a.trueHeading == 'number' || a.trueHeading === null).toBe(true);
+                expect(a.headingAccuracy).not.toBe(undefined);
+                expect(typeof a.headingAccuracy == 'number' || a.headingAccuracy === null).toBe(true);
+                expect(typeof a.timestamp == 'number').toBe(true);
+            }),
+            fail = jasmine.createSpy();
+
+        runs(function () {
+            navigator.compass.getCurrentHeading(win, fail);
+        });
+
+        waitsFor(function () { return win.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+
+        runs(function () {
+            expect(fail).not.toHaveBeenCalled();
+            expect(win).toHaveBeenCalled();
+        });
+	});
+
+    it("compass.spec.4 should contain a watchHeading function", function() {
+        expect(navigator.compass.watchHeading).toBeDefined();
+        expect(typeof navigator.compass.watchHeading == 'function').toBe(true);
+    });
+
+    it("compass.spec.5 should contain a clearWatch function", function() {
+        expect(navigator.compass.clearWatch).toBeDefined();
+        expect(typeof navigator.compass.clearWatch == 'function').toBe(true);
+    });
+
+    describe('Compass Constants (window.CompassError)', function () {
+        it("compass.spec.1 should exist", function() {
+            expect(window.CompassError).toBeDefined();
+            expect(window.CompassError.COMPASS_INTERNAL_ERR).toBe(0);
+            expect(window.CompassError.COMPASS_NOT_SUPPORTED).toBe(20);
+        });
+    });
+
+    describe('Compass Heading model (CompassHeading)', function () {
+        it("compass.spec.1 should exist", function() {
+            expect(CompassHeading).toBeDefined();
+        });
+
+        it("compass.spec.8 should be able to create a new CompassHeading instance with no parameters", function() {
+            var h = new CompassHeading();
+            expect(h).toBeDefined();
+            expect(h.magneticHeading).toBeUndefined();
+            expect(h.trueHeading).toBeUndefined();
+            expect(h.headingAccuracy).toBeUndefined();
+            expect(typeof h.timestamp == 'number').toBe(true);
+        });
+
+        it("compass.spec.9 should be able to create a new CompassHeading instance with parameters", function() {
+            var h = new CompassHeading(1,2,3,4);
+            expect(h.magneticHeading).toBe(1);
+            expect(h.trueHeading).toBe(2);
+            expect(h.headingAccuracy).toBe(3);
+            expect(h.timestamp.valueOf()).toBe(4);
+            expect(typeof h.timestamp == 'number').toBe(true);
+        });
+    });
+});


[16/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/contacts.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/contacts.tests.js b/autotest/tests/contacts.tests.js
deleted file mode 100644
index 73a605c..0000000
--- a/autotest/tests/contacts.tests.js
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-// global to store a contact so it doesn't have to be created or retrieved multiple times
-// all of the setup/teardown test methods can reference the following variables to make sure to do the right cleanup
-var gContactObj = null,
-    gContactId = null,
-    isWindowsPhone = cordova.platformId == 'windowsphone';
-
-var removeContact = function(){
-    if (gContactObj) {
-        gContactObj.remove(function(){},function(){
-            console.log("[CONTACTS ERROR]: removeContact cleanup method failed to clean up test artifacts.");
-        });
-        gContactObj = null;
-    }
-};
-
-describe("Contacts (navigator.contacts)", function () {
-    it("contacts.spec.1 should exist", function() {
-        expect(navigator.contacts).toBeDefined();
-    });
-
-    it("contacts.spec.2 should contain a find function", function() {
-        expect(navigator.contacts.find).toBeDefined();
-        expect(typeof navigator.contacts.find).toBe('function');
-    });
-
-    describe("find method", function() {
-        it("contacts.spec.3 success callback should be called with an array", function() {
-            var win = jasmine.createSpy().andCallFake(function(result) {
-                    expect(result).toBeDefined();
-                    expect(result instanceof Array).toBe(true);
-                }),
-                fail = jasmine.createSpy(),
-                obj = new ContactFindOptions();
-
-            runs(function () {
-                obj.filter="";
-                obj.multiple=true;
-                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, obj);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-
-        it("success callback should be called with an array, even if partial ContactFindOptions specified", function () {
-            var win = jasmine.createSpy().andCallFake(function (result) {
-                expect(result).toBeDefined();
-                expect(result instanceof Array).toBe(true);
-            }),
-                fail = jasmine.createSpy();
-
-            runs(function () {
-                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, {
-                    multiple: true
-                });
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-
-        it("contacts.spec.4 should throw an exception if success callback is empty", function() {
-            var fail = function() {};
-            var obj = new ContactFindOptions();
-            obj.filter="";
-            obj.multiple=true;
-
-            expect(function () {
-                navigator.contacts.find(["displayName", "name", "emails", "phoneNumbers"], null, fail, obj);
-            }).toThrow();
-        });
-
-        it("contacts.spec.5 error callback should be called when no fields are specified", function() {
-            var win = jasmine.createSpy(),
-                fail = jasmine.createSpy(function(result) {
-                    expect(result).toBeDefined();
-                    expect(result.code).toBe(ContactError.INVALID_ARGUMENT_ERROR);
-                }),
-                obj = new ContactFindOptions();
-
-            runs(function () {
-                obj.filter="";
-                obj.multiple=true;
-                navigator.contacts.find([], win, fail, obj);
-            });
-
-            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(win).not.toHaveBeenCalled();
-                expect(fail).toHaveBeenCalled();
-            });
-        });
-
-        describe("with newly-created contact", function () {
-
-            afterEach(removeContact);
-
-            it("contacts.spec.6 should be able to find a contact by name", function() {
-
-                // this api requires manual user confirmation on WP7/8 so skip it
-                if (isWindowsPhone) return;
-
-                var foundName = jasmine.createSpy().andCallFake(function(result) {
-                        var bFound = false;
-                        try {
-                            for (var i=0; i < result.length; i++) {
-                                if (result[i].name.familyName == "Delete") {
-                                    bFound = true;
-                                    break;
-                                }
-                            }
-                        } catch(e) {
-                            return false;
-                        }
-                        return bFound;
-                    }),
-                    fail = jasmine.createSpy(),
-                    test = jasmine.createSpy().andCallFake(function(savedContact) {
-                        console.log('in test');
-                        // update so contact will get removed
-                        gContactObj = savedContact;
-                        // ----
-                        // Find asserts
-                        // ---
-                        var findWin = jasmine.createSpy().andCallFake(function(object) {
-                                console.log('in findwin');
-                                expect(object instanceof Array).toBe(true);
-                                expect(object.length >= 1).toBe(true);
-                                expect(foundName(object)).toBe(true);
-                            }),
-                            findFail = jasmine.createSpy(),
-                            obj = new ContactFindOptions();
-
-                        obj.filter="Delete";
-                        obj.multiple=true;
-
-                        runs(function () {
-                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
-                        });
-
-                        waitsFor(function () { return foundName.wasCalled; }, "foundName not done", Tests.TEST_TIMEOUT);
-
-                        runs(function () {
-                            expect(findFail).not.toHaveBeenCalled();
-                            expect(fail).not.toHaveBeenCalled();
-                        });
-                    });
-
-                runs(function () {
-                    gContactObj = new Contact();
-                    gContactObj.name = new ContactName();
-                    gContactObj.name.familyName = "Delete";
-                    gContactObj.save(test, fail);
-                });
-
-                waitsFor(function () { return test.wasCalled; }, "test not done", Tests.TEST_TIMEOUT);
-            });
-        });
-    });
-
-    describe('create method', function() {
-
-        it("contacts.spec.7 should exist", function() {
-            expect(navigator.contacts.create).toBeDefined();
-            expect(typeof navigator.contacts.create).toBe('function');
-        });
-
-        it("contacts.spec.8 should return a Contact object", function() {
-            var bDay = new Date(1976, 7,4);
-            var obj = navigator.contacts.create({"displayName": "test name", "gender": "male", "note": "my note", "name": {"formatted": "Mr. Test Name"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay});
-
-            expect(obj).toBeDefined();
-            expect(obj.displayName).toBe('test name');
-            expect(obj.note).toBe('my note');
-            expect(obj.name.formatted).toBe('Mr. Test Name');
-            expect(obj.emails.length).toBe(2);
-            expect(obj.emails[0].value).toBe('here@there.com');
-            expect(obj.emails[1].value).toBe('there@here.com');
-            expect(obj.nickname).toBe(null);
-            expect(obj.birthday).toBe(bDay);
-        });
-    });
-
-    describe("Contact object", function () {
-        it("contacts.spec.9 should be able to create instance", function() {
-            var contact = new Contact("a", "b", new ContactName("a", "b", "c", "d", "e", "f"), "c", [], [], [], [], [], "f", "i",
-                [], [], []);
-            expect(contact).toBeDefined();
-            expect(contact.id).toBe("a");
-            expect(contact.displayName).toBe("b");
-            expect(contact.name.formatted).toBe("a");
-            expect(contact.nickname).toBe("c");
-            expect(contact.phoneNumbers).toBeDefined();
-            expect(contact.emails).toBeDefined();
-            expect(contact.addresses).toBeDefined();
-            expect(contact.ims).toBeDefined();
-            expect(contact.organizations).toBeDefined();
-            expect(contact.birthday).toBe("f");
-            expect(contact.note).toBe("i");
-            expect(contact.photos).toBeDefined();
-            expect(contact.categories).toBeDefined();
-            expect(contact.urls).toBeDefined();
-        });
-
-        it("contacts.spec.10 should be able to define a ContactName object", function() {
-            var contactName = new ContactName("Dr. First Last Jr.", "Last", "First", "Middle", "Dr.", "Jr.");
-            expect(contactName).toBeDefined();
-            expect(contactName.formatted).toBe("Dr. First Last Jr.");
-            expect(contactName.familyName).toBe("Last");
-            expect(contactName.givenName).toBe("First");
-            expect(contactName.middleName).toBe("Middle");
-            expect(contactName.honorificPrefix).toBe("Dr.");
-            expect(contactName.honorificSuffix).toBe("Jr.");
-        });
-
-        it("contacts.spec.11 should be able to define a ContactField object", function() {
-            var contactField = new ContactField("home", "8005551212", true);
-            expect(contactField).toBeDefined();
-            expect(contactField.type).toBe("home");
-            expect(contactField.value).toBe("8005551212");
-            expect(contactField.pref).toBe(true);
-        });
-
-        it("contacts.spec.12 ContactField object should coerce type and value properties to strings", function() {
-            var contactField = new ContactField(12345678, 12345678, true);
-            expect(contactField.type).toBe("12345678");
-            expect(contactField.value).toBe("12345678");
-        });
-
-        it("contacts.spec.13 should be able to define a ContactAddress object", function() {
-            var contactAddress = new ContactAddress(true, "home", "a","b","c","d","e","f");
-            expect(contactAddress).toBeDefined();
-            expect(contactAddress.pref).toBe(true);
-            expect(contactAddress.type).toBe("home");
-            expect(contactAddress.formatted).toBe("a");
-            expect(contactAddress.streetAddress).toBe("b");
-            expect(contactAddress.locality).toBe("c");
-            expect(contactAddress.region).toBe("d");
-            expect(contactAddress.postalCode).toBe("e");
-            expect(contactAddress.country).toBe("f");
-        });
-
-        it("contacts.spec.14 should be able to define a ContactOrganization object", function() {
-            var contactOrg = new ContactOrganization(true, "home", "a","b","c","d","e","f","g");
-            expect(contactOrg).toBeDefined();
-            expect(contactOrg.pref).toBe(true);
-            expect(contactOrg.type).toBe("home");
-            expect(contactOrg.name).toBe("a");
-            expect(contactOrg.department).toBe("b");
-            expect(contactOrg.title).toBe("c");
-        });
-
-        it("contacts.spec.15 should be able to define a ContactFindOptions object", function() {
-            var contactFindOptions = new ContactFindOptions("a", true, "b");
-            expect(contactFindOptions).toBeDefined();
-            expect(contactFindOptions.filter).toBe("a");
-            expect(contactFindOptions.multiple).toBe(true);
-        });
-
-        it("contacts.spec.16 should contain a clone function", function() {
-            var contact = new Contact();
-            expect(contact.clone).toBeDefined();
-            expect(typeof contact.clone).toBe('function');
-        });
-
-        it("contacts.spec.17 clone function should make deep copy of Contact Object", function() {
-            var contact = new Contact();
-            contact.id=1;
-            contact.displayName="Test Name";
-            contact.nickname="Testy";
-            contact.gender="male";
-            contact.note="note to be cloned";
-            contact.name = new ContactName("Mr. Test Name");
-
-            var clonedContact = contact.clone();
-
-            expect(contact.id).toBe(1);
-            expect(clonedContact.id).toBe(null);
-            expect(clonedContact.displayName).toBe(contact.displayName);
-            expect(clonedContact.nickname).toBe(contact.nickname);
-            expect(clonedContact.gender).toBe(contact.gender);
-            expect(clonedContact.note).toBe(contact.note);
-            expect(clonedContact.name.formatted).toBe(contact.name.formatted);
-            expect(clonedContact.connected).toBe(contact.connected);
-        });
-
-        it("contacts.spec.18 should contain a save function", function() {
-            var contact = new Contact();
-            expect(contact.save).toBeDefined();
-            expect(typeof contact.save).toBe('function');
-        });
-
-        it("contacts.spec.19 should contain a remove function", function() {
-            var contact = new Contact();
-            expect(contact.remove).toBeDefined();
-            expect(typeof contact.remove).toBe('function');
-        });
-    });
-
-    describe('save method', function () {
-        it("contacts.spec.20 should be able to save a contact", function() {
-
-            // this api requires manual user confirmation on WP7/8 so skip it
-            if (isWindowsPhone) return;
-
-            var bDay = new Date(1976, 6,4);
-            gContactObj = navigator.contacts.create({"gender": "male", "note": "my note", "name": {"familyName": "Delete", "givenName": "Test"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}], "birthday": bDay});
-
-            var saveSuccess = jasmine.createSpy().andCallFake(function(obj) {
-                    expect(obj).toBeDefined();
-                    if (cordova.platformId !== 'blackberry10') {
-                        expect(obj.note).toBe('my note');
-                    }
-                    expect(obj.name.familyName).toBe('Delete');
-                    expect(obj.name.givenName).toBe('Test');
-                    expect(obj.emails.length).toBe(2);
-                    expect(obj.emails[0].value).toBe('here@there.com');
-                    expect(obj.emails[1].value).toBe('there@here.com');
-                    expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
-                    expect(obj.addresses).toBe(null);
-                    // must store returned object in order to have id for update test below
-                    gContactObj = obj;
-                }),
-                saveFail = jasmine.createSpy();
-
-            runs(function () {
-                gContactObj.save(saveSuccess, saveFail);
-            });
-
-            waitsFor(function () { return saveSuccess.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(saveFail).not.toHaveBeenCalled();
-            });
-         });
-        // HACK: there is a reliance between the previous and next test. This is bad form.
-        it("contacts.spec.21 update a contact", function() {
-
-            // this api requires manual user confirmation on WP7/8 so skip it
-            if (isWindowsPhone) return;
-
-            expect(gContactObj).toBeDefined();
-
-            var bDay = new Date(1975, 5,4);
-            var noteText = "an UPDATED note";
-
-            var win = jasmine.createSpy().andCallFake(function(obj) {
-                    expect(obj).toBeDefined();
-                    expect(obj.id).toBe(gContactObj.id);
-                    if (cordova.platformId !== 'blackberry10') {
-                        expect(obj.note).toBe(noteText);
-                    }
-                    expect(obj.birthday.toDateString()).toBe(bDay.toDateString());
-                    expect(obj.emails.length).toBe(1);
-                    expect(obj.emails[0].value).toBe('here@there.com');
-                    removeContact();         // Clean up contact object
-                }), fail = jasmine.createSpy().andCallFake(removeContact);
-
-            runs(function () {
-                // remove an email
-                gContactObj.emails[1].value = "";
-                // change birthday
-                gContactObj.birthday = bDay;
-                // update note
-                gContactObj.note = noteText;
-                gContactObj.save(win, fail);
-            });
-
-            waitsFor(function () { return win.wasCalled; }, "saveSuccess never called", Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(fail).not.toHaveBeenCalled();
-            });
-        });
-    });
-
-    describe('Contact.remove method', function () {
-        afterEach(removeContact);
-
-        it("contacts.spec.22 calling remove on a contact has an id of null should return ContactError.UNKNOWN_ERROR", function() {
-            var win = jasmine.createSpy();
-            var fail = jasmine.createSpy().andCallFake(function(result) {
-                expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
-            });
-
-            runs(function () {
-                var rmContact = new Contact();
-                rmContact.remove(win, fail);
-            });
-
-            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(win).not.toHaveBeenCalled();
-            });
-        });
-
-        it("contacts.spec.23 calling remove on a contact that does not exist should return ContactError.UNKNOWN_ERROR", function() {
-            var win = jasmine.createSpy();
-            var fail = jasmine.createSpy().andCallFake(function(result) {
-                expect(result.code).toBe(ContactError.UNKNOWN_ERROR);
-            });
-
-            runs(function () {
-                var rmContact = new Contact();
-                // this is a bit risky as some devices may have contact ids that large
-                var contact = new Contact("this string is supposed to be a unique identifier that will never show up on a device");
-                contact.remove(win, fail);
-            });
-
-            waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
-
-            runs(function () {
-                expect(win).not.toHaveBeenCalled();
-            });
-        });
-    });
-
-    describe("Round trip Contact tests (creating + save + delete + find).", function () {
-        it("contacts.spec.24 Creating, saving, finding a contact should work, removing it should work, after which we should not be able to find it, and we should not be able to delete it again.", function() {
-
-            // this api requires manual user confirmation on WP7/8 so skip it
-            if (isWindowsPhone) return;
-
-            var done = false;
-            runs(function () {
-                gContactObj = new Contact();
-                gContactObj.name = new ContactName();
-                gContactObj.name.familyName = "DeleteMe";
-                gContactObj.save(function(c_obj) {
-                    var findWin = function(cs) {
-                        expect(cs.length).toBe(1);
-                        // update to have proper saved id
-                        gContactObj = cs[0];
-                        gContactObj.remove(function() {
-                            var findWinAgain = function(seas) {
-                                expect(seas.length).toBe(0);
-                                gContactObj.remove(function() {
-                                    throw("success callback called after non-existent Contact object called remove(). Test failed.");
-                                }, function(e) {
-                                    expect(e.code).toBe(ContactError.UNKNOWN_ERROR);
-                                    done = true;
-                                });
-                            };
-                            var findFailAgain = function(e) {
-                                throw("find error callback invoked after delete, test failed.");
-                            };
-                            var obj = new ContactFindOptions();
-                            obj.filter="DeleteMe";
-                            obj.multiple=true;
-                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWinAgain, findFailAgain, obj);
-                        }, function(e) {
-                            throw("Newly created contact's remove function invoked error callback. Test failed.");
-                        });
-                    };
-                    var findFail = function(e) {
-                        throw("Failure callback invoked in navigator.contacts.find call, test failed.");
-                    };
-                    var obj = new ContactFindOptions();
-                    obj.filter="DeleteMe";
-                    obj.multiple=true;
-                    navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findWin, findFail, obj);
-                }, function(e) {
-                    throw("Contact creation failed, error callback was invoked.");
-                });
-            });
-
-            waitsFor(function () { return done; }, Tests.TEST_TIMEOUT);
-        });
-    });
-
-    describe('ContactError interface', function () {
-        it("contacts.spec.25 ContactError constants should be defined", function() {
-            expect(ContactError.UNKNOWN_ERROR).toBe(0);
-            expect(ContactError.INVALID_ARGUMENT_ERROR).toBe(1);
-            expect(ContactError.TIMEOUT_ERROR).toBe(2);
-            expect(ContactError.PENDING_OPERATION_ERROR).toBe(3);
-            expect(ContactError.IO_ERROR).toBe(4);
-            expect(ContactError.NOT_SUPPORTED_ERROR).toBe(5);
-            expect(ContactError.PERMISSION_DENIED_ERROR).toBe(20);
-        });
-    });
-
-    describe("Contacts autotests cleanup", function () {
-        it("contacts.spec.26 Cleanup any DeleteMe contacts from Contacts tests.", function() {
-            var done = false;
-            var obj = new ContactFindOptions();
-            obj.filter="DeleteMe";
-            obj.multiple=true;
-            runs(function () {
-                var findSuccess = function (cs) {
-                    var contactObj = new Contact();
-                    if (cs.length>0){
-                        contactObj = cs[0];
-                        contactObj.remove(function(){
-                            console.log("[CONTACTS CLEANUP] DeleteMe contact successfully removed");
-                            navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findSuccess, findFail, obj);
-                        },function(){
-                            console.log("[CONTACTS CLEANUP ERROR]: failed to remove DeleteMe contact");
-                        });
-                    } else {
-                        done = true;
-                    }
-                };
-                var findFail = function(e) {
-                    throw("Failure callback invoked in navigator.contacts.find call, test failed.");
-                };
-                navigator.contacts.find(["displayName", "name", "phoneNumbers", "emails"], findSuccess, findFail, obj);
-            });
-            waitsFor(function () { return done; }, Tests.TEST_TIMEOUT);
-        });
-    });
-
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/datauri.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/datauri.tests.js b/autotest/tests/datauri.tests.js
deleted file mode 100644
index 08ebbbc..0000000
--- a/autotest/tests/datauri.tests.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-var isWindowsPhone = cordova.platformId == 'windowsphone';
-
-describe('data uris', function () {
-    it("datauri.spec.1 should work with iframes", function() {
-        // IE on WP7/8 considers 'data:' in frame.src string as protocol type
-        // so asks user to look for appropriating application in the market;
-        // temporary skipped since requires user interaction
-        if (isWindowsPhone) return;
-        var gotFoo = false,
-            frame = document.createElement('iframe');
-        function onMessage(msg) {
-            gotFoo = gotFoo || msg.data == 'foo';
-        };
-
-        this.after(function() {
-            document.body.removeChild(frame);
-            window.removeEventListener('message', onMessage, false);
-        });
-
-        window.addEventListener('message', onMessage, false);
-        frame.src = 'data:text/html;charset=utf-8,%3Chtml%3E%3Cscript%3Eparent.postMessage%28%27foo%27%2C%27%2A%27%29%3C%2Fscript%3E%3C%2Fhtml%3E'
-        document.body.appendChild(frame);
-        waitsFor(function() {
-            return gotFoo;
-        }, 'iframe did not load.', 1000);
-        runs(function() {
-            expect(gotFoo).toBe(true);
-        });
-    });
-    it("datauri.spec.2 should work with images", function() {
-        var img = new Image();
-        img.onload = jasmine.createSpy('onLoad');
-        img.onerror = jasmine.createSpy('onError');
-        img.src = 'data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'
-        waitsFor(function() {
-            return img.onload.wasCalled || img.onerror.wasCalled;
-        }, 'image did not load or error', 1000);
-        runs(function() {
-            expect(img.onload).toHaveBeenCalled();
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/tests/device.tests.js
----------------------------------------------------------------------
diff --git a/autotest/tests/device.tests.js b/autotest/tests/device.tests.js
deleted file mode 100644
index 0bcd0d9..0000000
--- a/autotest/tests/device.tests.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-describe('Device Information (window.device)', function () {
-	it("should exist", function() {
-        expect(window.device).toBeDefined();
-	});
-
-	it("should contain a platform specification that is a string", function() {
-        expect(window.device.platform).toBeDefined();
-		expect((new String(window.device.platform)).length > 0).toBe(true);
-	});
-
-	it("should contain a version specification that is a string", function() {
-        expect(window.device.version).toBeDefined();
-		expect((new String(window.device.version)).length > 0).toBe(true);
-	});
-
-	it("should contain a UUID specification that is a string or a number", function() {
-        expect(window.device.uuid).toBeDefined();
-		if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') {
-		    expect((new String(window.device.uuid)).length > 0).toBe(true);
-		} else {
-			expect(window.device.uuid > 0).toBe(true);
-		}
-	});
-
-	it("should contain a cordova specification that is a string", function() {
-        expect(window.device.cordova).toBeDefined();
-		expect((new String(window.device.cordova)).length > 0).toBe(true);
-	});
-
-    it("should depend on the precense of cordova.version string", function() {
-            expect(window.cordova.version).toBeDefined();
-            expect((new String(window.cordova.version)).length > 0).toBe(true);
-    });
-
-    it("should contain device.cordova equal to cordova.version", function() {
-             expect(window.device.cordova).toBe(window.cordova.version);
-    });
-
-	it("should contain a model specification that is a string", function() {
-        expect(window.device.model).toBeDefined();
-		expect((new String(window.device.model)).length > 0).toBe(true);
-	});
-});


[04/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/globalization.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/globalization.tests.js b/www/autotest/tests/globalization.tests.js
new file mode 100644
index 0000000..ddc7c3c
--- /dev/null
+++ b/www/autotest/tests/globalization.tests.js
@@ -0,0 +1,869 @@
+/*
+ * 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('Globalization (navigator.globalization)', function () {
+
+    //not supported on bb10
+    if (cordova.platformId === 'blackberry10') {
+        return;
+    }
+
+    it("globalization.spec.1 should exist", function() {
+        expect(navigator.globalization).toBeDefined();
+    });
+    
+    describe("getPreferredLanguage", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.getPreferredLanguage).toBeDefined();
+            expect(typeof navigator.globalization.getPreferredLanguage == 'function').toBe(true);
+        });
+        it("globalization.spec.3 getPreferredLanguage success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getPreferredLanguage(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("getLocaleName", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.getLocaleName).toBeDefined();
+            expect(typeof navigator.globalization.getLocaleName == 'function').toBe(true);
+        });
+        it("globalization.spec.3 getLocaleName success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getLocaleName(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe('Globalization Constants (window.Globalization)', function () {
+        it("globalization.spec.1 should exist", function() {
+            expect(window.GlobalizationError).toBeDefined();
+            expect(window.GlobalizationError.UNKNOWN_ERROR).toBe(0);
+            expect(window.GlobalizationError.FORMATTING_ERROR).toBe(1);
+            expect(window.GlobalizationError.PARSING_ERROR).toBe(2);
+            expect(window.GlobalizationError.PATTERN_ERROR).toBe(3);
+        });
+    });
+    
+    describe("dateToString", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.dateToString).toBeDefined();
+            expect(typeof navigator.globalization.dateToString == 'function').toBe(true);
+        });
+        it("globalization.spec.5 dateToString using default options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.6 dateToString using formatLength=short and selector=date options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'short', selector: 'date'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.7 dateToString using formatLength=full and selector=date options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'full', selector: 'date'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.8 dateToString using formatLength=medium and selector=date and time(default) options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'medium'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.9 dateToString using formatLength=long and selector=date and time(default) options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'long'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.10 dateToString using formatLength=full and selector=date and time(default) options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win, fail, {formatLength: 'full'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("stringToDate", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.stringToDate).toBeDefined();
+            expect(typeof navigator.globalization.stringToDate == 'function').toBe(true);
+        });
+        it("globalization.spec.12 stringToDate using default options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.year).toBeDefined();
+                    expect(typeof a.year).toBe('number');
+                    expect(a.year >= 0 && a.year <=9999).toBe(true);
+                    expect(a.month).toBeDefined();
+                    expect(typeof a.month).toBe('number');
+                    expect(a.month >= 0 && a.month <=11).toBe(true);
+                    expect(a.day).toBeDefined();
+                    expect(typeof a.day).toBe('number');
+                    expect(a.day >= 1 && a.day <=31).toBe(true);
+                    expect(a.hour).toBeDefined();
+                    expect(typeof a.hour).toBe('number');
+                    expect(a.hour >= 0 && a.hour <=23).toBe(true);
+                    expect(a.minute).toBeDefined();
+                    expect(typeof a.minute).toBe('number');
+                    expect(a.minute >= 0 && a.minute <=59).toBe(true);
+                    expect(a.second).toBeDefined();
+                    expect(typeof a.second).toBe('number');
+                    expect(a.second >= 0 && a.second <=59).toBe(true);
+                    expect(a.millisecond).toBeDefined();
+                    expect(typeof a.millisecond).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+                
+            var win2 = function(a) {
+                navigator.globalization.stringToDate(a.value, win, fail);                
+            };
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win2, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.13 stringToDate using formatLength=short and selector=date options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.year).toBeDefined();
+                    expect(typeof a.year).toBe('number');
+                    expect(a.year >= 0 && a.year <=9999).toBe(true);
+                    expect(a.month).toBeDefined();
+                    expect(typeof a.month).toBe('number');
+                    expect(a.month >= 0 && a.month <=11).toBe(true);
+                    expect(a.day).toBeDefined();
+                    expect(typeof a.day).toBe('number');
+                    expect(a.day >= 1 && a.day <=31).toBe(true);
+                    expect(a.hour).toBeDefined();
+                    expect(typeof a.hour).toBe('number');
+                    expect(a.hour >= 0 && a.hour <=23).toBe(true);
+                    expect(a.minute).toBeDefined();
+                    expect(typeof a.minute).toBe('number');
+                    expect(a.minute >= 0 && a.minute <=59).toBe(true);
+                    expect(a.second).toBeDefined();
+                    expect(typeof a.second).toBe('number');
+                    expect(a.second >= 0 && a.second <=59).toBe(true);
+                    expect(a.millisecond).toBeDefined();
+                    expect(typeof a.millisecond).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+                
+            var win2 = function(a) {
+                navigator.globalization.stringToDate(a.value, win, fail, {formatLength: 'short', selector: 'date'});
+            };
+
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win2, fail, {formatLength: 'short', selector: 'date'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.14 stringToDate using formatLength=full and selector=date options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.year).toBeDefined();
+                    expect(typeof a.year).toBe('number');
+                    expect(a.year >= 0 && a.year <=9999).toBe(true);
+                    expect(a.month).toBeDefined();
+                    expect(typeof a.month).toBe('number');
+                    expect(a.month >= 0 && a.month <=11).toBe(true);
+                    expect(a.day).toBeDefined();
+                    expect(typeof a.day).toBe('number');
+                    expect(a.day >= 1 && a.day <=31).toBe(true);
+                    expect(a.hour).toBeDefined();
+                    expect(typeof a.hour).toBe('number');
+                    expect(a.hour >= 0 && a.hour <=23).toBe(true);
+                    expect(a.minute).toBeDefined();
+                    expect(typeof a.minute).toBe('number');
+                    expect(a.minute >= 0 && a.minute <=59).toBe(true);
+                    expect(a.second).toBeDefined();
+                    expect(typeof a.second).toBe('number');
+                    expect(a.second >= 0 && a.second <=59).toBe(true);
+                    expect(a.millisecond).toBeDefined();
+                    expect(typeof a.millisecond).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+
+            var win2 = function(a) {
+                navigator.globalization.stringToDate(a.value, win, fail, {formatLength: 'full', selector: 'date'});
+            };
+            runs(function () {
+                navigator.globalization.dateToString(new Date(), win2, fail, {formatLength: 'full', selector: 'date'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.15 stringToDate using invalid date, error callback should be called with a GlobalizationError object", function() {
+            var win = jasmine.createSpy(),
+                fail = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.code).toBeDefined();
+                    expect(typeof a.code).toBe('number');
+                    expect(a.code === GlobalizationError.PARSING_ERROR).toBe(true);
+                    expect(a.message).toBeDefined();
+                    expect(typeof a.message).toBe('string');
+                    expect(a.message !== "").toBe(true);
+                });
+
+            runs(function () {
+                navigator.globalization.stringToDate('notADate', win, fail, {selector:'foobar'});
+            });
+
+            waitsFor(function () { return fail.wasCalled; }, "fail never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(win).not.toHaveBeenCalled();
+            });
+        });
+    });
+
+    describe("getDatePattern", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.getDatePattern).toBeDefined();
+            expect(typeof navigator.globalization.getDatePattern == 'function').toBe(true);
+        });
+        it("globalization.spec.17 getDatePattern using default options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.pattern).toBeDefined();
+                    expect(typeof a.pattern).toBe('string');
+                    expect(a.pattern.length > 0).toBe(true);
+                    expect(a.timezone).toBeDefined();
+                    expect(typeof a.timezone).toBe('string');
+                    expect(a.timezone.length > 0).toBe(true);
+                    expect(a.utc_offset).toBeDefined();
+                    expect(typeof a.utc_offset).toBe('number');
+                    expect(a.dst_offset).toBeDefined();
+                    expect(typeof a.dst_offset).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getDatePattern(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.18 getDatePattern using formatLength=medium and selector=date options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.pattern).toBeDefined();
+                    expect(typeof a.pattern).toBe('string');
+                    expect(a.pattern.length > 0).toBe(true);
+                    expect(a.timezone).toBeDefined();
+                    expect(typeof a.timezone).toBe('string');
+                    expect(a.timezone.length > 0).toBe(true);
+                    expect(a.utc_offset).toBeDefined();
+                    expect(typeof a.utc_offset).toBe('number');
+                    expect(a.dst_offset).toBeDefined();
+                    expect(typeof a.dst_offset).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getDatePattern(win, fail, {formatLength: 'medium', selector: 'date'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });    
+
+    describe("getDateNames", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.getDateNames).toBeDefined();
+            expect(typeof navigator.globalization.getDateNames == 'function').toBe(true);
+        });
+        it("globalization.spec.20 getDateNames using default options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(a.value instanceof Array).toBe(true);
+                    expect(a.value.length > 0).toBe(true);
+                    expect(typeof a.value[0]).toBe('string');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getDateNames(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.21 getDateNames using type=narrow and item=days options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(a.value instanceof Array).toBe(true);
+                    expect(a.value.length > 0).toBe(true);
+                    expect(typeof a.value[0]).toBe('string');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getDateNames(win, fail, {type: 'narrow', item: 'days'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.22 getDateNames using type=narrow and item=months options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(a.value instanceof Array).toBe(true);
+                    expect(a.value.length > 0).toBe(true);
+                    expect(typeof a.value[0]).toBe('string');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getDateNames(win, fail, {type: 'narrow', item: 'months'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.23 getDateNames using type=wide and item=days options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(a.value instanceof Array).toBe(true);
+                    expect(a.value.length > 0).toBe(true);
+                    expect(typeof a.value[0]).toBe('string');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getDateNames(win, fail, {type: 'wide', item: 'days'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.24 getDateNames using type=wide and item=months options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(a.value instanceof Array).toBe(true);
+                    expect(a.value.length > 0).toBe(true);
+                    expect(typeof a.value[0]).toBe('string');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getDateNames(win, fail, {type: 'wide', item: 'months'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("isDayLightSavingsTime", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.isDayLightSavingsTime).toBeDefined();
+            expect(typeof navigator.globalization.isDayLightSavingsTime == 'function').toBe(true);
+        });
+        it("globalization.spec.26 isDayLightSavingsTime using default options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.dst).toBeDefined();
+                    expect(typeof a.dst).toBe('boolean');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.isDayLightSavingsTime(new Date(), win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("getFirstDayOfWeek", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.getFirstDayOfWeek).toBeDefined();
+            expect(typeof navigator.globalization.getFirstDayOfWeek == 'function').toBe(true);
+        });
+        it("globalization.spec.28 getFirstDayOfWeek success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('number');
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getFirstDayOfWeek(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("numberToString", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.numberToString).toBeDefined();
+            expect(typeof navigator.globalization.numberToString == 'function').toBe(true);
+        });
+        it("globalization.spec.30 numberToString using default options, should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.numberToString(3.25, win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.31 numberToString using type=percent options, should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.numberToString(.25, win, fail, {type: 'percent'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.32 numberToString using type=currency options, should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('string');
+                    expect(a.value.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.numberToString(5.20, win, fail, {type: 'currency'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("stringToNumber", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.stringToNumber).toBeDefined();
+            expect(typeof navigator.globalization.stringToNumber == 'function').toBe(true);
+        });
+        it("globalization.spec.34 stringToNumber using default options, should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('number');
+                    expect(a.value > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            var win2 = function(a) {
+                navigator.globalization.stringToNumber(a.value, win, fail);
+            };
+            
+            runs(function () {
+                navigator.globalization.numberToString(3.25, win2, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.35 stringToNumber using type=percent options, should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.value).toBeDefined();
+                    expect(typeof a.value).toBe('number');
+                    expect(a.value > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            var win2 = function(a) {
+                navigator.globalization.stringToNumber(a.value, win, fail, {type: 'percent'});
+            };
+            
+            runs(function () {
+                navigator.globalization.numberToString(.25, win2, fail, {type: 'percent'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("getNumberPattern", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.getNumberPattern).toBeDefined();
+            expect(typeof navigator.globalization.getNumberPattern == 'function').toBe(true);
+        });
+        it("globalization.spec.37 getNumberPattern using default options, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.pattern).toBeDefined();
+                    expect(typeof a.pattern).toBe('string');
+                    expect(a.pattern.length > 0).toBe(true);
+                    expect(typeof a.symbol).toBe('string');
+                    expect(typeof a.fraction).toBe('number');
+                    expect(typeof a.rounding).toBe('number');
+                    expect(a.positive).toBeDefined();
+                    expect(typeof a.positive).toBe('string');
+                    expect(a.positive.length >= 0).toBe(true);
+                    expect(a.negative).toBeDefined();
+                    expect(typeof a.negative).toBe('string');
+                    expect(a.negative.length >= 0).toBe(true);
+                    expect(a.decimal).toBeDefined();
+                    expect(typeof a.decimal).toBe('string');
+                    expect(a.decimal.length > 0).toBe(true);
+                    expect(a.grouping).toBeDefined();
+                    expect(typeof a.grouping).toBe('string');
+                    expect(a.grouping.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getNumberPattern(win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.38 getNumberPattern using type=percent, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.pattern).toBeDefined();
+                    expect(typeof a.pattern).toBe('string');
+                    expect(a.pattern.length > 0).toBe(true);
+                    expect(typeof a.symbol).toBe('string');
+                    expect(typeof a.fraction).toBe('number');
+                    expect(typeof a.rounding).toBe('number');
+                    expect(a.positive).toBeDefined();
+                    expect(typeof a.positive).toBe('string');
+                    expect(a.positive.length >= 0).toBe(true);
+                    expect(a.negative).toBeDefined();
+                    expect(typeof a.negative).toBe('string');
+                    expect(a.negative.length >= 0).toBe(true);
+                    expect(a.decimal).toBeDefined();
+                    expect(typeof a.decimal).toBe('string');
+                    expect(a.decimal.length > 0).toBe(true);
+                    expect(a.grouping).toBeDefined();
+                    expect(typeof a.grouping).toBe('string');
+                    expect(a.grouping.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getNumberPattern(win, fail, {type: 'percent'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+        it("globalization.spec.39 getNumberPattern using type=currency, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.pattern).toBeDefined();
+                    expect(typeof a.pattern).toBe('string');
+                    expect(a.pattern.length > 0).toBe(true);
+                    expect(typeof a.symbol).toBe('string');
+                    expect(typeof a.fraction).toBe('number');
+                    expect(typeof a.rounding).toBe('number');
+                    expect(a.positive).toBeDefined();
+                    expect(typeof a.positive).toBe('string');
+                    expect(a.positive.length >= 0).toBe(true);
+                    expect(a.negative).toBeDefined();
+                    expect(typeof a.negative).toBe('string');
+                    expect(a.negative.length >= 0).toBe(true);
+                    expect(a.decimal).toBeDefined();
+                    expect(typeof a.decimal).toBe('string');
+                    expect(a.decimal.length > 0).toBe(true);
+                    expect(a.grouping).toBeDefined();
+                    expect(typeof a.grouping).toBe('string');
+                    expect(a.grouping.length > 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getNumberPattern(win, fail, {type: 'currency'});
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+    
+    describe("getCurrencyPattern", function() {
+        it("globalization.spec.1 should exist", function() {
+            expect(typeof navigator.globalization.getCurrencyPattern).toBeDefined();
+            expect(typeof navigator.globalization.getCurrencyPattern == 'function').toBe(true);
+        });
+        it("globalization.spec.41 getCurrencyPattern using EUR for currency, success callback should be called with a Properties object", function() {
+            var win = jasmine.createSpy().andCallFake(function(a) {
+                    expect(a).toBeDefined();
+                    expect(typeof a).toBe('object');
+                    expect(a.pattern).toBeDefined();
+                    expect(typeof a.pattern).toBe('string');
+                    expect(a.pattern.length > 0).toBe(true);
+                    expect(a.code).toBeDefined();
+                    expect(typeof a.code).toBe('string');
+                    expect(a.code.length > 0).toBe(true);
+                    expect(typeof a.fraction).toBe('number');
+                    expect(typeof a.rounding).toBe('number');                   
+                    expect(a.decimal).toBeDefined();
+                    expect(typeof a.decimal).toBe('string');
+                    expect(a.decimal.length >= 0).toBe(true);                    
+                    expect(a.grouping).toBeDefined();
+                    expect(typeof a.grouping).toBe('string');
+                    expect(a.grouping.length >= 0).toBe(true);
+                }),
+                fail = jasmine.createSpy();
+
+            runs(function () {
+                navigator.globalization.getCurrencyPattern("EUR", win, fail);
+            });
+
+            waitsFor(function () { return win.wasCalled; }, "win never called", Tests.TEST_TIMEOUT);
+
+            runs(function () {
+                expect(fail).not.toHaveBeenCalled();
+            });
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/localXHR.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/localXHR.tests.js b/www/autotest/tests/localXHR.tests.js
new file mode 100644
index 0000000..c50105d
--- /dev/null
+++ b/www/autotest/tests/localXHR.tests.js
@@ -0,0 +1,189 @@
+/*
+ *
+ * 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("XMLHttpRequest", function () {
+
+    var createXHR = function (url, bAsync, win, lose) {
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", url, bAsync);
+        xhr.onload = win;
+        xhr.onerror = lose;
+        xhr.send();
+        return xhr;
+    }
+
+        it("XMLHttpRequest.spec.1 should exist", function () {
+            expect(window.XMLHttpRequest).toBeDefined();
+            expect(window.XMLHttpRequest.UNSENT).toBe(0);
+            expect(window.XMLHttpRequest.OPENED).toBe(1);
+            expect(window.XMLHttpRequest.HEADERS_RECEIVED).toBe(2);
+            expect(window.XMLHttpRequest.LOADING).toBe(3);
+            expect(window.XMLHttpRequest.DONE).toBe(4);
+        });
+
+        it("XMLHttpRequest.spec.2 should be able to create new XHR", function () {
+
+        	var xhr = new XMLHttpRequest();
+        	expect(xhr).toBeDefined();
+
+    // abort
+        	expect(xhr.abort).toBeDefined();
+        	expect(typeof xhr.abort == 'function').toBe(true);
+
+    // getResponseHeader
+        	expect(xhr.getResponseHeader).toBeDefined();
+        	expect(typeof xhr.getResponseHeader == 'function').toBe(true);
+
+    // getAllResponseHeaders
+        	expect(xhr.getAllResponseHeaders).toBeDefined();
+        	expect(typeof xhr.getAllResponseHeaders == 'function').toBe(true);
+
+    // overrideMimeType
+        	expect(xhr.overrideMimeType).toBeDefined();
+        	expect(typeof xhr.overrideMimeType == 'function').toBe(true);
+        	return;
+    // open
+        	expect(xhr.open).toBeDefined();
+        	expect(typeof xhr.open == 'function').toBe(true);
+    // send
+        	expect(xhr.send).toBeDefined();
+        	expect(typeof xhr.send == 'function').toBe(true);
+    // setRequestHeader
+        	expect(xhr.setRequestHeader).toBeDefined();
+        	expect(typeof xhr.setRequestHeader == 'function').toBe(true);
+        });
+
+        it("XMLHttpRequest.spec.2 should be able to load the current page", function () {
+            var win = jasmine.createSpy().andCallFake(function (res) {});
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR("localXHR.html", true, win, lose);
+            waitsForAny(win, lose);
+
+        });
+
+        it("XMLHttpRequest.spec.9 calls onload from successful http get", function () {
+            var win = jasmine.createSpy().andCallFake(function (res) { });
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR("http://cordova-filetransfer.jitsu.com", true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+        it("XMLHttpRequest.spec.3 should be able to load the current page", function () {
+            var win = jasmine.createSpy().andCallFake(function (res) {});
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR(window.location.href, true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+        it("XMLHttpRequest.spec.4 should be able to load the parent folder page ../index.html", function () {
+            var win = jasmine.createSpy().andCallFake(function (res) {});
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR("../index.html", true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+        it("XMLHttpRequest.spec.5 should be able to load the current page ./???.html", function () {
+            var win = jasmine.createSpy().andCallFake(function (res) { });
+            var lose = createDoNotCallSpy('xhrFail');
+            var fileName = window.location.href.split('#')[0].split('/').pop();
+            var xhr = createXHR("./" + fileName, true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+        it("XMLHttpRequest.spec.6 adds hash-path and loads file okay", function () {
+            window.location = window.location.href + "#asd/asd/asdasd";
+            var win = jasmine.createSpy().andCallFake(function (res) { });
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR(window.location.href, true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+    it("XMLHttpRequest.spec.10 overlapping async calls are not muxed", function () {
+
+        var order = "";
+
+        var winA = jasmine.createSpy("spyWinA").andCallFake(function(){
+            order += "A";  
+        });
+        var winB = jasmine.createSpy("spyWinB").andCallFake(function(){
+            order += "B";  
+        });
+        var lose = createDoNotCallSpy('xhrFail');
+        var fileName = window.location.href.split('#')[0].split('/').pop();
+        createXHR(fileName, true, winA, lose);
+        createXHR(fileName, false, winB, lose);
+
+        waitsFor(function () {
+            return lose.wasCalled ||
+                (winA.wasCalled && winB.wasCalled);
+        }, "Expecting both callbacks to be called.", Tests.TEST_TIMEOUT);
+
+        runs(function () {
+            expect(lose).not.toHaveBeenCalled();
+            expect(winA).toHaveBeenCalled();
+            expect(winB).toHaveBeenCalled();
+            console.log("order = " + order);
+        });
+    });
+
+
+});
+
+// only add these tests if we are testing on windows phone
+
+if (/Windows Phone/.exec(navigator.userAgent)) {
+
+    var createXHR = function (url, bAsync, win, lose) {
+        var xhr = new XMLHttpRequest();
+        xhr.open("GET", url, bAsync);
+        xhr.onload = win;
+        xhr.onerror = lose;
+        xhr.send();
+        return xhr;
+    }
+
+    describe("XMLHttpRequest Windows Phone", function () {
+
+        console.log("running special windows tests");
+        it("XMLHttpRequest.spec.7 should be able to load the (WP8 backwards compatability) root page www/index.html", function () {
+            var win = jasmine.createSpy().andCallFake(function (res) { });
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR("www/index.html", true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+        it("XMLHttpRequest.spec.8 should be able to load the (WP7 backwards compatability) root page app/www/index.html", function () {
+            var win = jasmine.createSpy().andCallFake(function (res) { });
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR("app/www/index.html", true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+        it("XMLHttpRequest.spec.11 should be able to load the current page using window.location with extra / [CB-6299]", function () {
+            var path = window.location.protocol + "/" + window.location.toString().substr(window.location.protocol.length);
+            var win = jasmine.createSpy().andCallFake(function (res) { });
+            var lose = createDoNotCallSpy('xhrFail');
+            var xhr = createXHR(path, true, win, lose);
+            waitsForAny(win, lose);
+        });
+
+    });
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/media.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/media.tests.js b/www/autotest/tests/media.tests.js
new file mode 100644
index 0000000..393ca00
--- /dev/null
+++ b/www/autotest/tests/media.tests.js
@@ -0,0 +1,207 @@
+/*
+ *
+ * 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('Media', function () {
+	it("should exist", function() {
+        expect(Media).toBeDefined();
+		expect(typeof Media).toBe("function");
+	});
+
+    it("media.spec.1 should have the following properties", function() {
+        var media1 = new Media("dummy");
+        expect(media1.id).toBeDefined();
+        expect(media1.src).toBeDefined();
+        expect(media1._duration).toBeDefined();
+        expect(media1._position).toBeDefined();
+        media1.release();
+    });
+    
+    it("should define constants for Media status", function() {
+        expect(Media).toBeDefined();
+        expect(Media.MEDIA_NONE).toBe(0);
+        expect(Media.MEDIA_STARTING).toBe(1);
+		expect(Media.MEDIA_RUNNING).toBe(2);
+		expect(Media.MEDIA_PAUSED).toBe(3);
+		expect(Media.MEDIA_STOPPED).toBe(4);
+	});
+
+	it("should define constants for Media errors", function() {
+        expect(MediaError).toBeDefined();
+        expect(MediaError.MEDIA_ERR_NONE_ACTIVE).toBe(0);
+        expect(MediaError.MEDIA_ERR_ABORTED).toBe(1);
+		expect(MediaError.MEDIA_ERR_NETWORK).toBe(2);
+		expect(MediaError.MEDIA_ERR_DECODE).toBe(3);
+		expect(MediaError.MEDIA_ERR_NONE_SUPPORTED).toBe(4);
+	});
+
+    it("media.spec.2 should contain a play function", function() {
+        var media1 = new Media();
+        expect(media1.play).toBeDefined();
+        expect(typeof media1.play).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.3 should contain a stop function", function() {
+        var media1 = new Media();
+        expect(media1.stop).toBeDefined();
+        expect(typeof media1.stop).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.4 should contain a seekTo function", function() {
+        var media1 = new Media();
+        expect(media1.seekTo).toBeDefined();
+        expect(typeof media1.seekTo).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.5 should contain a pause function", function() {
+        var media1 = new Media();
+        expect(media1.pause).toBeDefined();
+        expect(typeof media1.pause).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.6 should contain a getDuration function", function() {
+        var media1 = new Media();
+        expect(media1.getDuration).toBeDefined();
+        expect(typeof media1.getDuration).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.7 should contain a getCurrentPosition function", function() {
+        var media1 = new Media();
+        expect(media1.getCurrentPosition).toBeDefined();
+        expect(typeof media1.getCurrentPosition).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.8 should contain a startRecord function", function() {
+        var media1 = new Media();
+        expect(media1.startRecord).toBeDefined();
+        expect(typeof media1.startRecord).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.9 should contain a stopRecord function", function() {
+        var media1 = new Media();
+        expect(media1.stopRecord).toBeDefined();
+        expect(typeof media1.stopRecord).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.10 should contain a release function", function() {
+        var media1 = new Media();
+        expect(media1.release).toBeDefined();
+        expect(typeof media1.release).toBe('function');
+        media1.release();
+    });
+
+    it("media.spec.11 should contain a setVolume function", function() {
+        var media1 = new Media();
+        expect(media1.setVolume).toBeDefined();
+        expect(typeof media1.setVolume).toBe('function');
+        media1.release();
+    });
+
+	it("should return MediaError for bad filename", function() {
+		var badMedia = null,
+            win = jasmine.createSpy(),
+            fail = jasmine.createSpy().andCallFake(function (result) {
+                expect(result).toBeDefined();
+                expect(result.code).toBe(MediaError.MEDIA_ERR_ABORTED);
+            });
+
+        //bb10 dialog pops up, preventing tests from running
+        if (cordova.platformId === 'blackberry10') {
+            return;
+        }
+            
+        runs(function () {
+            badMedia = new Media("invalid.file.name", win,fail);
+            badMedia.play();
+        });
+
+        waitsFor(function () { return fail.wasCalled; }, Tests.TEST_TIMEOUT);
+
+        runs(function () {
+            expect(win).not.toHaveBeenCalled();
+            badMedia.release();
+        });
+	});
+
+    it("media.spec.12 position should be set properly", function() {
+        var playcomplete = jasmine.createSpy();
+        var fail = jasmine.createSpy();
+        var mediaState=Media.MEDIA_STOPPED;
+        var statuschange= function(statusCode){
+            mediaState=statusCode;
+        };
+        var media1 = new Media("http://cordova.apache.org/downloads/BlueZedEx.mp3",playcomplete,fail,statuschange),
+            test = jasmine.createSpy().andCallFake(function(position) {
+                    console.log("position = " + position);
+                    expect(position).toBeGreaterThan(0.0);
+                    media1.stop()
+                    media1.release();
+                });
+
+        media1.play();
+
+        if (cordova.platformId !== 'blackberry10') {
+            waitsFor(function () { return mediaState==Media.MEDIA_RUNNING; }, 10000);
+        } else {
+            waits(5000);
+        }
+
+        // make sure we are at least one second into the file
+        waits(1000);
+        runs(function () {
+            expect(fail).not.toHaveBeenCalled();
+             // note that the file is about 60 seconds long and we kill the play almost immediately
+             // as a result, the playcomplete should not happen
+            expect(playcomplete).not.toHaveBeenCalled();
+            media1.getCurrentPosition(test, function () {});
+        });
+
+        waitsFor(function () { return test.wasCalled || fail.wasCalled; }, Tests.TEST_TIMEOUT);
+    });
+
+    it("media.spec.13 duration should be set properly", function() {
+
+        if (cordova.platformId === 'blackberry10') {
+            return;
+        }
+
+        var win = jasmine.createSpy();
+        var fail = jasmine.createSpy();
+        var mediaState=Media.MEDIA_STOPPED;
+        var statuschange= function(statusCode){
+            mediaState=statusCode;
+        };
+        var media1 = new Media("http://cordova.apache.org/downloads/BlueZedEx.mp3",win,fail,statuschange);
+        media1.play();
+        waitsFor(function () { return mediaState==Media.MEDIA_RUNNING; }, 10000);
+        runs(function () {
+            expect(media1.getDuration()).toBeGreaterThan(0.0);
+            expect(fail).not.toHaveBeenCalled();
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/network.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/network.tests.js b/www/autotest/tests/network.tests.js
new file mode 100644
index 0000000..bf3a940
--- /dev/null
+++ b/www/autotest/tests/network.tests.js
@@ -0,0 +1,56 @@
+/*
+ *
+ * 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('Network (navigator.connection)', function () {
+    it("network.spec.1 should exist", function() {
+        expect(navigator.network && navigator.network.connection).toBeDefined();
+        expect(navigator.connection).toBeDefined();
+    });
+
+    it("network.spec.2 should be set to a valid value", function() {
+        var validValues = {
+            'unknown': 1,
+            'ethernet': 1,
+            'wifi': 1,
+            '2g': 1,
+            'cellular': 1,
+            '3g': 1,
+            '4g': 1,
+            'none': 1
+        };
+        expect(validValues[navigator.connection.type]).toBe(1);
+    });
+
+    it("network.spec.3 should have the same value in deprecated and non-deprecated apis", function() {
+        expect(navigator.network.connection.type).toBe(navigator.connection.type);
+    });
+
+    it("network.spec.4 should define constants for connection status", function() {
+        expect(Connection.UNKNOWN).toBe("unknown");
+        expect(Connection.ETHERNET).toBe("ethernet");
+        expect(Connection.WIFI).toBe("wifi");
+        expect(Connection.CELL_2G).toBe("2g");
+        expect(Connection.CELL_3G).toBe("3g");
+        expect(Connection.CELL_4G).toBe("4g");
+        expect(Connection.NONE).toBe("none");
+        expect(Connection.CELL).toBe("cellular");
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/notification.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/notification.tests.js b/www/autotest/tests/notification.tests.js
new file mode 100644
index 0000000..016bcfb
--- /dev/null
+++ b/www/autotest/tests/notification.tests.js
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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('Notification (navigator.notification)', function () {
+	it("should exist", function() {
+                expect(navigator.notification).toBeDefined();
+	});
+
+	it("should contain a beep function", function() {
+		expect(typeof navigator.notification.beep).toBeDefined();
+		expect(typeof navigator.notification.beep).toBe("function");
+	});
+
+	it("should contain an alert function", function() {
+		expect(typeof navigator.notification.alert).toBeDefined();
+		expect(typeof navigator.notification.alert).toBe("function");
+	});
+
+	it("should contain a confirm function", function() {
+		expect(typeof navigator.notification.confirm).toBeDefined();
+		expect(typeof navigator.notification.confirm).toBe("function");
+	});
+	
+	it("should contain a prompt function", function() {
+		expect(typeof navigator.notification.prompt).toBeDefined();
+		expect(typeof navigator.notification.prompt).toBe("function");
+	});
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/platform.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/platform.tests.js b/www/autotest/tests/platform.tests.js
new file mode 100644
index 0000000..4a1c1a4
--- /dev/null
+++ b/www/autotest/tests/platform.tests.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.
+ *
+*/
+
+describe('Platform (cordova)', function () {
+    it("platform.spec.1 should exist", function() {
+        expect(cordova).toBeDefined();
+    });
+
+    it("platform.spec.2 exec method should exist", function() {
+        expect(cordova.exec).toBeDefined();
+        expect(typeof cordova.exec).toBe('function');
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/splashscreen.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/splashscreen.tests.js b/www/autotest/tests/splashscreen.tests.js
new file mode 100644
index 0000000..a57cb9f
--- /dev/null
+++ b/www/autotest/tests/splashscreen.tests.js
@@ -0,0 +1,36 @@
+/*
+ *
+ * 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('Splashscreen (cordova)', function () {
+    it("splashscreen.spec.1 should exist", function() {
+        expect(navigator.splashscreen).toBeDefined();
+    });
+
+    it("splashscreen.spec.2 exec method should exist", function() {
+        expect(navigator.splashscreen.show).toBeDefined();
+        expect(typeof navigator.splashscreen.show).toBe('function');
+    });
+    
+    it("splashscreen.spec.3 exec method should exist", function() {
+        expect(navigator.splashscreen.hide).toBeDefined();
+        expect(typeof navigator.splashscreen.hide).toBe('function');
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/storage.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/storage.tests.js b/www/autotest/tests/storage.tests.js
new file mode 100644
index 0000000..4f4bd5b
--- /dev/null
+++ b/www/autotest/tests/storage.tests.js
@@ -0,0 +1,201 @@
+/*
+ *
+ * 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("Session Storage", function () {
+    it("storage.spec.1 should exist", function () {
+        expect(window.sessionStorage).toBeDefined();
+        expect(typeof window.sessionStorage.length).not.toBe('undefined');
+        expect(typeof(window.sessionStorage.key)).toBe('function');
+        expect(typeof(window.sessionStorage.getItem)).toBe('function');
+        expect(typeof(window.sessionStorage.setItem)).toBe('function');
+        expect(typeof(window.sessionStorage.removeItem)).toBe('function');
+        expect(typeof(window.sessionStorage.clear)).toBe('function');
+    });
+
+    it("storage.spec.2 check length", function () {
+        expect(window.sessionStorage.length).toBe(0);
+        window.sessionStorage.setItem("key","value");
+        expect(window.sessionStorage.length).toBe(1);
+        window.sessionStorage.removeItem("key");   
+        expect(window.sessionStorage.length).toBe(0);
+    });
+
+    it("storage.spec.3 check key", function () {
+        expect(window.sessionStorage.key(0)).toBe(null);
+        window.sessionStorage.setItem("test","value");
+        expect(window.sessionStorage.key(0)).toBe("test");
+        window.sessionStorage.removeItem("test");   
+        expect(window.sessionStorage.key(0)).toBe(null);
+    });
+
+    it("storage.spec.4 check getItem", function() {
+        expect(window.sessionStorage.getItem("item")).toBe(null);
+        window.sessionStorage.setItem("item","value");
+        expect(window.sessionStorage.getItem("item")).toBe("value");
+        window.sessionStorage.removeItem("item");   
+        expect(window.sessionStorage.getItem("item")).toBe(null);
+    });
+
+    it("storage.spec.5 check setItem", function() {
+        expect(window.sessionStorage.getItem("item")).toBe(null);
+        window.sessionStorage.setItem("item","value");
+        expect(window.sessionStorage.getItem("item")).toBe("value");
+        window.sessionStorage.setItem("item","newval");
+        expect(window.sessionStorage.getItem("item")).toBe("newval");
+        window.sessionStorage.removeItem("item");   
+        expect(window.sessionStorage.getItem("item")).toBe(null);
+    });
+
+    it("storage.spec.6 can remove an item", function () {
+        expect(window.sessionStorage.getItem("item")).toBe(null);
+        window.sessionStorage.setItem("item","value");
+        expect(window.sessionStorage.getItem("item")).toBe("value");
+        window.sessionStorage.removeItem("item");   
+        expect(window.sessionStorage.getItem("item")).toBe(null);
+    });
+
+    it("storage.spec.7 check clear", function() {
+        window.sessionStorage.setItem("item1","value");
+        window.sessionStorage.setItem("item2","value");
+        window.sessionStorage.setItem("item3","value");
+        expect(window.sessionStorage.length).toBe(3);
+        window.sessionStorage.clear();
+        expect(window.sessionStorage.length).toBe(0);
+    });
+
+    it("storage.spec.8 check dot notation", function() {
+        expect(window.sessionStorage.item).not.toBeDefined();
+        window.sessionStorage.item = "value";
+        expect(window.sessionStorage.item).toBe("value");
+        window.sessionStorage.removeItem("item");   
+        expect(window.sessionStorage.item).not.toBeDefined();
+    });
+
+    describe("Local Storage", function () {
+        it("storage.spec.9 should exist", function() {
+            expect(window.localStorage).toBeDefined();
+            expect(window.localStorage.length).toBeDefined();
+            expect(typeof window.localStorage.key).toBe("function");
+            expect(typeof window.localStorage.getItem).toBe("function");
+            expect(typeof window.localStorage.setItem).toBe("function");
+            expect(typeof window.localStorage.removeItem).toBe("function");
+            expect(typeof window.localStorage.clear).toBe("function");
+        });  
+
+        it("storage.spec.10 check length", function() {
+            expect(window.localStorage.length).toBe(0);
+            window.localStorage.setItem("key","value");
+            expect(window.localStorage.length).toBe(1);
+            window.localStorage.removeItem("key");   
+            expect(window.localStorage.length).toBe(0);
+        });
+
+        it("storage.spec.11 check key", function() {
+            expect(window.localStorage.key(0)).toBe(null);
+            window.localStorage.setItem("test","value");
+            expect(window.localStorage.key(0)).toBe("test");
+            window.localStorage.removeItem("test");   
+            expect(window.localStorage.key(0)).toBe(null);
+        });
+
+        it("storage.spec.4 check getItem", function() {
+            expect(window.localStorage.getItem("item")).toBe(null);
+            window.localStorage.setItem("item","value");
+            expect(window.localStorage.getItem("item")).toBe("value");
+            window.localStorage.removeItem("item");   
+            expect(window.localStorage.getItem("item")).toBe(null);
+        });
+
+        it("storage.spec.5 check setItem", function() {
+            expect(window.localStorage.getItem("item")).toBe(null);
+            window.localStorage.setItem("item","value");
+            expect(window.localStorage.getItem("item")).toBe("value");
+            window.localStorage.setItem("item","newval");
+            expect(window.localStorage.getItem("item")).toBe("newval");
+            window.localStorage.removeItem("item");   
+            expect(window.localStorage.getItem("item")).toBe(null);
+        });
+
+        it("storage.spec.14 check removeItem", function() {
+            expect(window.localStorage.getItem("item")).toBe(null);
+            window.localStorage.setItem("item","value");
+            expect(window.localStorage.getItem("item")).toBe("value");
+            window.localStorage.removeItem("item");   
+            expect(window.localStorage.getItem("item")).toBe(null);
+        });
+
+        it("storage.spec.7 check clear", function() {
+            expect(window.localStorage.getItem("item1")).toBe(null);
+            expect(window.localStorage.getItem("item2")).toBe(null);
+            expect(window.localStorage.getItem("item3")).toBe(null);
+            window.localStorage.setItem("item1","value");
+            window.localStorage.setItem("item2","value");
+            window.localStorage.setItem("item3","value");
+            expect(window.localStorage.getItem("item1")).toBe("value");
+            expect(window.localStorage.getItem("item2")).toBe("value");
+            expect(window.localStorage.getItem("item3")).toBe("value");
+            expect(window.localStorage.length).toBe(3);
+            window.localStorage.clear();
+            expect(window.localStorage.length).toBe(0);
+            expect(window.localStorage.getItem("item1")).toBe(null);
+            expect(window.localStorage.getItem("item2")).toBe(null);
+            expect(window.localStorage.getItem("item3")).toBe(null);
+        });
+
+        it("storage.spec.8 check dot notation", function() {
+            expect(window.localStorage.item).not.toBeDefined();
+            window.localStorage.item = "value";
+            expect(window.localStorage.item).toBe("value");
+            window.localStorage.removeItem("item");   
+            expect(window.localStorage.item).not.toBeDefined();
+        });
+    });
+
+    describe("HTML 5 Storage", function () {
+        it("storage.spec.9 should exist", function() {
+            expect(window.openDatabase);
+            
+        });
+        
+        it("storage.spec.17 should contain an openDatabase function", function() {
+            expect(window.openDatabase).toBeDefined();
+            expect(typeof window.openDatabase == 'function').toBe(true);
+        });
+
+        it("storage.spec.18 Should be able to create and drop tables", function() {
+            var win = jasmine.createSpy('win');
+            var fail1 = createDoNotCallSpy('fail1');
+            var fail2 = createDoNotCallSpy('fail2');
+            var db = openDatabase("Database", "1.0", "HTML5 Database API example", 5*1024*1024);
+            db.transaction(function(t) {
+                t.executeSql('CREATE TABLE IF NOT EXISTS foo(id int, name varchar(255));');
+                t.executeSql('CREATE TABLE IF NOT EXISTS foo2(id int, name varchar(255));');
+            }, fail1, step2);
+            function step2() {
+              db.transaction(function(t) {
+                  t.executeSql('DROP TABLE foo;');
+                  t.executeSql('DROP TABLE foo2');
+              }, fail2, win);
+            }
+            waitsForAny(win, fail1, fail2);
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/vibration.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/vibration.tests.js b/www/autotest/tests/vibration.tests.js
new file mode 100644
index 0000000..18e75f2
--- /dev/null
+++ b/www/autotest/tests/vibration.tests.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.
+ *
+*/
+
+describe('Vibration (navigator.notification.vibrate)', function () {
+	it("navigator.notification should exist", function() {
+                expect(navigator.notification).toBeDefined();
+	});
+
+	it("should contain a vibrate function", function() {
+		expect(typeof navigator.notification.vibrate).toBeDefined();
+		expect(typeof navigator.notification.vibrate).toBe("function");
+	});
+});

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/www/autotest/tests/whitelist.tests.js
----------------------------------------------------------------------
diff --git a/www/autotest/tests/whitelist.tests.js b/www/autotest/tests/whitelist.tests.js
new file mode 100644
index 0000000..fde24cc
--- /dev/null
+++ b/www/autotest/tests/whitelist.tests.js
@@ -0,0 +1,168 @@
+/*
+ *
+ * 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('Whitelist API (cordova.whitelist)', function () {
+	it("should exist", function() {
+        expect(cordova.whitelist).toBeDefined();
+	});
+
+    describe("Match function", function() {
+        function expectMatchWithResult(result) {
+            return (function(url, patterns, description) {
+                description = description || ((result ? "should accept " : "should reject ") + url + " for " + JSON.stringify(patterns));
+                it(description, function() {
+                    var cb = jasmine.createSpy();
+                    runs(function() {
+                        cordova.whitelist.match(url, patterns, cb);
+                    });
+                    waitsFor(function() { return cb.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+                    runs(function() {
+                        expect(cb).toHaveBeenCalledWith(result);
+                    });
+                });
+            });
+        }
+
+        var itShouldMatch = expectMatchWithResult(true);
+        var itShouldNotMatch = expectMatchWithResult(false);
+
+        it("should exist", function() {
+            expect(cordova.whitelist.match).toBeDefined();
+            expect(typeof cordova.whitelist.match).toBe("function");
+        });
+
+        itShouldMatch('http://www.apache.org/',['*'], "should accept any domain for *");
+        itShouldNotMatch('http://www.apache.org/',[], "should not accept any domain for []");
+
+        itShouldMatch('http://apache.org/', ['http://*.apache.org']);
+        itShouldMatch('http://www.apache.org/', ['http://*.apache.org']);
+        itShouldMatch('http://www.apache.org/some/path', ['http://*.apache.org']);
+        itShouldMatch('http://some.domain.under.apache.org/', ['http://*.apache.org']);
+        itShouldMatch('http://user:pass@apache.org/', ['http://*.apache.org']);
+        itShouldMatch('http://user:pass@www.apache.org/', ['http://*.apache.org']);
+        itShouldMatch('http://www.apache.org/?some=params', ['http://*.apache.org']);
+        itShouldNotMatch('http://apache.com/', ['http://*.apache.org']);
+        itShouldNotMatch('http://www.evil.com/?url=www.apache.org', ['http://*.apache.org']);
+        itShouldNotMatch('http://www.evil.com/?url=http://www.apache.org', ['http://*.apache.org']);
+        itShouldNotMatch('http://www.evil.com/?url=http%3A%2F%2Fwww%2Eapache%2Eorg', ['http://*.apache.org']);
+        itShouldNotMatch('https://apache.org/', ['http://*.apache.org']);
+        itShouldNotMatch('http://www.apache.org:pass@evil.com/', ['http://*.apache.org']);
+        itShouldNotMatch('http://www.apache.org.evil.com/', ['http://*.apache.org']);
+
+        itShouldMatch('http://www.apache.org/',['http://*.apache.org','https://*.apache.org']);
+        itShouldMatch('https://www.apache.org/',['http://*.apache.org','https://*.apache.org']);
+        itShouldNotMatch('ftp://www.apache.org/',['http://*.apache.org','https://*.apache.org']);
+        itShouldNotMatch('http://www.apache.com/',['http://*.apache.org','https://*.apache.org']);
+
+        itShouldMatch('http://www.apache.org/',['http://www.apache.org']);
+        itShouldNotMatch('http://build.apache.org/',['http://www.apache.org']);
+        itShouldNotMatch('http://apache.org/',['http://www.apache.org']);
+
+        itShouldMatch('http://www.apache.org/', ['http://*/*']);
+        itShouldMatch('http://www.apache.org/foo/bar.html', ['http://*/*']);
+
+        itShouldMatch('http://www.apache.org/foo', ['http://*/foo*']);
+        itShouldMatch('http://www.apache.org/foo/bar.html', ['http://*/foo*']);
+        itShouldNotMatch('http://www.apache.org/', ['http://*/foo*']);
+
+        itShouldMatch('file:///foo', ['file:///*']);
+
+        itShouldMatch('file:///foo', ['file:///foo*']);
+        itShouldMatch('file:///foo/bar.html', ['file:///foo*']);
+        itShouldNotMatch('file:///etc/foo', ['file:///foo*']);
+        itShouldNotMatch('http://www.apache.org/foo', ['file:///foo*']);
+
+        itShouldMatch('http://www.apache.org/', ['*://www.apache.org/*']);
+        itShouldMatch('https://www.apache.org/', ['*://www.apache.org/*']);
+        itShouldMatch('ftp://www.apache.org/', ['*://www.apache.org/*']);
+        itShouldMatch('file://www.apache.org/', ['*://www.apache.org/*']);
+        itShouldMatch('content://www.apache.org/', ['*://www.apache.org/*']);
+        itShouldMatch('foo://www.apache.org/', ['*://www.apache.org/*']);
+        itShouldNotMatch('http://www.apache.com/', ['*://www.apache.org/*']);
+
+        itShouldMatch('http://www.apache.org/', ['*.apache.org']);
+        itShouldMatch('https://www.apache.org/', ['*.apache.org']);
+        itShouldNotMatch('ftp://www.apache.org/', ['*.apache.org']);
+
+        itShouldMatch('http://www.apache.org:81/', ['http://www.apache.org:81/*']);
+        itShouldMatch('http://user:pass@www.apache.org:81/foo/bar.html', ['http://www.apache.org:81/*']);
+        itShouldNotMatch('http://www.apache.org:80/', ['http://www.apache.org:81/*']);
+        itShouldNotMatch('http://www.apache.org/', ['http://www.apache.org:81/*']);
+        itShouldNotMatch('http://www.apache.org:foo/', ['http://www.apache.org:81/*']);
+        itShouldNotMatch('http://www.apache.org:81@www.apache.org/', ['http://www.apache.org:81/*']);
+        itShouldNotMatch('http://www.apache.org:81@www.evil.com/', ['http://www.apache.org:81/*']);
+
+        itShouldMatch('http://www.APAche.org/', ['*.apache.org']);
+        itShouldMatch('http://WWw.apache.org/', ['*.apache.org']);
+        itShouldMatch('http://www.apache.org/', ['*.APACHE.ORG']);
+        itShouldMatch('HTTP://www.apache.org/', ['*.apache.org']);
+        itShouldMatch('HTTP://www.apache.org/', ['http://*.apache.org']);
+        itShouldMatch('http://www.apache.org/', ['HTTP://*.apache.org']);
+
+        itShouldMatch('http://www.apache.org/foo/', ['*://*.apache.org/foo/*']);
+        itShouldMatch('http://www.apache.org/foo/bar', ['*://*.apache.org/foo/*']);
+        itShouldNotMatch('http://www.apache.org/bar/foo/', ['*://*.apache.org/foo/*']);
+        itShouldNotMatch('http://www.apache.org/Foo/', ['*://*.apache.org/foo/*']);
+        itShouldNotMatch('http://www.apache.org/Foo/bar', ['*://*.apache.org/foo/*']);
+
+    });
+
+    describe("Test function", function() {
+        function expectTestWithResult(result) {
+            return (function(url, description) {
+                description = description || ((result ? "should accept " : "should reject ") + url);
+                it(description, function() {
+                    var cb = jasmine.createSpy();
+                    runs(function() {
+                        cordova.whitelist.test(url, cb);
+                    });
+                    waitsFor(function() { return cb.wasCalled; }, "success callback never called", Tests.TEST_TIMEOUT);
+                    runs(function() {
+                        expect(cb).toHaveBeenCalledWith(result);
+                    });
+                });
+            });
+        }
+
+        var itShouldAccept = expectTestWithResult(true);
+        var itShouldReject = expectTestWithResult(false);
+
+        it("should exist", function() {
+            expect(cordova.whitelist.test).toBeDefined();
+            expect(typeof cordova.whitelist.test).toBe("function");
+        });
+
+        itShouldAccept('http://apache.org');
+        itShouldAccept('http://apache.org/');
+        itShouldAccept('http://www.apache.org/');
+        itShouldAccept('http://www.apache.org/some/path');
+        itShouldAccept('http://some.domain.under.apache.org/');
+        itShouldAccept('http://user:pass@apache.org/');
+        itShouldAccept('http://user:pass@www.apache.org/');
+        itShouldAccept('https://www.apache.org/');
+        itShouldReject('ftp://www.apache.org/');
+        itShouldReject('http://www.apache.com/');
+        itShouldReject('http://www.apache.org:pass@evil.com/');
+        itShouldReject('http://www.apache.org.evil.com/');
+        itShouldAccept('file:///foo');
+        itShouldAccept('content:///foo');
+    });
+});


[19/19] spec commit: Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
Move mobilespec into www/ so as to not include non-app files in the app


Project: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/commit/77ff9a37
Tree: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/tree/77ff9a37
Diff: http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/diff/77ff9a37

Branch: refs/heads/master
Commit: 77ff9a37d215ed1265be251ddf83b8789eef06f3
Parents: e2ddbd3
Author: Andrew Grieve <ag...@chromium.org>
Authored: Mon Jul 7 14:07:20 2014 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Mon Jul 7 14:07:20 2014 -0400

----------------------------------------------------------------------
 accelerometer/index.html                      |   51 -
 accelerometer/index.js                        |  111 -
 audio/index.html                              |   88 -
 audio/index.js                                |  356 --
 autotest/html/HtmlReporter.js                 |  101 -
 autotest/html/HtmlReporterHelpers.js          |   60 -
 autotest/html/ReporterView.js                 |  164 -
 autotest/html/SpecView.js                     |   79 -
 autotest/html/SuiteView.js                    |   22 -
 autotest/html/TrivialReporter.js              |  192 -
 autotest/index.html                           |   63 -
 autotest/index.js                             |    4 -
 autotest/jasmine.css                          |   81 -
 autotest/jasmine.js                           | 2530 -----------
 autotest/pages/accelerometer.html             |   54 -
 autotest/pages/all.html                       |   73 -
 autotest/pages/all.js                         |   46 -
 autotest/pages/battery.html                   |   51 -
 autotest/pages/bridge.html                    |   55 -
 autotest/pages/camera.html                    |   55 -
 autotest/pages/capture.html                   |   55 -
 autotest/pages/compass.html                   |   55 -
 autotest/pages/contacts.html                  |   56 -
 autotest/pages/datauri.html                   |   53 -
 autotest/pages/device.html                    |   55 -
 autotest/pages/file.html                      |   53 -
 autotest/pages/file.js                        |   39 -
 autotest/pages/filetransfer.html              |   54 -
 autotest/pages/geolocation.html               |   55 -
 autotest/pages/globalization.html             |   54 -
 autotest/pages/localXHR.html                  |   54 -
 autotest/pages/media.html                     |   55 -
 autotest/pages/network.html                   |   55 -
 autotest/pages/notification.html              |   55 -
 autotest/pages/platform.html                  |   55 -
 autotest/pages/run-tests.js                   |   18 -
 autotest/pages/splashscreen.html              |   55 -
 autotest/pages/storage.html                   |   55 -
 autotest/pages/vibration.html                 |   55 -
 autotest/pages/whitelist.html                 |   55 -
 autotest/test-runner.js                       |   66 -
 autotest/tests/accelerometer.tests.js         |  222 -
 autotest/tests/battery.tests.js               |  187 -
 autotest/tests/bridge.tests.js                |   37 -
 autotest/tests/camera.tests.js                |   70 -
 autotest/tests/capture.tests.js               |  112 -
 autotest/tests/compass.tests.js               |  136 -
 autotest/tests/contacts.tests.js              |  542 ---
 autotest/tests/datauri.tests.js               |   60 -
 autotest/tests/device.tests.js                |   64 -
 autotest/tests/file.tests.js                  | 4451 --------------------
 autotest/tests/filetransfer.tests.js          |  945 -----
 autotest/tests/geolocation.tests.js           |  160 -
 autotest/tests/globalization.tests.js         |  869 ----
 autotest/tests/localXHR.tests.js              |  189 -
 autotest/tests/media.tests.js                 |  207 -
 autotest/tests/network.tests.js               |   56 -
 autotest/tests/notification.tests.js          |   46 -
 autotest/tests/platform.tests.js              |   31 -
 autotest/tests/splashscreen.tests.js          |   36 -
 autotest/tests/storage.tests.js               |  201 -
 autotest/tests/vibration.tests.js             |   31 -
 autotest/tests/whitelist.tests.js             |  168 -
 battery/index.html                            |   53 -
 battery/index.js                              |   72 -
 beep.wav                                      |  Bin 8114 -> 0 bytes
 benchmarks/arraybuffer.html                   |  132 -
 benchmarks/autobench.html                     |  194 -
 benchmarks/exec.html                          |  239 --
 benchmarks/index.html                         |   39 -
 benchmarks/setImmediate.js                    |  239 --
 benchmarks/uubench.js                         |  115 -
 camera/index.html                             |   60 -
 camera/index.js                               |  344 --
 capture/index.html                            |   52 -
 capture/index.js                              |  137 -
 compass/index.html                            |   48 -
 compass/index.js                              |  104 -
 contacts/index.html                           |   47 -
 contacts/index.js                             |   90 -
 cordova-incl.js                               |   88 -
 createmobilespec/createmobilespec.js          |   19 +-
 events/index.html                             |   60 -
 events/index.js                               |   94 -
 file/index.html                               |   72 -
 file/index.js                                 |  153 -
 inappbrowser/index.html                       |  236 --
 inappbrowser/index.js                         |  242 --
 inappbrowser/inject.css                       |   21 -
 inappbrowser/inject.html                      |   43 -
 inappbrowser/inject.js                        |   20 -
 inappbrowser/local.html                       |   64 -
 inappbrowser/local.pdf                        |  Bin 8568 -> 0 bytes
 inappbrowser/video.html                       |   42 -
 index.html                                    |   69 -
 keyboard/index.html                           |  175 -
 keyboard/index.js                             |   69 -
 keyboard/window-onerror.js                    |    1 -
 lazyloadjs/do-not-write-cordova-script.js     |    1 -
 lazyloadjs/index.html                         |   41 -
 lazyloadjs/index.js                           |   16 -
 location/index.html                           |   98 -
 location/index.js                             |  128 -
 main.js                                       |  165 -
 master.css                                    |  182 -
 misc/index.html                               |   60 -
 misc/index.js                                 |   30 -
 misc/page2.html                               |   64 -
 misc/page2.js                                 |   12 -
 misc/page3.html                               |   84 -
 misc/page3A.js                                |   27 -
 network/index.html                            |   48 -
 network/index.js                              |   38 -
 notification/index.html                       |   51 -
 notification/index.js                         |  100 -
 splashscreen/index.html                       |   48 -
 sql/index.html                                |   50 -
 sql/index.js                                  |  125 -
 storage/index.html                            |   41 -
 storage/index.js                              |   27 -
 vibration/index.html                          |   43 -
 vibration/index.js                            |   31 -
 www/accelerometer/index.html                  |   51 +
 www/accelerometer/index.js                    |  111 +
 www/audio/index.html                          |   88 +
 www/audio/index.js                            |  356 ++
 www/autotest/html/HtmlReporter.js             |  101 +
 www/autotest/html/HtmlReporterHelpers.js      |   60 +
 www/autotest/html/ReporterView.js             |  164 +
 www/autotest/html/SpecView.js                 |   79 +
 www/autotest/html/SuiteView.js                |   22 +
 www/autotest/html/TrivialReporter.js          |  192 +
 www/autotest/index.html                       |   63 +
 www/autotest/index.js                         |    4 +
 www/autotest/jasmine.css                      |   81 +
 www/autotest/jasmine.js                       | 2530 +++++++++++
 www/autotest/pages/accelerometer.html         |   54 +
 www/autotest/pages/all.html                   |   73 +
 www/autotest/pages/all.js                     |   46 +
 www/autotest/pages/battery.html               |   51 +
 www/autotest/pages/bridge.html                |   55 +
 www/autotest/pages/camera.html                |   55 +
 www/autotest/pages/capture.html               |   55 +
 www/autotest/pages/compass.html               |   55 +
 www/autotest/pages/contacts.html              |   56 +
 www/autotest/pages/datauri.html               |   53 +
 www/autotest/pages/device.html                |   55 +
 www/autotest/pages/file.html                  |   53 +
 www/autotest/pages/file.js                    |   39 +
 www/autotest/pages/filetransfer.html          |   54 +
 www/autotest/pages/geolocation.html           |   55 +
 www/autotest/pages/globalization.html         |   54 +
 www/autotest/pages/localXHR.html              |   54 +
 www/autotest/pages/media.html                 |   55 +
 www/autotest/pages/network.html               |   55 +
 www/autotest/pages/notification.html          |   55 +
 www/autotest/pages/platform.html              |   55 +
 www/autotest/pages/run-tests.js               |   18 +
 www/autotest/pages/splashscreen.html          |   55 +
 www/autotest/pages/storage.html               |   55 +
 www/autotest/pages/vibration.html             |   55 +
 www/autotest/pages/whitelist.html             |   55 +
 www/autotest/test-runner.js                   |   66 +
 www/autotest/tests/accelerometer.tests.js     |  222 +
 www/autotest/tests/battery.tests.js           |  187 +
 www/autotest/tests/bridge.tests.js            |   37 +
 www/autotest/tests/camera.tests.js            |   70 +
 www/autotest/tests/capture.tests.js           |  112 +
 www/autotest/tests/compass.tests.js           |  136 +
 www/autotest/tests/contacts.tests.js          |  542 +++
 www/autotest/tests/datauri.tests.js           |   60 +
 www/autotest/tests/device.tests.js            |   64 +
 www/autotest/tests/file.tests.js              | 4451 ++++++++++++++++++++
 www/autotest/tests/filetransfer.tests.js      |  945 +++++
 www/autotest/tests/geolocation.tests.js       |  160 +
 www/autotest/tests/globalization.tests.js     |  869 ++++
 www/autotest/tests/localXHR.tests.js          |  189 +
 www/autotest/tests/media.tests.js             |  207 +
 www/autotest/tests/network.tests.js           |   56 +
 www/autotest/tests/notification.tests.js      |   46 +
 www/autotest/tests/platform.tests.js          |   31 +
 www/autotest/tests/splashscreen.tests.js      |   36 +
 www/autotest/tests/storage.tests.js           |  201 +
 www/autotest/tests/vibration.tests.js         |   31 +
 www/autotest/tests/whitelist.tests.js         |  168 +
 www/battery/index.html                        |   53 +
 www/battery/index.js                          |   72 +
 www/beep.wav                                  |  Bin 0 -> 8114 bytes
 www/benchmarks/arraybuffer.html               |  132 +
 www/benchmarks/autobench.html                 |  194 +
 www/benchmarks/exec.html                      |  239 ++
 www/benchmarks/index.html                     |   39 +
 www/benchmarks/setImmediate.js                |  239 ++
 www/benchmarks/uubench.js                     |  115 +
 www/camera/index.html                         |   60 +
 www/camera/index.js                           |  344 ++
 www/capture/index.html                        |   52 +
 www/capture/index.js                          |  137 +
 www/compass/index.html                        |   48 +
 www/compass/index.js                          |  104 +
 www/contacts/index.html                       |   47 +
 www/contacts/index.js                         |   90 +
 www/cordova-incl.js                           |   88 +
 www/events/index.html                         |   60 +
 www/events/index.js                           |   94 +
 www/file/index.html                           |   72 +
 www/file/index.js                             |  153 +
 www/inappbrowser/index.html                   |  236 ++
 www/inappbrowser/index.js                     |  242 ++
 www/inappbrowser/inject.css                   |   21 +
 www/inappbrowser/inject.html                  |   43 +
 www/inappbrowser/inject.js                    |   20 +
 www/inappbrowser/local.html                   |   64 +
 www/inappbrowser/local.pdf                    |  Bin 0 -> 8568 bytes
 www/inappbrowser/video.html                   |   42 +
 www/index.html                                |   69 +
 www/keyboard/index.html                       |  175 +
 www/keyboard/index.js                         |   69 +
 www/keyboard/window-onerror.js                |    1 +
 www/lazyloadjs/do-not-write-cordova-script.js |    1 +
 www/lazyloadjs/index.html                     |   41 +
 www/lazyloadjs/index.js                       |   16 +
 www/location/index.html                       |   98 +
 www/location/index.js                         |  128 +
 www/main.js                                   |  165 +
 www/master.css                                |  182 +
 www/misc/index.html                           |   60 +
 www/misc/index.js                             |   30 +
 www/misc/page2.html                           |   64 +
 www/misc/page2.js                             |   12 +
 www/misc/page3.html                           |   84 +
 www/misc/page3A.js                            |   27 +
 www/network/index.html                        |   48 +
 www/network/index.js                          |   38 +
 www/notification/index.html                   |   51 +
 www/notification/index.js                     |  100 +
 www/splashscreen/index.html                   |   48 +
 www/sql/index.html                            |   50 +
 www/sql/index.js                              |  125 +
 www/storage/index.html                        |   41 +
 www/storage/index.js                          |   27 +
 www/vibration/index.html                      |   43 +
 www/vibration/index.js                        |   31 +
 243 files changed, 19101 insertions(+), 19092 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/accelerometer/index.html
----------------------------------------------------------------------
diff --git a/accelerometer/index.html b/accelerometer/index.html
deleted file mode 100644
index 71000b8..0000000
--- a/accelerometer/index.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Acceleration</h1>
-    <div id="info">
-        <div id="accel_status">Stopped</div>
-        <div ><table width="100%">
-            <tr><td width="20%">X:</td><td id="x"> </td></tr>
-            <tr><td width="20%">Y:</td><td id="y"> </td></tr>
-            <tr><td width="20%">Z:</td><td id="z"> </td></tr>
-        </table></div>
-    </div>
-
-    <h2>Action</h2>
-    <div class="btn large getAccel">Get Acceleration</div>
-    <div class="btn large watchAccel">Start Watch</div>
-    <div class="btn large stopAccel">Clear Watch</div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/accelerometer/index.js
----------------------------------------------------------------------
diff --git a/accelerometer/index.js b/accelerometer/index.js
deleted file mode 100644
index 946cfe2..0000000
--- a/accelerometer/index.js
+++ /dev/null
@@ -1,111 +0,0 @@
-var deviceReady = false;
-
-function roundNumber(num) {
-    var dec = 3;
-    var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
-    return result;
-}
-
-//-------------------------------------------------------------------------
-// Acceleration
-//-------------------------------------------------------------------------
-var watchAccelId = null;
-
-/**
- * Start watching acceleration
- */
-var watchAccel = function() {
-    console.log("watchAccel()");
-
-    // Success callback
-    var success = function(a){
-        document.getElementById('x').innerHTML = roundNumber(a.x);
-        document.getElementById('y').innerHTML = roundNumber(a.y);
-        document.getElementById('z').innerHTML = roundNumber(a.z);
-        console.log("watchAccel success callback");
-    };
-
-    // Fail callback
-    var fail = function(e){
-        console.log("watchAccel fail callback with error code "+e);
-        stopAccel();
-        setAccelStatus(Accelerometer.ERROR_MSG[e]);
-    };
-
-    // Update acceleration every 1 sec
-    var opt = {};
-    opt.frequency = 1000;
-    watchAccelId = navigator.accelerometer.watchAcceleration(success, fail, opt);
-
-    setAccelStatus("Running");
-};
-
-/**
- * Stop watching the acceleration
- */
-var stopAccel = function() {
-	console.log("stopAccel()");
-    setAccelStatus("Stopped");
-    if (watchAccelId) {
-        navigator.accelerometer.clearWatch(watchAccelId);
-        watchAccelId = null;
-    }
-};
-
-/**
- * Get current acceleration
- */
-var getAccel = function() {
-    console.log("getAccel()");
-
-    // Stop accel if running
-    stopAccel();
-
-    // Success callback
-    var success = function(a){
-        document.getElementById('x').innerHTML = roundNumber(a.x);
-        document.getElementById('y').innerHTML = roundNumber(a.y);
-        document.getElementById('z').innerHTML = roundNumber(a.z);
-    };
-
-    // Fail callback
-    var fail = function(e){
-        console.log("getAccel fail callback with error code "+e);
-        setAccelStatus(Accelerometer.ERROR_MSG[e]);
-    };
-
-    // Make call
-    var opt = {};
-    navigator.accelerometer.getCurrentAcceleration(success, fail, opt);
-};
-
-/**
- * Set accelerometer status
- */
-var setAccelStatus = function(status) {
-    document.getElementById('accel_status').innerHTML = status;
-};
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    console.log("accelerometer.init()");
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-    	if (!deviceReady) {
-    		alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-    	}
-    },1000);
-}
-
-window.onload = function() {
-  addListenerToClass('getAccel', getAccel);
-  addListenerToClass('watchAccel', watchAccel);
-  addListenerToClass('stopAccel', stopAccel);
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/audio/index.html
----------------------------------------------------------------------
diff --git a/audio/index.html b/audio/index.html
deleted file mode 100644
index a05ea04..0000000
--- a/audio/index.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Audio Tests</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Audio</h1>  
-    <div id="info">
-        <table width="100%">
-        <tr><td><b>Status:</b></td><td id="audio_status"> </td></tr>
-        <tr><td><b>Duration:</b></td><td id="audio_duration"></td></tr>
-        <tr><td><b>Position:</b></td><td id="audio_position"></td></tr>
-        </table>
-    </div>
-    <h2>Action</h2>
-    <table style="width:80%;">
-        <tr>
-            <th colspan=3>Play Sample Audio</th>
-        </tr>
-        <tr>
-            <td><div class="btn wide playAudio">Play</div></td>
-            <td><div class="btn wide pauseAudio">Pause</div></td>
-        </tr>
-        <tr>
-            <td><div class="btn wide stopAudio">Stop</div></td>
-            <td><div class="btn wide releaseAudio">Release</div></td>
-        </tr>
-    </table>
-    
-    <table style="width:80%;">
-        <tr>
-            <td><div class="btn wide seekAudioBy">Seek By</div></td>
-            <td><div class="btn wide seekAudioTo">Seek To</div></td>
-            <td>
-                <div>
-                    <input class="input numeric" type="number" id="seekinput" value="in seconds">
-                </div>
-            </td>
-        </tr>
-    </table>
-    
-    <table style="width:80%;">
-        <tr>
-            <th colspan=3><br><br>Record Audio</th>
-        </tr>
-        <tr>
-            <td colspan=3><div class="btn wide recordAudio">Record Audio for 10 sec</a></td>
-        </tr>
-        <tr>
-            <td><div class="btn wide playRecording">Play</div></td>
-            <td><div class="btn wide pauseAudio">Pause</div></td>
-            <td><div class="btn wide stopAudio">Stop</div></td>
-        </tr>
-    </table>
-    
-    <h2> </h2><div class="backBtn">Back</div>
-    
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/audio/index.js
----------------------------------------------------------------------
diff --git a/audio/index.js b/audio/index.js
deleted file mode 100644
index e7ca9b6..0000000
--- a/audio/index.js
+++ /dev/null
@@ -1,356 +0,0 @@
-var defaultaudio = "http://cordova.apache.org/downloads/BlueZedEx.mp3";
-var deviceReady = false;
-
-//-------------------------------------------------------------------------
-// Audio player
-//-------------------------------------------------------------------------
-var media1 = null;
-var media1Timer = null;
-var audioSrc = null;
-var recordSrc = "myRecording.mp3";
-
-/**
- * Play audio
- */
-function playAudio(url) {
-    console.log("playAudio()");
-    console.log(" -- media="+media1);
-
-  var src = defaultaudio;
-    
-    if (url) {
-        src = url;
-    }
-
-    // Stop playing if src is different from currently playing source
-    if (src != audioSrc) {
-        if (media1 != null) {
-            stopAudio();
-            media1 = null;
-        }
-    }
-
-    if (media1 == null) {
-
-
-        // TEST STREAMING AUDIO PLAYBACK
-        //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.mp3";   // works
-        //var src = "http://nunzioweb.com/misc/Bon_Jovi-Crush_Mystery_Train.m3u"; // doesn't work
-        //var src = "http://www.wav-sounds.com/cartoon/bugsbunny1.wav"; // works
-        //var src = "http://www.angelfire.com/fl5/html-tutorial/a/couldyou.mid"; // doesn't work
-        //var src = "MusicSearch/mp3/train.mp3";    // works
-        //var src = "bryce.mp3";  // works
-        //var src = "/android_asset/www/bryce.mp3"; // works
-
-        media1 = new Media(src,
-            function() {
-                console.log("playAudio():Audio Success");
-            },
-            function(err) {
-                console.log("playAudio():Audio Error: "+err.code);
-                setAudioStatus("Error: " + err.code);
-            },
-            function(status) {
-                console.log("playAudio():Audio Status: "+status);
-                setAudioStatus(Media.MEDIA_MSG[status]);
-
-                // If stopped, then stop getting current position
-                if (Media.MEDIA_STOPPED == status) {
-                    clearInterval(media1Timer);
-                    media1Timer = null;
-                    setAudioPosition("0 sec");
-                }
-            });
-    }
-    audioSrc = src;
-    document.getElementById('audio_duration').innerHTML = "";
-    // Play audio
-    media1.play();
-    if (media1Timer == null && media1.getCurrentPosition) {
-        media1Timer = setInterval(
-            function() {
-                media1.getCurrentPosition(
-                    function(position) {
-                        console.log("Pos="+position);
-                        if (position >= 0.0) {
-                            setAudioPosition(position+" sec");
-                        }
-                    },
-                    function(e) {
-                        console.log("Error getting pos="+e);
-                        setAudioPosition("Error: "+e);
-                    }
-                );
-            },
-            1000
-        );
-    }
-
-    // Get duration
-    var counter = 0;
-    var timerDur = setInterval(
-        function() {
-            counter = counter + 100;
-            if (counter > 2000) {
-                clearInterval(timerDur);
-            }
-            var dur = media1.getDuration();
-            if (dur > 0) {
-                clearInterval(timerDur);
-                document.getElementById('audio_duration').innerHTML = dur + " sec";
-            }
-        }, 100);
-}
-
-/**
- * Pause audio playback
- */
-function pauseAudio() {
-    console.log("pauseAudio()");
-    if (media1) {
-        media1.pause();
-    }
-}
-
-/**
- * Stop audio
- */
-function stopAudio() {
-    console.log("stopAudio()");
-    if (media1) {
-        media1.stop();
-    }
-    clearInterval(media1Timer);
-    media1Timer = null;
-}
-
-/**
- * Release audio
- */
-function releaseAudio() {
-  console.log("releaseAudio()");
-  if (media1) {
-  	media1.stop(); //imlied stop of playback, resets timer
-  	media1.release();
-  }
-}
-
-
-/**
- * Set audio status
- */
-function setAudioStatus(status) {
-    document.getElementById('audio_status').innerHTML = status;
-};
-
-/**
- * Set audio position
- */
-function setAudioPosition(position) {
-    document.getElementById('audio_position').innerHTML = position;
-};
-
-//-------------------------------------------------------------------------
-// Audio recorder
-//-------------------------------------------------------------------------
-var mediaRec = null;
-var recTime = 0;
-
-/**
- * Record audio
- */
-function recordAudio() {
-    console.log("recordAudio()");
-    console.log(" -- media="+mediaRec);
-    if (mediaRec == null) {
-
-        var src = recordSrc;
-        mediaRec = new Media(src,
-                function() {
-                    console.log("recordAudio():Audio Success");
-                },
-                function(err) {
-                    console.log("recordAudio():Audio Error: "+err.code);
-                    setAudioStatus("Error: " + err.code);
-                },
-                function(status) {
-                    console.log("recordAudio():Audio Status: "+status);
-                    setAudioStatus(Media.MEDIA_MSG[status]);
-                }
-            );
-    }
-
-    navigator.notification.beep(1);
-
-    // Record audio
-    mediaRec.startRecord();
-
-    // Stop recording after 10 sec
-    recTime = 0;
-    var recInterval = setInterval(function() {
-        recTime = recTime + 1;
-        setAudioPosition(recTime+" sec");
-        if (recTime >= 10) {
-            clearInterval(recInterval);
-            if (mediaRec.stopAudioRecord){
-                mediaRec.stopAudioRecord();
-            } else {
-                mediaRec.stopRecord();
-            }
-            console.log("recordAudio(): stop");
-            navigator.notification.beep(1);
-        }
-    }, 1000);
-}
-
-/**
- * Play back recorded audio
- */
-function playRecording() {
-    playAudio(recordSrc);
-}
-
-/**
- * Function to create a file for iOS recording
- */
-function getRecordSrc() {
-    var fsFail = function(error) {
-        console.log("error creating file for iOS recording");
-    };
-    var gotFile = function(file) {
-        recordSrc = file.fullPath;
-        //console.log("recording Src: " + recordSrc);
-    };
-    var gotFS = function(fileSystem) {
-        fileSystem.root.getFile("iOSRecording.wav", {create: true}, gotFile, fsFail);
-    };
-    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
-}
-
-/**
- * Function to create a file for BB recording
- */
-function getRecordSrcBB() {
-    var fsFail = function(error) {
-        console.log("error creating file for BB recording");
-    };
-    var gotFile = function(file) {
-        recordSrc = file.fullPath;
-    };
-    var gotFS = function(fileSystem) {
-        fileSystem.root.getFile("BBRecording.amr", {create: true}, gotFile, fsFail);
-    };
-    window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, gotFS, fsFail);
-}
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            if (device.platform.indexOf("iOS") !=-1)
-            {
-                 getRecordSrc();
-            } else if (typeof blackberry !== 'undefined') {
-                getRecordSrcBB();
-            }
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-    	if (!deviceReady) {
-    		alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-    	}
-    },1000);
-}
-
-/**
- * for forced updates of position after a successful seek
- */
-function updatePosition() {
-    media1.getCurrentPosition(
-        function(position) {
-            console.log("Pos="+position);
-            if (position >= 0.0) {
-                setAudioPosition(position+" sec");
-            }
-        },
-        function(e) {
-            console.log("Error getting pos="+e);
-            setAudioPosition("Error: "+e);
-        });
-}
-
-/**
- *
- */
-function seekAudio(mode) {
-    var time = document.getElementById("seekinput").value;
-    if (time == "") {
-        time = 5000;
-    } else {
-        time = time * 1000; //we expect the input to be in seconds
-    }
-    if (media1 == null) {
-        console.log("seekTo requested while media1 is null");
-        if (audioSrc == null) {
-            audioSrc = defaultaudio;
-        }
-        media1 = new Media(audioSrc,
-            function() {
-                console.log("seekToAudio():Audio Success");
-            },
-            function(err) {
-                console.log("seekAudio():Audio Error: "+err.code);
-                setAudioStatus("Error: " + err.code);
-            },
-            function(status) {
-                console.log("seekAudio():Audio Status: "+status);
-                setAudioStatus(Media.MEDIA_MSG[status]);
-
-                // If stopped, then stop getting current position
-                if (Media.MEDIA_STOPPED == status) {
-                    clearInterval(media1Timer);
-                    media1Timer = null;
-                    setAudioPosition("0 sec");
-                }
-            });
-    }
-    
-    media1.getCurrentPosition(
-        function (position) {
-            var deltat = time;
-            if (mode == "by") {
-                deltat = time + position * 1000;   
-            }
-            media1.seekTo(deltat,
-                function () {
-                    console.log("seekAudioTo():Audio Success");
-                    //force an update on the position display
-                    updatePosition();
-                },
-                function (err) {
-                    console.log("seekAudioTo():Audio Error: " + err.code);
-                });
-        },
-        function(e) {
-            console.log("Error getting pos="+e);
-            setAudioPosition("Error: "+e);
-        });
-}
-
-window.onload = function() {
-  addListenerToClass('playAudio', function () {
-    playAudio();
-  });
-  addListenerToClass('pauseAudio', pauseAudio);
-  addListenerToClass('stopAudio', stopAudio);
-  addListenerToClass('releaseAudio', releaseAudio);
-  addListenerToClass('seekAudioBy', seekAudio, 'by');
-  addListenerToClass('seekAudioTo', seekAudio, 'to');
-  addListenerToClass('recordAudio', recordAudio);
-  addListenerToClass('playRecording', playRecording);
-
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/html/HtmlReporter.js
----------------------------------------------------------------------
diff --git a/autotest/html/HtmlReporter.js b/autotest/html/HtmlReporter.js
deleted file mode 100644
index 7d9d924..0000000
--- a/autotest/html/HtmlReporter.js
+++ /dev/null
@@ -1,101 +0,0 @@
-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);

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/html/HtmlReporterHelpers.js
----------------------------------------------------------------------
diff --git a/autotest/html/HtmlReporterHelpers.js b/autotest/html/HtmlReporterHelpers.js
deleted file mode 100644
index 745e1e0..0000000
--- a/autotest/html/HtmlReporterHelpers.js
+++ /dev/null
@@ -1,60 +0,0 @@
-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];
-  }
-};
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/html/ReporterView.js
----------------------------------------------------------------------
diff --git a/autotest/html/ReporterView.js b/autotest/html/ReporterView.js
deleted file mode 100644
index 6a6d005..0000000
--- a/autotest/html/ReporterView.js
+++ /dev/null
@@ -1,164 +0,0 @@
-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);
-
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/html/SpecView.js
----------------------------------------------------------------------
diff --git a/autotest/html/SpecView.js b/autotest/html/SpecView.js
deleted file mode 100644
index e8a3c23..0000000
--- a/autotest/html/SpecView.js
+++ /dev/null
@@ -1,79 +0,0 @@
-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);

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/html/SuiteView.js
----------------------------------------------------------------------
diff --git a/autotest/html/SuiteView.js b/autotest/html/SuiteView.js
deleted file mode 100644
index 19a1efa..0000000
--- a/autotest/html/SuiteView.js
+++ /dev/null
@@ -1,22 +0,0 @@
-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);
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/html/TrivialReporter.js
----------------------------------------------------------------------
diff --git a/autotest/html/TrivialReporter.js b/autotest/html/TrivialReporter.js
deleted file mode 100644
index 167ac50..0000000
--- a/autotest/html/TrivialReporter.js
+++ /dev/null
@@ -1,192 +0,0 @@
-/* @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-mobile-spec/blob/77ff9a37/autotest/index.html
----------------------------------------------------------------------
diff --git a/autotest/index.html b/autotest/index.html
deleted file mode 100644
index 3a41d78..0000000
--- a/autotest/index.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!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 http-equiv="Content-Type" content="text/html;charset=UTF-8" />
-    <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-
-    <title>Cordova API Specs</title>
-
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-    <h1>Cordova API Specs</h1>
-
-    <a href="pages/all.html" class="btn large" style="width:100%;">Run All Tests</a>
-    <a href="pages/accelerometer.html" class="btn large" style="width:100%;">Run Accelerometer Tests</a>
-    <a href="pages/battery.html" class="btn large" style="width:100%;">Run Battery Tests</a>
-    <a href="pages/camera.html" class="btn large" style="width:100%;">Run Camera Tests</a>
-    <a href="pages/capture.html" class="btn large" style="width:100%;">Run Capture Tests</a>
-    <a href="pages/compass.html" class="btn large" style="width:100%;">Run Compass Tests</a>
-    <a href="pages/contacts.html" class="btn large" style="width:100%;">Run Contacts Tests</a>
-    <a href="pages/datauri.html" class="btn large" style="width:100%;">Run Data URI Tests</a>
-    <a href="pages/device.html" class="btn large" style="width:100%;">Run Device Tests</a>
-    <a href="pages/file.html" class="btn large" style="width:100%;">Run File Tests</a>
-    <a href="pages/filetransfer.html" class="btn large" style="width:100%;">Run FileTransfer Tests</a>
-    <a href="pages/geolocation.html" class="btn large" style="width:100%;">Run Geolocation Tests</a>
-    <a href="pages/globalization.html" class="btn large" style="width:100%;">Run Globalization Tests</a>
-    <a href="pages/media.html" class="btn large" style="width:100%;">Run Media Tests</a>
-    <a href="pages/network.html" class="btn large" style="width:100%;">Run Network Tests</a>
-    <a href="pages/notification.html" class="btn large" style="width:100%;">Run Notification Tests</a>
-    <a href="pages/platform.html" class="btn large" style="width:100%;">Run Platform Tests</a>
-    <a href="pages/storage.html" class="btn large" style="width:100%;">Run Storage Tests</a>
-    <a href="pages/bridge.html" class="btn large" style="width:100%;">Run Bridge Tests</a>
-    <a href="pages/splashscreen.html" class="btn large" style="width:100%;">Run Splashscreen Tests</a>
-    <a href="pages/whitelist.html" class="btn large" style="width:100%;">Run Whitelist Tests</a>
-    <a href="pages/localXHR.html" class="btn large" style="width:100%;">Run local XHR Tests</a>
-    <a href="pages/vibration.html" class="btn large" style="width:100%;">Run Vibration Tests</a>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/index.js
----------------------------------------------------------------------
diff --git a/autotest/index.js b/autotest/index.js
deleted file mode 100644
index aec19b4..0000000
--- a/autotest/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-}
-

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/autotest/jasmine.css
----------------------------------------------------------------------
diff --git a/autotest/jasmine.css b/autotest/jasmine.css
deleted file mode 100644
index 826e575..0000000
--- a/autotest/jasmine.css
+++ /dev/null
@@ -1,81 +0,0 @@
-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; }


[11/19] Move mobilespec into www/ so as to not include non-app files in the app

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/file/index.html
----------------------------------------------------------------------
diff --git a/file/index.html b/file/index.html
deleted file mode 100644
index 8f00e86..0000000
--- a/file/index.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-
-    <h1>File and File Transfer</h1>
-    <h2>File</h2>
-    <div class="btn large" id="downloadImgCDV">Download and display img (cdvfile)</div>
-    <div class="btn large" id="downloadImgNative">Download and display img (native)</div>
-    <div class="btn large" id="downloadVideoCDV">Download and play video (cdvfile)</div>
-    <div class="btn large" id="downloadVideoNative">Download and play video (native)</div>
-
-    <div class="ios platform">
-        <h2>iOS Special URL handling</h2>
-        <div class="btn large" id="testPrivateURL">Test /private/ URL (iOS)</div>
-
-        <h2>iOS Extra File Systems</h2>
-        <div class="btn large resolveFs" data-fsname="library">Resolve library FS</div>
-        <div class="btn large resolveFs" data-fsname="library-nosync">Resolve library-nosync FS</div>
-        <div class="btn large resolveFs" data-fsname="documents">Resolve documents FS</div>
-        <div class="btn large resolveFs" data-fsname="documents-nosync">Resolve documents-nosync FS</div>
-        <div class="btn large resolveFs" data-fsname="cache">Resolve cache FS</div>
-        <div class="btn large resolveFs" data-fsname="bundle">Resolve bundle FS</div>
-        <div class="btn large resolveFs" data-fsname="root">Resolve root FS</div>
-    </div>
-
-    <div class="android platform">
-        <h2>Android Extra File Systems</h2>
-        <div class="btn large resolveFs" data-fsname="files">Resolve files FS</div>
-        <div class="btn large resolveFs" data-fsname="files-external">Resolve files-external FS</div>
-        <div class="btn large resolveFs" data-fsname="documents">Resolve documents FS</div>
-        <div class="btn large resolveFs" data-fsname="sdcard">Resolve sdcard FS</div>
-        <div class="btn large resolveFs" data-fsname="cache">Resolve cache FS</div>
-        <div class="btn large resolveFs" data-fsname="cache-external">Resolve cache-external FS</div>
-        <div class="btn large resolveFs" data-fsname="root">Resolve root FS</div>
-    </div>
-
-    <div id="log"></div>
-    <div id="output"></div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/file/index.js
----------------------------------------------------------------------
diff --git a/file/index.js b/file/index.js
deleted file mode 100644
index 1f570dd..0000000
--- a/file/index.js
+++ /dev/null
@@ -1,153 +0,0 @@
-var deviceReady = false;
-
-var imageURL = "http://apache.org/images/feather-small.gif";
-var videoURL = "http://techslides.com/demos/sample-videos/small.mp4";
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-            bindEvents();
-            document.body.classList.add(device.platform.toLowerCase() + "-platform");
-        }, false);
-    window.setTimeout(function() {
-        if (!deviceReady) {
-            alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-        }
-    },1000);
-}
-
-function bindEvents() {
-    document.getElementById('downloadImgCDV').addEventListener('click', downloadImgCDV, false);
-    document.getElementById('downloadImgNative').addEventListener('click', downloadImgNative, false);
-    document.getElementById('downloadVideoCDV').addEventListener('click', downloadVideoCDV, false);
-    document.getElementById('downloadVideoNative').addEventListener('click', downloadVideoNative, false);
-    document.getElementById('testPrivateURL').addEventListener('click', testPrivateURL, false);
-    var fsButtons = document.querySelectorAll('.resolveFs');
-    for (var i=0; i < fsButtons.length; ++i) {
-        fsButtons[i].addEventListener('click', resolveFs, false);
-    }
-}
-
-function clearLog() {
-    var log = document.getElementById("log");
-    log.innerHTML = "";
-}
-
-function logMessage(message, color) {
-    var log = document.getElementById("log");
-    var logLine = document.createElement('div');
-    if (color) {
-        logLine.style.color = color;
-    }
-    logLine.innerHTML = message;
-    log.appendChild(logLine);
-}
-
-function logError(serviceName) {
-    return function(err) {
-        logMessage("ERROR: " + serviceName + " " + JSON.stringify(err), "red");
-    };
-}
-
-function downloadImgCDV(ev) {
-    ev.preventDefault();
-    ev.stopPropagation();
-    downloadImg(imageURL, function(entry) { return entry.toURL(); }, new Image());
-}
-
-function downloadImgNative(ev) {
-    ev.preventDefault();
-    ev.stopPropagation();
-    downloadImg(imageURL, function(entry) { return entry.toNativeURL(); }, new Image);
-}
-
-function downloadVideoCDV(ev) {
-    ev.preventDefault();
-    ev.stopPropagation();
-    var videoElement = document.createElement('video');
-    videoElement.controls = "controls";
-    downloadImg(videoURL, function(entry) { return entry.toURL(); }, videoElement);
-}
-
-function downloadVideoNative(ev) {
-    ev.preventDefault();
-    ev.stopPropagation();
-    var videoElement = document.createElement('video');
-    videoElement.controls = "controls";
-    downloadImg(videoURL, function(entry) { return entry.toNativeURL(); }, videoElement);
-}
-
-function downloadImg(source, urlFn, element) {
-    var filename = source.substring(source.lastIndexOf("/")+1);
-    function download(fileSystem) {
-        var ft = new FileTransfer();
-        logMessage("Starting download");
-        ft.download(source, fileSystem.root.toURL() + filename, function(entry) {
-            logMessage("Download complete")
-            element.src = urlFn(entry)
-            logMessage("Src URL is " + element.src, "green");
-            logMessage("Inserting element");
-            document.getElementById("output").appendChild(element);
-        }, logError("ft.download"));
-    }
-    clearLog();
-    logMessage("Requesting filesystem");
-    requestFileSystem(TEMPORARY, 0, function(fileSystem) {
-        logMessage("Checking for existing file");
-        fileSystem.root.getFile(filename, {create: false}, function(entry) {
-            logMessage("Removing existing file");
-            entry.remove(function() {
-                download(fileSystem);
-            }, logError("entry.remove"));
-        }, function() {
-            download(fileSystem);
-        });
-    }, logError("requestFileSystem"));
-}
-
-function testPrivateURL(ev) {
-    ev.preventDefault();
-    ev.stopPropagation();
-    requestFileSystem(TEMPORARY, 0, function(fileSystem) {
-        logMessage("Temporary root is at " + fileSystem.root.toNativeURL());
-        fileSystem.root.getFile("testfile", {create: true}, function(entry) {
-            logMessage("Temporary file is at " + entry.toNativeURL());
-            if (entry.toNativeURL().substring(0,12) == "file:///var/") {
-                logMessage("File starts with /var/, trying /private/var");
-                var newURL = "file://localhost/private/var/" + entry.toNativeURL().substring(12) + "?and=another_thing";
-                //var newURL = entry.toNativeURL();
-                logMessage(newURL, 'blue');
-                resolveLocalFileSystemURL(newURL, function(newEntry) {
-                    logMessage("Successfully resolved.", 'green');
-                    logMessage(newEntry.toURL(), 'blue');
-                    logMessage(newEntry.toNativeURL(), 'blue');
-                }, logError("resolveLocalFileSystemURL"));
-            }
-        }, logError("getFile"));
-    }, logError("requestFileSystem"));
-}
-
-function resolveFs(ev) {
-    var fsURL = "cdvfile://localhost/" + ev.target.getAttribute('data-fsname') + "/";
-    logMessage("Resolving URL: " + fsURL);
-    resolveLocalFileSystemURL(fsURL, function(entry) {
-        logMessage("Success", 'green');
-        logMessage(entry.toURL(), 'blue');
-        logMessage(entry.toInternalURL(), 'blue');
-        logMessage("Resolving URL: " + entry.toURL());
-        resolveLocalFileSystemURL(entry.toURL(), function(entry2) {
-            logMessage("Success", 'green');
-            logMessage(entry2.toURL(), 'blue');
-            logMessage(entry2.toInternalURL(), 'blue');
-        }, logError("resolveLocalFileSystemURL"));
-    }, logError("resolveLocalFileSystemURL"));
-}
-
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/index.html
----------------------------------------------------------------------
diff --git a/inappbrowser/index.html b/inappbrowser/index.html
deleted file mode 100644
index b06ed11..0000000
--- a/inappbrowser/index.html
+++ /dev/null
@@ -1,236 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>InAppBrowser</h1>
-    <div id="info">
-        Make sure http://www.google.com is white listed. </br>
-        Make sure http://www.apple.com is not in the white list.</br>  In iOS, starred <span style="vertical-align:super">*</span> tests will put the app in a state with no way to return.  </br>
-        <h4>User-Agent: <span id="user-agent"> </span></h4>
-    </div>
-    <div class="btn small backBtn">Back</div>
-
-    <h1>Local URL</h1>
-    <div class="btn large openLocal">target = Default</div>
-    Expected result: opens successfully in CordovaWebView.
-
-    <p/>
-    <div class="btn large openLocalSelf">target=_self</div>
-    Expected result: opens successfully in CordovaWebView.
-
-    <p/>
-    <div class="btn large openLocalSystem">target=_system</div>
-    Expected result: fails to open.
-
-    <p/>
-    <div class="btn large openLocalBlank">target=_blank</div>
-    Expected result: opens successfully in InAppBrowser with locationBar at top.
-
-    <p/>
-    <div class="btn large openLocalRandomNoLocation">target=Random, location=no,disallowoverscroll=yes</div>
-    Expected result: opens successfully in InAppBrowser without locationBar.
-
-    <p/>
-    <div class="btn large openLocalRandomToolBarBottom">target=Random, toolbarposition=bottom</div>
-    Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the bottom.
-
-    <p/>
-    <div class="btn large openLocalRandomToolBarTop">target=Random, toolbarposition=top</div>
-    Expected result: opens successfully in InAppBrowser with locationBar. On iOS the toolbar is at the top.
-
-    <p/>
-    <div class="btn large openLocalRandomToolBarTopNoLocation">target=Random, toolbarposition=top,location=no</div>
-    Expected result: opens successfully in InAppBrowser with no locationBar. On iOS the toolbar is at the top.
-
-    <h1>White Listed URL</h1>
-
-    <div class="btn large openWhiteListed">target=Default<span style="vertical-align:super">*</span></div>
-    Expected result: open successfully in CordovaWebView to www.google.com.
-
-    <p/>
-    <div class="btn large openWhiteListedSelf">target=_self<span style="vertical-align:super">*</span></div>
-    Expected result: open successfully in CordovaWebView to www.google.com.
-
-    <p/>
-    <div class="btn large openWhiteListedSystem">target=_system</div>
-    Expected result: open successfully in system browser to www.google.com.
-
-    <p/>
-    <div class="btn large openWhiteListedBlank">target=_blank</div>
-    Expected result: open successfully in InAppBrowser to www.google.com.
-
-    <p/>
-    <div class="btn large openWhiteListedRandom">target=Random</div>
-    Expected result: open successfully in InAppBrowser to www.google.com.
-
-    <p/>
-    <div class="btn large openWhiteListedRandomNoLocation">target=Random, no location bar<span style="vertical-align:super">*</span></div>
-    Expected result: open successfully in InAppBrowser to www.google.com with no location bar.
-
-    <h1>Non White Listed URL</h1>
-
-    <div class="btn large openNonWhiteListed">target=Default</div>
-    Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).
-
-    <p/>
-    <div class="btn larg openNonWhiteListedSelf">target=_self</div>
-    Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist).
-
-    <p/>
-    <div class="btn large openNonWhiteListedSystem">target=_system</div>
-    Expected result: open successfully in system browser to apple.com.
-
-    <p/>
-    <div class="btn large openNonWhiteListedBlank">target=_blank</div>
-    Expected result: open successfully in InAppBrowser to apple.com.
-
-    <p/>
-    <div class="btn large openNonWhiteListedRandom">target=Random</div>
-    Expected result: open successfully in InAppBrowser to apple.com.
-
-    <p/>
-    <div class="btn large openNonWhiteListedRandomNoLocation">target=Random, no location bar<span style="vertical-align:super">*</span></div>
-    Expected result: open successfully in InAppBrowser to apple.com without locationBar.
-
-    <h1>Page with redirect</h1>
-
-    <div class="btn large openRedirect301">http://google.com</div>
-    Expected result: should 301 and open successfully in InAppBrowser to www.google.com.
-
-    <p/>
-    <div class="btn large openRedirect302">http://goo.gl/pUFqg</div>
-    Expected result: should 302 and open successfully in InAppBrowser to www.zhihu.com/answer/16714076.
-
-    <h1>PDF URL</h1>
-
-    <div class="btn large openPDF">Remote URL</div>
-    Expected result: InAppBrowser opens. PDF should render on iOS.
-
-    <p/>
-    <div class="btn large openPDFBlank">Local URL</div>
-    Expected result: InAppBrowser opens. PDF should render on iOS.
-
-    <h1>Invalid URL</h1>
-
-    <div class="btn large openInvalidScheme">Invalid Scheme</div>
-    Expected result: fail to load in InAppBrowser.
-
-    <p/>
-    <div class="btn large openInvalidHost">Invalid Host</div>
-    Expected result: fail to load in InAppBrowser.
-
-    <p/>
-    <div class="btn large openInvalidMissing">Missing Local File</div>
-    Expected result: fail to load in InAppBrowser (404).
-
-    <h1>CSS / JS Injection</h1>
-
-    <div class="btn large openOriginalDocument">Original Document</div>
-    Expected result: open successfully in InAppBrowser without text "Style updated from..."
-
-    <p/> 
-    <div class="btn large openCSSInjection">CSS File Injection</div>
-    Expected result: open successfully in InAppBrowser with "Style updated from file".
-
-    <p/>
-    <div class="btn large openCSSInjectionCallback">CSS File Injection (callback)</div>
-    Expected result: open successfully in InAppBrowser with "Style updated from file", and alert dialog with text "Results verified".
-
-    <p/>
-    <div class="btn large openCSSLiteralInjection">CSS Literal Injection</div>
-    Expected result: open successfully in InAppBrowser with "Style updated from literal".
-
-    <p/>
-    <div class="btn large openCSSLiteralInjectionCallback">CSS Literal Injection (callback)</div>
-    Expected result: open successfully in InAppBrowser with "Style updated from literal", and alert dialog with text "Results verified".
-
-    <p/>
-    <div class="btn large openScriptInjection">Script File Injection</div>
-    Expected result: open successfully in InAppBrowser with text "Script file successfully injected".
-
-    <p/>
-    <div class="btn large openScriptInjectionCallback">Script File Injection (callback)</div>
-    Expected result: open successfully in InAppBrowser with text "Script file successfully injected" and alert dialog with the text "Results verified".
-
-    <p/>
-    <div class="btn large openScriptLiteralInjection">Script Literal Injection</div>
-    Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" .
-
-    <p/>
-    <div class="btn large openScriptLiteralInjectionCallback">Script Literal Injection (callback)</div>
-    Expected result: open successfully in InAppBrowser with the text "Script literal successfully injected" and alert dialog with the text "Results verified".
-
-    <h1>Open Hidden </h1>
-    <div class="btn large openHidden">create hidden</div>
-    Expected result: no additional browser window. Alert appears with the text "background window loaded".
-
-    <p/>
-    <div class="btn large showHidden">show hidden</div>
-    Expected result: after first clicking on previous test "create hidden", open successfully in InAppBrowser to google.com.
-
-    <p/>
-    <div class="btn large closeHidden">close hidden</div>
-    Expected result: no output. But click on "show hidden" again and nothing should be shown.
-
-    <p/>
-    <div class="btn large openHiddenShow">google.com not hidden</div>
-    Expected result: open successfully in InAppBrowser to www.google.com
-
-    <h1>Clearing Cache</h1>
-
-    <div class="btn large openClearCache">Clear Browser Cache</div>
-    Expected result: ?
-
-    <p/>
-    <div class="btn large openClearSessionCache">Clear Session Cache</div>
-    Expected result: ?
-
-    <h1>Video tag</h1>
-
-    <div class="btn large openRemoteVideo">remote video</div>
-    Expected result: open successfully in InAppBrowser with an embedded video that works after clicking the "play" button.
-
-    <h1>Local with anchor tag</h1>
-
-    <div class="btn large openAnchor1">Anchor1</div>
-    Expected result: open successfully in InAppBrowser to the local page, scrolled to the top.
-
-    <p/>
-    <div class="btn large openAnchor2">Anchor2</div>
-    Expected result: open successfully in InAppBrowser to the local page, scrolled to the beginning of the tall div with border.
-    
-    <p/>
-    <div class="backBtn">Back</div>
-
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/index.js
----------------------------------------------------------------------
diff --git a/inappbrowser/index.js b/inappbrowser/index.js
deleted file mode 100644
index a08c30d..0000000
--- a/inappbrowser/index.js
+++ /dev/null
@@ -1,242 +0,0 @@
-var deviceReady = false;
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    function updateUserAgent() {
-        document.getElementById("user-agent").textContent = navigator.userAgent;
-    }
-    updateUserAgent();
-    window.setInterval(updateUserAgent, 1500);
-    window.setTimeout(function() {
-      if (!deviceReady) {
-        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-      }
-    },1000);
-}
-
-function doOpen(url, target, params, numExpectedRedirects) {
-    numExpectedRedirects = numExpectedRedirects || 0;
-    var iab = window.open(url, target, params);
-    if (!iab) {
-        alert('window.open returned ' + iab);
-        return;
-    }
-    var counts;
-    var lastLoadStartURL;
-    var wasReset = false;
-    function reset()  {
-        counts = {
-            'loaderror': 0,
-            'loadstart': 0,
-            'loadstop': 0,
-            'exit': 0
-        };
-        lastLoadStartURL = '';
-    }
-    reset();
-
-    function logEvent(e) {
-        console.log('IAB event=' + JSON.stringify(e));
-        counts[e.type]++;
-        // Verify that event.url gets updated on redirects.
-        if (e.type == 'loadstart') {
-            if (e.url == lastLoadStartURL) {
-                alert('Unexpected: loadstart fired multiple times for the same URL.');
-            }
-            lastLoadStartURL = e.url;
-        }
-        // Verify the right number of loadstart events were fired.
-        if (e.type == 'loadstop' || e.type == 'loaderror') {
-            if (e.url != lastLoadStartURL) {
-                alert('Unexpected: ' + e.type + ' event.url != loadstart\'s event.url');
-            }
-            if (numExpectedRedirects === 0 && counts['loadstart'] !== 1) {
-                // Do allow a loaderror without a loadstart (e.g. in the case of an invalid URL).
-                if (!(e.type == 'loaderror' && counts['loadstart'] === 0)) {
-                    alert('Unexpected: got multiple loadstart events. (' + counts['loadstart'] + ')');
-                }
-            } else if (numExpectedRedirects > 0 && counts['loadstart'] < (numExpectedRedirects+1)) {
-                alert('Unexpected: should have got at least ' + (numExpectedRedirects+1) + ' loadstart events, but got ' + counts['loadstart']);
-            }
-            wasReset = true;
-            numExpectedRedirects = 0;
-            reset();
-        }
-        // Verify that loadend / loaderror was called.
-        if (e.type == 'exit') {
-            var numStopEvents = counts['loadstop'] + counts['loaderror'];
-            if (numStopEvents === 0 && !wasReset) {
-                alert('Unexpected: browser closed without a loadstop or loaderror.')
-            } else if (numStopEvents > 1) {
-                alert('Unexpected: got multiple loadstop/loaderror events.');
-            }
-        }
-    }
-    iab.addEventListener('loaderror', logEvent);
-    iab.addEventListener('loadstart', logEvent);
-    iab.addEventListener('loadstop', logEvent);
-    iab.addEventListener('exit', logEvent);
-
-    return iab;
-}
-
-function openWithStyle(url, cssUrl, useCallback) {
-    var iab = doOpen(url, '_blank', 'location=yes');
-    var callback = function(results) {
-        if (results && results.length === 0) {
-            alert('Results verified');
-        } else {
-            console.log(results);
-            alert('Got: ' + typeof(results) + '\n' + JSON.stringify(results));
-        }
-    };
-    if (cssUrl) {
-        iab.addEventListener('loadstop', function(event) {
-            iab.insertCSS({file: cssUrl}, useCallback && callback);
-        });
-    } else {
-        iab.addEventListener('loadstop', function(event) {
-            iab.insertCSS({code:'#style-update-literal { \ndisplay: block !important; \n}'},
-                          useCallback && callback);
-        });
-    }
-}
-
-function openWithScript(url, jsUrl, useCallback) {
-    var iab = doOpen(url, '_blank', 'location=yes');
-    if (jsUrl) {
-        iab.addEventListener('loadstop', function(event) {
-            iab.executeScript({file: jsUrl}, useCallback && function(results) {
-                if (results && results.length === 0) {
-                    alert('Results verified');
-                } else {
-                    console.log(results);
-                    alert('Got: ' + typeof(results) + '\n' + JSON.stringify(results));
-                }
-            });
-        });
-    } else {
-        iab.addEventListener('loadstop', function(event) {
-            var code = '(function(){\n' +
-              '    var header = document.getElementById("header");\n' +
-              '    header.innerHTML = "Script literal successfully injected";\n' +
-              '    return "abc";\n' +
-              '})()';
-            iab.executeScript({code:code}, useCallback && function(results) {
-                if (results && results.length === 1 && results[0] === 'abc') {
-                    alert('Results verified');
-                } else {
-                    console.log(results);
-                    alert('Got: ' + typeof(results) + '\n' + JSON.stringify(results));
-                }
-            });
-        });
-    }
-}
-var hiddenwnd=null;
-var loadlistener = function(event) { alert('background window loaded ' ); };
-function openHidden(url, startHidden) {
-    var shopt =(startHidden) ? 'hidden=yes' : '';
-    hiddenwnd = window.open(url,'random_string',shopt);
-    if (!hiddenwnd) {
-        alert('window.open returned ' + hiddenwnd);
-        return;
-    }
-    if(startHidden) hiddenwnd.addEventListener('loadstop', loadlistener);
-}
-function showHidden() {
-    if(!!hiddenwnd ) {
-        hiddenwnd.show();
-    }
-}
-function closeHidden() {
-   if(!!hiddenwnd ) {
-       hiddenwnd.removeEventListener('loadstop',loadlistener);
-       hiddenwnd.close();
-       hiddenwnd=null;
-   }
-}
-
-window.onload = function() {
-  addListenerToClass('openLocal', doOpen, 'local.html');
-  addListenerToClass('openLocalSelf', doOpen, ['local.html', '_self']);
-  addListenerToClass('openLocalSystem', doOpen, ['local.html', '_system']);
-  addListenerToClass('openLocalBlank', doOpen, ['local.html', '_blank']);
-  addListenerToClass('openLocalRandomNoLocation', doOpen, 
-      ['local.html', 'random_string', 'location=no,disallowoverscroll=yes']);
-  addListenerToClass('openLocalRandomToolBarBottom', doOpen,
-      ['local.html', 'random_string', 'toolbarposition=bottom']);
-  addListenerToClass('openLocalRandomToolBarTop', doOpen, 
-      ['local.html', 'random_string', 'toolbarposition=top']);
-  addListenerToClass('openLocalRandomToolBarTopNoLocation', doOpen, 
-      ['local.html', 'random_string', 'toolbarposition=top,location=no']);
-  addListenerToClass('openWhiteListed', doOpen, 'http://www.google.com');
-  addListenerToClass('openWhiteListedSelf', doOpen, 
-      ['http://www.google.com', '_self']);
-  addListenerToClass('openWhiteListedSystem', doOpen,
-      ['http://www.google.com', '_system']);
-  addListenerToClass('openWhiteListedBlank', doOpen, 
-      ['http://www.google.com', '_blank']);
-  addListenerToClass('openWhiteListedRandom', doOpen,
-      ['http://www.google.com', 'random_string']);
-  addListenerToClass('openWhiteListedRandomNoLocation', doOpen,
-      ['http://www.google.com', 'random_string', 'location=no']);
-  addListenerToClass('openNonWhiteListed', doOpen, 'http://www.apple.com');
-  addListenerToClass('openNonWhiteListedSelf', doOpen, 
-      ['http://www.apple.com', '_self']);
-  addListenerToClass('openNonWhiteListedSystem', doOpen, 
-      ['http://www.apple.com', '_system']);
-  addListenerToClass('openNonWhiteListedBlank', doOpen, 
-      ['http://www.apple.com', '_blank']);
-  addListenerToClass('openNonWhiteListedRandom', doOpen,
-      ['http://www.apple.com', 'random_string']);
-  addListenerToClass('openNonWhiteListedRandomNoLocation', doOpen, 
-      ['http://www.apple.com', 'random_string', 'location=no']);
-  addListenerToClass('openRedirect301', doOpen, 
-      ['http://google.com', 'random_string', '', 1]);
-  addListenerToClass('openRedirect302', doOpen, 
-      ['http://goo.gl/pUFqg', 'random_string', '', 2]);
-  addListenerToClass('openPDF', doOpen, 'http://www.stluciadance.com/prospectus_file/sample.pdf');
-  addListenerToClass('openPDFBlank', doOpen, ['local.pdf', '_blank']);
-  addListenerToClass('openInvalidScheme', doOpen, 
-      ['x-ttp://www.invalid.com/', '_blank']);
-  addListenerToClass('openInvalidHost', doOpen, 
-      ['http://www.inv;alid.com/', '_blank']);
-  addListenerToClass('openInvalidMissing', doOpen, ['nonexistent.html', '_blank']);
-  addListenerToClass('openOriginalDocument', doOpen, ['inject.html', '_blank']);
-  addListenerToClass('openCSSInjection', openWithStyle, 
-      ['inject.html','inject.css']);
-  addListenerToClass('openCSSInjectionCallback', openWithStyle, 
-      ['inject.html','inject.css', true]);
-  addListenerToClass('openCSSLiteralInjection', openWithStyle, 'inject.html');
-  addListenerToClass('openCSSLiteralInjectionCallback', openWithStyle, 
-    ['inject.html', null, true]);
-  addListenerToClass('openScriptInjection', openWithScript, 
-    ['inject.html', 'inject.js']);
-  addListenerToClass('openScriptInjectionCallback', openWithScript, 
-    ['inject.html', 'inject.js', true]);
-  addListenerToClass('openScriptLiteralInjection', openWithScript, 'inject.html');
-  addListenerToClass('openScriptLiteralInjectionCallback', openWithScript, 
-    ['inject.html', null, true]);
-  addListenerToClass('openHidden', openHidden, ['http://google.com', true]);
-  addListenerToClass('showHidden', showHidden);
-  addListenerToClass('closeHidden', closeHidden);
-  addListenerToClass('openHiddenShow', openHidden, ['http://google.com', false]);
-  addListenerToClass('openClearCache', doOpen, 
-    ['http://www.google.com', '_blank', 'clearcache=yes']);
-  addListenerToClass('openClearSessionCache', doOpen, 
-    ['http://www.google.com', '_blank', 'clearsessioncache=yes']);
-  addListenerToClass('openRemoteVideo', doOpen, ['video.html', '_blank']);
-  addListenerToClass('openAnchor1', doOpen, ['local.html#anchor1', '_blank']);
-  addListenerToClass('openAnchor2', doOpen, ['local.html#anchor2', '_blank']);
-
-
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/inject.css
----------------------------------------------------------------------
diff --git a/inappbrowser/inject.css b/inappbrowser/inject.css
deleted file mode 100644
index 3f6e41c..0000000
--- a/inappbrowser/inject.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-#style-update-file {
-    display: block !important;
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/inject.html
----------------------------------------------------------------------
diff --git a/inappbrowser/inject.html b/inappbrowser/inject.html
deleted file mode 100644
index 0f1efdd..0000000
--- a/inappbrowser/inject.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-  </head>
-  <body id="stage" class="theme">
-    <h1 id="header">InAppBrowser - Script / Style Injection Test</h1>
-    <h2 id="style-update-file" style="display:none">Style updated from file</h2>
-    <h2 id="style-update-literal" style="display:none">Style updated from literal</h2>
-  </body>
-  <script>
-      function updateUserAgent() {
-          document.getElementById("u-a").textContent = navigator.userAgent;
-      }
-      updateUserAgent();
-      window.setInterval(updateUserAgent, 1500);
-  </script>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/inject.js
----------------------------------------------------------------------
diff --git a/inappbrowser/inject.js b/inappbrowser/inject.js
deleted file mode 100644
index 6f25493..0000000
--- a/inappbrowser/inject.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
-*/
-var d = document.getElementById("header")
-d.innerHTML = "Script file successfully injected";

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/local.html
----------------------------------------------------------------------
diff --git a/inappbrowser/local.html b/inappbrowser/local.html
deleted file mode 100644
index 5e33800..0000000
--- a/inappbrowser/local.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>IAB test page</title>
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8">
-      function onDeviceReady() {
-          document.getElementById("hint").textContent = "Running CordovaWebView, deviceVersion=" + device.version + ", no toolbar should be present, Back link should work, logcat should NOT have failed 'gap:' calls.";
-      }
-      document.addEventListener("deviceready", onDeviceReady, false);
-    </script>
-  </head>
-  <body id="stage" class="theme">
-    <h1>Local URL</h1>
-    <div id="info">
-        You have successfully loaded a local URL:
-        <script>document.write(location.href)</script>
-    </div>
-    <hr />
-    <div>User-Agent = <span id="u-a"></span></div>
-    <hr />
-    <div id="hint">Likely running inAppBrowser: Device version from Cordova=not found, Back link should not work, toolbar may be present, logcat should show failed 'gap:' calls.</div>
-    <hr />
-    <div><a href="http://www.google.com">Visit Google</a> (whitelisted)</div>
-    <div><a href="http://www.yahoo.com">Visit Yahoo</a> (not whitelisted)</div>
-    <div><a href="http://www.stluciadance.com/prospectus_file/sample.pdf">Check out my remote PDF</a></div>
-    <div><a href="local.pdf">Check out my local PDF</a></div>
-    <p /><a href="javascript:;" onclick="history.back();">Back</a>
-    <p />
-    <a name="anchor2"></a>
-    <div style="height: 1000px;border:1px solid red;">tall div with border</div>
-  </body>
-  <script>
-      function updateUserAgent() {
-          document.getElementById("u-a").textContent = navigator.userAgent;
-      }
-      updateUserAgent();
-      window.setInterval(updateUserAgent, 1500);
-  </script>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/local.pdf
----------------------------------------------------------------------
diff --git a/inappbrowser/local.pdf b/inappbrowser/local.pdf
deleted file mode 100644
index b54f1b7..0000000
Binary files a/inappbrowser/local.pdf and /dev/null differ

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/inappbrowser/video.html
----------------------------------------------------------------------
diff --git a/inappbrowser/video.html b/inappbrowser/video.html
deleted file mode 100644
index 64ea3d1..0000000
--- a/inappbrowser/video.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-
-  </head>
-  <body>
-    <video width=100% height=100% id="player">
-      <source src="http://m.comptoir-info.com/app/beta/sample.mp4">
-      <meta property="og:video:secure_url" content="http://m.comptoir-info.com/app/beta/sample.mp4">
-      <meta property="og:video:type" content="video/mp4">
-    </video>
-    <div>
-      <button onclick="document.getElementById('player').play()"> play </button>
-      <button onclick="document.getElementById('player').pause()"> pause </button>
-    </div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/index.html
----------------------------------------------------------------------
diff --git a/index.html b/index.html
deleted file mode 100644
index 86b1173..0000000
--- a/index.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
-    <title>Cordova Mobile Spec</title>
-	  <link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-	  <script type="text/javascript" charset="utf-8" src="cordova-incl.js"></script>
-	  <script type="text/javascript" charset="utf-8" src="main.js"></script>
-
-  </head>
-  <body id="stage" class="theme">
-    <h1>Apache Cordova Tests</h1>
-    <div id="info">
-        <h4>cordova.version: <span id="cordova"> </span></h4>
-        <h4>Platform: <span id="platform">  </span></h4>
-        <h4>Version: <span id="version"> </span></h4>
-        <h4>UUID: <span id="uuid">  </span></h4>
-        <h4>Model: <span id="model"> </span></h4>
-        <h4>Width: <span id="width">  </span>,   Height: <span id="height">
-                   </span>, Color Depth: <span id="colorDepth"></span></h4>
-        <h4>User-Agent: <span id="user-agent"> </span></h4>
-     </div>
-    <a href="autotest/index.html" class="btn large">Automatic Test</a>
-    <a href="accelerometer/index.html" class="btn large">Accelerometer</a>
-    <a href="audio/index.html" class="btn large">Audio Play/Record</a>
-    <a href="battery/index.html" class="btn large">Battery</a>
-    <a href="camera/index.html" class="btn large">Camera</a>
-    <a href="capture/index.html" class="btn large">Capture</a>
-    <a href="compass/index.html" class="btn large">Compass</a>
-    <a href="contacts/index.html" class="btn large">Contacts</a>
-    <a href="events/index.html" class="btn large">Events</a>
-    <a href="location/index.html" class="btn large">Location</a>
-    <a href="lazyloadjs/index.html" class="btn large">Lazy Loading of cordova-incl.js</a>
-    <a href="misc/index.html" class="btn large">Misc Content</a>
-    <a href="network/index.html" class="btn large">Network</a>
-    <a href="notification/index.html" class="btn large">Notification</a>
-    <a href="splashscreen/index.html" class="btn large">Splashscreen</a>
-    <a href="sql/index.html" class="btn large">Web SQL</a>
-    <a href="storage/index.html" class="btn large">Local Storage</a>
-    <a href="benchmarks/index.html" class="btn large">Benchmarks</a>
-    <a href="inappbrowser/index.html" class="btn large">In App Browser</a>
-    <a href="keyboard/index.html" class="btn large">Keyboard</a>
-    <a href="vibration/index.html" class="btn large">Vibration</a>
-    <a href="file/index.html" class="btn large">File &amp; File Transfer</a>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/keyboard/index.html
----------------------------------------------------------------------
diff --git a/keyboard/index.html b/keyboard/index.html
deleted file mode 100644
index 9a66add..0000000
--- a/keyboard/index.html
+++ /dev/null
@@ -1,175 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <style>
-    table {
-      width: 100%;
-      border: 1px solid white;
-    }
-
-    th, td {
-      width: 25%;
-      text-align: center;
-      vertical-align: top;
-      border: 1px solid gray;
-    }
-    
-    .highlight-w {
-        color: white;
-    }
-    
-    #stage.theme .small{
-        width:50px;
-        padding:1.2em 0;
-    }
-    
-    input[type=text] {
-        width: 70%;
-        height: 30px;
-    }
-    
-    .btn-dismiss {
-        width: 20%;
-        height: 30px;
-    }
-    
-    #error {
-        color: red;
-    }
-
-    </style>
-    <script type="text/javascript" charset="utf-8" src="./window-onerror.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Keyboard (iOS)</h1>
-
-    <br />
-    <div>
-        <input type="text" placeholder="touch to see keyboard" /><button class="btn-dismiss">dismiss</button>
-    </div>
-
-    <h1>isVisible</h1>
-    <br />
-    <div class="btn large keyboardIsVisible">Keyboard.isVisible</div>
-    
-    <h1>API Tests</h1>
-    <br />
-    <div>
-    The current state is highlighted below in the list. Touch a test <span class="highlight-w">"#" button</span> in the table, then touch a textfield (available at the top and bottom of the page) to see the results.
-    </div>
-    <ul>
-        <li>shrinkView(<span id="shrinkView-arg" class="highlight-w">false</span>)</li>
-        <li>hideFormAccessoryBar(<span id="hideFormAccessoryBar-arg" class="highlight-w">false</span>)</li>
-        <li>disableScrollingInShrinkView(<span id="disableScrollingInShrinkView-arg" class="highlight-w">false</span>)</li>
-    </ul>
-    <!-- &#x2717; is X, &#10004; is check-mark -->
-    <table>
-        <tr>
-            <th>Test #</th>
-            <th>shrinkView</th>
-            <th>hideForm&hellip;</th>
-            <th>disableScrolling&hellip;</th>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_1">1</div>
-            </td>
-            <td>&#x2717;</td>
-            <td>&#x2717;</td>
-            <td>&#x2717;</td>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_2">2</div>
-            </td>
-            <td>&#x2717;</td>
-            <td>&#x2717;</td>
-            <td class="highlight-w">&#10004;</td>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_3">3</div>
-            </td>
-            <td>&#x2717;</td>
-            <td class="highlight-w">&#10004;</td>
-            <td class="highlight-w">&#10004;</td>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_4">4</div>
-            </td>
-            <td>&#x2717;</td>
-            <td class="highlight-w">&#10004;</td>
-            <td>&#x2717;</td>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_5">5</div>
-            </td>
-            <td class="highlight-w">&#10004;</td>
-            <td>&#x2717;</td>
-            <td>&#x2717;</td>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_6">6</div>
-            </td>
-            <td class="highlight-w">&#10004;</td>
-            <td>&#x2717;</td>
-            <td class="highlight-w">&#10004;</td>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_7">7</div>
-            </td>
-            <td class="highlight-w">&#10004;</td>
-            <td class="highlight-w">&#10004;</td>
-            <td class="highlight-w">&#10004;</td>
-        </tr>
-        <tr>
-            <td class="highlight-w">
-                <div class="btn small set_8">8</div>
-            </td>
-            <td class="highlight-w">&#10004;</td>
-            <td class="highlight-w">&#10004;</td>
-            <td>&#x2717;</td>
-        </tr>
-    </table>
-    <br />
-    <div>
-        <input type="text" placeholder="touch to see keyboard" /><button class="btn-dismiss">dismiss</button>
-    </div>
-    <br />
-    <div class="backBtn">Back</div>
-    
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/keyboard/index.js
----------------------------------------------------------------------
diff --git a/keyboard/index.js b/keyboard/index.js
deleted file mode 100644
index 2302f31..0000000
--- a/keyboard/index.js
+++ /dev/null
@@ -1,69 +0,0 @@
-
-var deviceReady = false;
-var keyboardPlugin = null;
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            keyboardPlugin = window.Keyboard; // for now, before plugin re-factor
-                              
-            if (keyboardPlugin == null) {
-                var msg = 'The plugin org.apache.cordova.keyboard was not found. Check that you have it installed.';
-                alert(msg);
-            }
-
-        }, false);
-    window.setTimeout(function() {
-      if (!deviceReady) {
-            var msg = 'Error: Apache Cordova did not initialize.  Demo will not run correctly.';
-            alert(msg);
-      }
-    },1000);
-}
-
-function setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(shrinkView, hideFormAccessoryBar, disableScrollingInShrinkView)
-{
-    keyboardPlugin.shrinkView(shrinkView);
-    document.getElementById("shrinkView-arg").innerHTML = shrinkView;
-    
-    keyboardPlugin.hideFormAccessoryBar(hideFormAccessoryBar);
-    document.getElementById("hideFormAccessoryBar-arg").innerHTML = hideFormAccessoryBar;
-
-    keyboardPlugin.disableScrollingInShrinkView(disableScrollingInShrinkView);
-    document.getElementById("disableScrollingInShrinkView-arg").innerHTML = disableScrollingInShrinkView;
-}
-
-window.onload = function() {
-  addListenerToClass('keyboardIsVisible', function() {
-    alert('Keyboard.isVisible: ' + Keyboard.isVisible);
-  });
-  addListenerToClass('set_1', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, false, false)
-  });
-  addListenerToClass('set_2', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, false, true)
-  });
-  addListenerToClass('set_3', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, true, true)
-  });
-  addListenerToClass('set_4', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(false, true, false)
-  });
-  addListenerToClass('set_5', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, false, false)
-  });
-  addListenerToClass('set_6', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, false, true)
-  });
-  addListenerToClass('set_7', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, true, true)
-  });
-  addListenerToClass('set_8', function() {
-    setShrinkView_hideFormAccessoryBar_andDisableScrollingInShrinkView(true, true, false)
-  });
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/keyboard/window-onerror.js
----------------------------------------------------------------------
diff --git a/keyboard/window-onerror.js b/keyboard/window-onerror.js
deleted file mode 100644
index f833882..0000000
--- a/keyboard/window-onerror.js
+++ /dev/null
@@ -1 +0,0 @@
-window.onerror = function(err,fn,ln) {alert("ERROR:" + err + ", " + fn + ":" + ln);};

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/lazyloadjs/do-not-write-cordova-script.js
----------------------------------------------------------------------
diff --git a/lazyloadjs/do-not-write-cordova-script.js b/lazyloadjs/do-not-write-cordova-script.js
deleted file mode 100644
index 0f20c76..0000000
--- a/lazyloadjs/do-not-write-cordova-script.js
+++ /dev/null
@@ -1 +0,0 @@
-_doNotWriteCordovaScript = true;

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/lazyloadjs/index.html
----------------------------------------------------------------------
diff --git a/lazyloadjs/index.html b/lazyloadjs/index.html
deleted file mode 100644
index 5816349..0000000
--- a/lazyloadjs/index.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Lazy-Loading of cordova-incl.js test</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
-    <script type="text/javascript" charset="utf-8" src="./do-not-write-cordova-script.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-    <h1>Lazy-Loading of cordova-incl.js</h1>
-    <div id="info">
-      onDeviceReady has not yet fired.
-    </div>
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/lazyloadjs/index.js
----------------------------------------------------------------------
diff --git a/lazyloadjs/index.js b/lazyloadjs/index.js
deleted file mode 100644
index 6559319..0000000
--- a/lazyloadjs/index.js
+++ /dev/null
@@ -1,16 +0,0 @@
-function init() {
-    document.addEventListener("deviceready", function() {
-        console.log("Device="+device.platform+" "+device.version);
-        document.getElementById('info').innerHTML = 'Cordova loaded just fine.';
-    }, false);
-    window.setTimeout(function() {
-        var s = document.createElement('script');
-        s.src = cordovaPath;
-        document.body.appendChild(s);
-    }, 0);
-}
-
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/location/index.html
----------------------------------------------------------------------
diff --git a/location/index.html b/location/index.html
deleted file mode 100644
index f0cc7de..0000000
--- a/location/index.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Location</h1>
-    <div id="info">
-        <b>Status:</b> <span id="location_status">Stopped</span>
-        <table width="100%">
-            <tr>
-                <td><b>Latitude:</b></td>
-                <td id="latitude">&nbsp;</td>
-                <td>(decimal degrees) geographic coordinate [<a href="http://dev.w3.org/geo/api/spec-source.html#lat">#ref]</a></td>
-            </tr>
-            <tr>
-                <td><b>Longitude:</b></td>
-                <td id="longitude">&nbsp;</td>
-                <td>(decimal degrees) geographic coordinate [<a href="http://dev.w3.org/geo/api/spec-source.html#lat">#ref]</a></td>
-            </tr>
-            <tr>
-                <td><b>Altitude:</b></td>
-                <td id="altitude">&nbsp;</td>
-                <td>null if not supported;<br>
-                    (meters) height above the [<a href="http://dev.w3.org/geo/api/spec-source.html#ref-wgs">WGS84</a>] ellipsoid. [<a href="http://dev.w3.org/geo/api/spec-source.html#altitude">#ref]</a></td>
-            </tr>
-            <tr>
-                <td><b>Accuracy:</b></td>
-                <td id="accuracy">&nbsp;</td>
-                <td>(meters; non-negative; 95% confidence level) the accuracy level of the latitude and longitude coordinates. [<a href="http://dev.w3.org/geo/api/spec-source.html#accuracy">#ref]</a></td>
-            </tr>
-            <tr>
-                <td><b>Heading:</b></td>
-                <td id="heading">&nbsp;</td>
-                <td>null if not supported;<br>
-                    NaN if speed == 0;<br>
-                    (degrees; 0° ≤ heading < 360°) direction of travel of the hosting device- counting clockwise relative to the true north. [<a href="http://dev.w3.org/geo/api/spec-source.html#heading">#ref]</a></td>
-            </tr>
-            <tr>
-                <td><b>Speed:</b></td>
-                <td id="speed">&nbsp;</td>
-                <td>null if not supported;<br>
-                    (meters per second; non-negative) magnitude of the horizontal component of the hosting device's current velocity. [<a href="http://dev.w3.org/geo/api/spec-source.html#speed">#ref]</a></td>
-            </tr>
-            <tr>
-                <td><b>Altitude Accuracy:</b></td>
-                <td id="altitude_accuracy">&nbsp;</td>
-                <td>null if not supported;<br>(meters; non-negative; 95% confidence level) the accuracy level of the altitude. [<a href="http://dev.w3.org/geo/api/spec-source.html#altitude-accuracy">#ref]</a></td>
-            </tr>
-            <tr>
-                <td><b>Time:</b></td>
-                <td id="timestamp">&nbsp;</td>
-                <td>(DOMTimeStamp) when the position was acquired [<a href="http://dev.w3.org/geo/api/spec-source.html#timestamp">#ref]</a></td>
-            </tr>
-        </table>
-    </div>
-    <h2>Action</h2>
-    <h3>Use Built-in WebView navigator.geolocation</h3>
-    <a href="javascript:" class="btn large getWebViewLocation">Get Location</a>
-    <a href="javascript:" class="btn large watchWebViewLocation">Start Watching Location</a>
-    <a href="javascript:" class="btn large stopWebViewLocation">Stop Watching Location</a>
-    <a href="javascript:" class="btn large getWebViewLocation30">Get Location Up to 30 Seconds Old</a>
-    <h3>Use Cordova Geolocation Plugin</h3>
-    <a href="javascript:" class="btn large getLocation">Get Location</a>
-    <a href="javascript:" class="btn large watchLocation">Start Watching Location</a>
-    <a href="javascript:" class="btn large stopLocation">Stop Watching Location</a>
-    <a href="javascript:" class="btn large getLocation30">Get Location Up to 30 Seconds Old</a>
-    <h2>&nbsp;</h2><a href="javascript:" class="backBtn"">Back</a>    
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/location/index.js
----------------------------------------------------------------------
diff --git a/location/index.js b/location/index.js
deleted file mode 100644
index 242919d..0000000
--- a/location/index.js
+++ /dev/null
@@ -1,128 +0,0 @@
-var origGeolocation = null;
-var newGeolocation = null;
-
-//-------------------------------------------------------------------------
-// Location
-//-------------------------------------------------------------------------
-var watchLocationId = null;
-
-/**
- * Start watching location
- */
-var watchLocation = function(usePlugin) {
-    var geo = usePlugin ? newGeolocation : origGeolocation;
-    if (!geo) {
-        alert('geolocation object is missing. usePlugin = ' + usePlugin);
-        return;
-    }
-
-    // Success callback
-    var success = function(p){
-          console.log('watch location success');
-          setLocationDetails(p);
-    };
-
-    // Fail callback
-    var fail = function(e){
-        console.log("watchLocation fail callback with error code "+e);
-        stopLocation(geo);
-    };
-
-    // Get location
-    watchLocationId = geo.watchPosition(success, fail, {enableHighAccuracy: true});
-    setLocationStatus("Running");
-};
-
-/**
- * Stop watching the location
- */
-var stopLocation = function(usePlugin) {
-    var geo = usePlugin ? newGeolocation : origGeolocation;
-    if (!geo) {
-        alert('geolocation object is missing. usePlugin = ' + usePlugin);
-        return;
-    }
-    setLocationStatus("Stopped");
-    if (watchLocationId) {
-        geo.clearWatch(watchLocationId);
-        watchLocationId = null;
-    }
-};
-
-/**
- * Get current location
- */
-var getLocation = function(usePlugin, opts) {
-    var geo = usePlugin ? newGeolocation : origGeolocation;
-    if (!geo) {
-        alert('geolocation object is missing. usePlugin = ' + usePlugin);
-        return;
-    }
-
-    // Stop location if running
-    stopLocation(geo);
-
-    // Success callback
-    var success = function(p){
-        console.log('get location success');
-        setLocationDetails(p);
-        setLocationStatus("Done");
-    };
-
-    // Fail callback
-    var fail = function(e){
-        console.log("getLocation fail callback with error code "+e.code);
-        setLocationStatus("Error: "+e.code);
-    };
-
-    setLocationStatus("Retrieving location...");
-
-    // Get location
-    geo.getCurrentPosition(success, fail, opts || {enableHighAccuracy: true}); //, {timeout: 10000});
-
-};
-
-/**
- * Set location status
- */
-var setLocationStatus = function(status) {
-    document.getElementById('location_status').innerHTML = status;
-};
-var setLocationDetails = function(p) {
-var date = (new Date(p.timestamp));
-        document.getElementById('latitude').innerHTML = p.coords.latitude;
-        document.getElementById('longitude').innerHTML = p.coords.longitude;
-        document.getElementById('altitude').innerHTML = p.coords.altitude;
-        document.getElementById('accuracy').innerHTML = p.coords.accuracy;
-        document.getElementById('heading').innerHTML = p.coords.heading;
-        document.getElementById('speed').innerHTML = p.coords.speed;
-        document.getElementById('altitude_accuracy').innerHTML = p.coords.altitudeAccuracy;
-        document.getElementById('timestamp').innerHTML =  date.toDateString() + " " + date.toTimeString();
-}
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-        newGeolocation = navigator.geolocation;
-        origGeolocation = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation');
-        if (!origGeolocation) {
-            origGeolocation = newGeolocation;
-            newGeolocation = null;
-        }
-    }, false);
-}
-
-window.onload = function() {
-  addListenerToClass('getWebViewLocation', getLocation, [false]);
-  addListenerToClass('watchWebViewLocation', watchLocation, [false]);
-  addListenerToClass('stopWebViewLocation', stopLocation, [false]);
-  addListenerToClass('getWebViewLocation30', getLocation, [false, {maximumAge:30000}]);
-  addListenerToClass('getLocation', getLocation, [true]);
-  addListenerToClass('watchLocation', watchLocation, [true]);
-  addListenerToClass('stopLocation', stopLocation, [true]);
-  addListenerToClass('getLocation30', getLocation, [true, {maximumAge:30000}]);
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/main.js
----------------------------------------------------------------------
diff --git a/main.js b/main.js
deleted file mode 100644
index 42e9edd..0000000
--- a/main.js
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-var deviceInfo = function() {
-    document.getElementById("cordova").innerHTML = cordova.version;
-    document.getElementById("platform").innerHTML = device.platform;
-    document.getElementById("version").innerHTML = device.version;
-    document.getElementById("uuid").innerHTML = device.uuid;
-    document.getElementById("model").innerHTML = device.model;
-    document.getElementById("width").innerHTML = screen.width;
-    document.getElementById("height").innerHTML = screen.height;
-    document.getElementById("colorDepth").innerHTML = screen.colorDepth;
-};
-
-var getLocation = function() {
-    var suc = function(p) {
-        alert(p.coords.latitude + " " + p.coords.longitude);
-    };
-    var locFail = function() {
-    };
-    navigator.geolocation.getCurrentPosition(suc, locFail);
-};
-
-var beep = function() {
-    navigator.notification.beep(2);
-};
-
-var vibrate = function() {
-    navigator.notification.vibrate(0);
-};
-
-function roundNumber(num) {
-    var dec = 3;
-    var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
-    return result;
-}
-
-var accelerationWatch = null;
-
-function updateAcceleration(a) {
-    document.getElementById('x').innerHTML = roundNumber(a.x);
-    document.getElementById('y').innerHTML = roundNumber(a.y);
-    document.getElementById('z').innerHTML = roundNumber(a.z);
-}
-
-var toggleAccel = function() {
-    if (accelerationWatch !== null) {
-        navigator.accelerometer.clearWatch(accelerationWatch);
-        updateAcceleration({
-            x : "",
-            y : "",
-            z : ""
-        });
-        accelerationWatch = null;
-    } else {
-        var options = {};
-        options.frequency = 1000;
-        accelerationWatch = navigator.accelerometer.watchAcceleration(
-                updateAcceleration, function(ex) {
-                    alert("accel fail (" + ex.name + ": " + ex.message + ")");
-                }, options);
-    }
-};
-
-var preventBehavior = function(e) {
-    e.preventDefault();
-};
-
-function dump_pic(data) {
-    var viewport = document.getElementById('viewport');
-    console.log(data);
-    viewport.style.display = "";
-    viewport.style.position = "absolute";
-    viewport.style.top = "10px";
-    viewport.style.left = "10px";
-    document.getElementById("test_img").src = "data:image/jpeg;base64," + data;
-}
-
-function fail(msg) {
-    alert(msg);
-}
-
-function show_pic() {
-    navigator.camera.getPicture(dump_pic, fail, {
-        quality : 50
-    });
-}
-
-function close() {
-    var viewport = document.getElementById('viewport');
-    viewport.style.position = "relative";
-    viewport.style.display = "none";
-}
-
-// This is just to do this.
-function readFile() {
-    navigator.file.read('/sdcard/cordova.txt', fail, fail);
-}
-
-function writeFile() {
-    navigator.file.write('foo.txt', "This is a test of writing to a file",
-            fail, fail);
-}
-
-function contacts_success(contacts) {
-    alert(contacts.length
-            + ' contacts returned.'
-            + (contacts[2] && contacts[2].name ? (' Third contact is ' + contacts[2].name.formatted)
-                    : ''));
-}
-
-function get_contacts() {
-    var obj = new ContactFindOptions();
-    obj.filter = "";
-    obj.multiple = true;
-    obj.limit = 5;
-    navigator.service.contacts.find(
-            [ "displayName", "name" ], contacts_success,
-            fail, obj);
-}
-
-var networkReachableCallback = function(reachability) {
-    // There is no consistency on the format of reachability
-    var networkState = reachability.code || reachability;
-
-    var currentState = {};
-    currentState[NetworkStatus.NOT_REACHABLE] = 'No network connection';
-    currentState[NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK] = 'Carrier data connection';
-    currentState[NetworkStatus.REACHABLE_VIA_WIFI_NETWORK] = 'WiFi connection';
-
-    confirm("Connection type:\n" + currentState[networkState]);
-};
-
-function check_network() {
-    navigator.network.isReachable("www.mobiledevelopersolutions.com",
-            networkReachableCallback, {});
-}
-
-function init() {
-    // the next line makes it impossible to see Contacts on the HTC Evo since it
-    // doesn't have a scroll button
-    // document.addEventListener("touchmove", preventBehavior, false);
-    document.addEventListener("deviceready", deviceInfo, true);
-    document.getElementById("user-agent").textContent = navigator.userAgent;
-}
-
-window.onload = init;

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/master.css
----------------------------------------------------------------------
diff --git a/master.css b/master.css
deleted file mode 100644
index 8c2b232..0000000
--- a/master.css
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-  body {
-    background:#222 none repeat scroll 0 0;
-    color:#666;
-    font-family:Helvetica;
-    font-size:72%;
-    line-height:1.5em;
-    margin:0;
-    border-top:1px solid #393939;
-  }
-
-  #info{
-    background:#ffa;
-    border: 1px solid #ffd324;
-    -webkit-border-radius: 5px;
-    border-radius: 5px;
-    clear:both;
-    margin:15px 6px 0;
-    min-width:295px;
-    max-width:97%;
-    padding:4px 0px 2px 10px;
-    word-wrap:break-word;
-    margin-bottom:10px;
-    display:inline-block;
-    min-height: 160px;
-    max-height: 300px;
-    overflow: auto;
-    -webkit-overflow-scrolling: touch;
-  }
-  
-  #info > h4{
-    font-size:.95em;
-    margin:5px 0;
-  }
- 	
-  #stage.theme{
-    padding-top:3px;
-  }
-
-  /* Definition List */
-  #stage.theme > dl{
-  	padding-top:10px;
-  	clear:both;
-  	margin:0;
-  	list-style-type:none;
-  	padding-left:10px;
-  	overflow:auto;
-  }
-
-  #stage.theme > dl > dt{
-  	font-weight:bold;
-  	float:left;
-  	margin-left:5px;
-  }
-
-  #stage.theme > dl > dd{
-  	width:45px;
-  	float:left;
-  	color:#a87;
-  	font-weight:bold;
-  }
-
-  /* Content Styling */
-  #stage.theme > h1, #stage.theme > h2, #stage.theme > p{
-    margin:1em 0 .5em 13px;
-  }
-
-  #stage.theme > h1{
-    color:#eee;
-    font-size:1.6em;
-    text-align:center;
-    margin:0;
-    margin-top:15px;
-    padding:0;
-  }
-
-  #stage.theme > h2{
-  	clear:both;
-    margin:0;
-    padding:3px;
-    font-size:1em;
-    text-align:center;
-  }
-
-  /* Stage Buttons */
-  #stage.theme .btn{
-  	border: 1px solid #555;
-  	-webkit-border-radius: 5px;
-  	border-radius: 5px;
-  	text-align:center;
-  	display:inline-block;
-  	background:#444;
-  	width:150px;
-  	color:#9ab;
-  	font-size:1.1em;
-  	text-decoration:none;
-  	padding:1.2em 0;
-  	margin:3px 0px 3px 5px;
-  }
-  
-  #stage.theme .large{
-  	width:308px;
-  	padding:1.2em 0;
-  }
-  
-  #stage.theme .wide{
-    width:100%;
-    padding:1.2em 0;
-  }
-  
-  #stage.theme .backBtn{
-   border: 1px solid #555;
-   -webkit-border-radius: 5px;
-   border-radius: 5px;
-   text-align:center;
-   display:block;
-   float:right;
-   background:#666;
-   width:75px;
-   color:#9ab;
-   font-size:1.1em;
-   text-decoration:none;
-   padding:1.2em 0;
-   margin:3px 5px 3px 5px;
-  }
-  
-  #stage.theme .input{
-   border: 1px solid #555;
-   -webkit-border-radius: 5px;
-   border-radius: 5px;
-   text-align:center;
-   display:block;
-   float:light;
-   background:#888;
-   color:#9cd;
-   font-size:1.1em;
-   text-decoration:none;
-   padding:1.2em 0;
-   margin:3px 0px 3px 5px;    
- }
-  
-  #stage.theme .numeric{
-   width:100%;
-  }
-
-/* Selectively hide and show items by platform */
-.platform {
-  display: none;
-}
-
-body.amazon-fireos-platform .platform.amazon-fireos,
-body.android-platform .platform.android,
-body.blackberry10-platform .platform.blackberry10,
-body.browser-platform .platform.browser,
-body.firefoxos-platform .platform.firefoxos,
-body.ios-platform .platform.ios,
-body.osx-platform .platform.ios,
-body.ubuntu-platform .platform.ubuntu,
-body.windows8-platform .platform.windows8,
-body.windowsphone-platform .platform.windowsphone {
-  display: block;
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/misc/index.html
----------------------------------------------------------------------
diff --git a/misc/index.html b/misc/index.html
deleted file mode 100644
index 0ebb217..0000000
--- a/misc/index.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <!-- ISO-8859-1 -->
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="./index.js"></script>      
-
-  </head>
-  <body id="stage" class="theme">
-  
-    <h1>Display Other Content</h1>
-    <div id="info">
-    </div>
-    <h2>Action</h2>
-    <div class="btn large telLocation">Call 411</div>
-    <a href="mailto:bob@abc.org?subject=My Subject&body=This is the body.%0D%0ANew line." class="btn large">Send Mail</a>
-    <a href="sms:5125551234?body=The SMS message." class="btn large">Send SMS</a>
-    <a href="http://www.google.com" class="btn large">Load Web Site</a>
-    <!--  Need new URL -->
-    <!-- a href="http://handle.library.cornell.edu/control/authBasic/authTest/" class="btn large">Basic Auth: test/this</a -->
-    <a href="page2.html" class="btn large">Load a page with iframes</a>
-    <a href="page2.html?me=test" class="btn large">Load page with query param</a>
-    <a href="page3.html#foo" class="btn large">Page with hash</a>
-    <a href="page3.html?hash1#gah" class="btn large">Page with hash change on load</a>
-    <a href="page3.html?hash2#gah" class="btn large">Page with hash replace on load</a>
-    <a href="page3.html?hash1&changeURL#gah" class="btn large">Page with replaceState & hash change</a>
-    <a href="page3.html?iframe#gah" class="btn large">Page iframe hash change</a>
-    <h2>Android Only</h2>
-    <a href="geo:0,0?q=11400 Burnet Rd, Austin, TX" class="btn large">Map IBM</a>
-    <a href="market://search?q=google" class="btn large">Search Android market</a>
-    <a href="content://media/external/images/media" class="btn large">View image app</a>
-
-    <h2> </h2><div class="backBtn">Back</div>
-  </body>
-</html>      

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/misc/index.js
----------------------------------------------------------------------
diff --git a/misc/index.js b/misc/index.js
deleted file mode 100644
index e38ade7..0000000
--- a/misc/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-var deviceReady = false;
-
-function roundNumber(num) {
-    var dec = 3;
-    var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);
-    return result;
-}
-
-/**
- * Function called when page has finished loading.
- */
-function init() {
-    document.addEventListener("deviceready", function() {
-            deviceReady = true;
-            console.log("Device="+device.platform+" "+device.version);
-        }, false);
-    window.setTimeout(function() {
-      if (!deviceReady) {
-        alert("Error: Apache Cordova did not initialize.  Demo will not run correctly.");
-      }
-    },1000);
-}
-
-window.onload = function() {
-  addListenerToClass('telLocation', function() {
-    document.location='tel:5551212';
-  });
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/misc/page2.html
----------------------------------------------------------------------
diff --git a/misc/page2.html b/misc/page2.html
deleted file mode 100644
index 1d370a9..0000000
--- a/misc/page2.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="../main.js"></script>
-    <script type="text/javascript" charset="utf-8" src="./page2.js"></script>      
-    <style>
-      iframe, .iframe_container {
-        height:100px;
-        overflow:scroll;
-      }
-    </style>
-  </head>
-  <body id="stage" class="theme">
-    <h1>Page2 App</h1>
-    <h2>This is page 2 of a Apache Cordova app</h2>
-    <div id="info">
-      loading...
-     </div>
-     about:blank
-     <div class="iframe_container">
-       <iframe src="about:blank"></iframe>
-     </div>
-     invalid URL
-     <div class="iframe_container">
-       <iframe src="x-ttp://www.invalid.com/"></iframe>
-     </div>
-     whatheaders.com
-     <div class="iframe_container">
-       <iframe src="http://whatheaders.com"></iframe>
-     </div>
-     apache.org
-     <div class="iframe_container">
-       <iframe src="" id="apacheiframe"></iframe>
-     </div>
-     <div><button class="backBtn">Back</button></div>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/misc/page2.js
----------------------------------------------------------------------
diff --git a/misc/page2.js b/misc/page2.js
deleted file mode 100644
index 1f489c2..0000000
--- a/misc/page2.js
+++ /dev/null
@@ -1,12 +0,0 @@
-setTimeout(function() {
-    console.log('loading iframe after timeout.');
-    document.querySelector('#apacheiframe').src = 'http://apache.org';
-}, 2000);
-document.addEventListener("deviceready", function() {
-    document.getElementById('info').textContent += '\nDevice is ready.';
-}, false);
-
-window.onload = function() {
-  addListenerToClass('backBtn', backHome);
-  init();
-}

http://git-wip-us.apache.org/repos/asf/cordova-mobile-spec/blob/77ff9a37/misc/page3.html
----------------------------------------------------------------------
diff --git a/misc/page3.html b/misc/page3.html
deleted file mode 100644
index 6677677..0000000
--- a/misc/page3.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!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 name="viewport" content="width=device-width,height=device-height,user-scalable=no,maximum-scale=1.0,initial-scale=1.0" />
-    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
-    <title>Cordova Mobile Spec</title>
-    <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title" charset="utf-8">
-    <script type="text/javascript" charset="utf-8" src="./page3A.js"></script>      
-    <script type="text/javascript" charset="utf-8" src="../cordova-incl.js"></script>
-    <script type="text/javascript" charset="utf-8" src="../main.js"></script>
-  </head>
-  <body onload="init();" id="stage" class="theme">
-    <h1>Page2 App</h1>
-    <h2>This is page 2 of a Apache Cordova app</h2>
-    <div id="info">
-      loading...
-     </div>
-    <div id="info2">
-     </div>
-     <script>
-      if (location.search.indexOf('iframe') != -1) {
-        document.write('<iframe src="' + location.href.replace('iframe','hash1') + '"></iframe>');
-      }
-     </script>
-     <div><button onclick="changeHash()">changeHash()</button></div>
-     <div><button onclick="loadFrame()">loadFrame()</button></div>
-     <div><button onclick="reload()">reload()</button></div>
-     <div><button class="backBtn" onclick="backHome();">Back</button></div>
-  </body>
-  <script>
-    setInterval(function() {
-      document.getElementById('info2').textContent = location.href;
-    }, 300);
-
-    document.addEventListener("deviceready", function() {
-        document.getElementById('info').innerHTML += '<br>Device is ready.';
-        console.log('device ready');
-    }, false);
-    window.onload = function() {
-        document.getElementById('info').innerHTML += '<br>got load event.';
-        console.log('got onload');
-    }
-  </script>
-  <script>
-    document.getElementById('info').innerHTML += '<br>Changing hash #2.';
-    console.log('Changing hash #2');
-    if (location.search.indexOf('hash1') != -1) {
-      location.hash = 'b';
-    } else if (location.search.indexOf('hash2') != -1) {
-      location.replace('#replaced2');
-    }
-    var hashCount = 0;
-    function changeHash() {
-      hashCount += 1;
-      if (hashCount % 1) {
-        location.hash = hashCount;
-      } else {
-        location.replace('#' + hashCount);
-      }
-    }
-  </script>
-</html>