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:06 UTC

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

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>