| <!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"> |
| |
| 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, false); |
| iab.addEventListener('loadstart', logEvent, false); |
| iab.addEventListener('loadstop', logEvent, false); |
| iab.addEventListener('exit', logEvent, false); |
| |
| 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; |
| } |
| } |
| </script> |
| </head> |
| <body onload="init();" 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 leave the app with no way to return. </br> |
| <h4>User-Agent: <span id="user-agent"> </span></h4> |
| </div> |
| <div onclick="backHome();">Back</div> |
| <h1>Local URL</h1> |
| <div class="btn large" onclick="doOpen('local.html');">Default: CordovaWebView</div> |
| <div class="btn large" onclick="doOpen('local.html', '_self');">Target=Self: CordovaWebView</div> |
| <div class="btn large" onclick="doOpen('local.html', '_system');">Target=System: Error</div> |
| <div class="btn large" onclick="doOpen('local.html', '_blank');">Target=Blank: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('local.html', 'random_string');">Target=Random: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('local.html', 'random_string', 'location=no');">Target=Random, no location bar: InAppBrowser</div> |
| <h1>White Listed URL</h1> |
| <div class="btn large" onclick="doOpen('http://www.google.com');">Default: CordovaWebView<span style="vertical-align:super">*</span></div> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_self');">Target=Self: CordovaWebView<span style="vertical-align:super">*</span></div> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_system');">Target=System: System Browser</div> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_blank');">Target=Blank: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('http://www.google.com', 'random_string');">Target=Random: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('http://www.google.com', 'random_string', 'location=no');">Target=Random, no location bar: InAppBrowser</div> |
| <h1>Non White Listed URL</h1> |
| <div class="btn large" onclick="doOpen('http://www.apple.com');">Default: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', '_self');">Target=Self: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', '_system');">Target=System: System</div> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', '_blank');">Target=Blank: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', 'random_string');">Target=Random: InAppBrowser</div> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', 'random_string', 'location=no');">Target=Random, no location bar: InAppBrowser</div> |
| <h1>Page with redirect</h1> |
| <div class="btn large" onclick="doOpen('http://google.com', 'random_string', '', 1);">http://google.com (should 301)</div> |
| <div class="btn large" onclick="doOpen('http://goo.gl/pUFqg', 'random_string', '', 2);">http://www.zhihu.com/answer/16714076 (should 302)</div> |
| <h1>PDF URL</h1> |
| <div class="btn large" onclick="doOpen('http://www.stluciadance.com/prospectus_file/sample.pdf');">Remote URL</div> |
| <div class="btn large" onclick="doOpen('local.pdf', '_blank');">Local URL</div> |
| <h1>INVALID URL</h1> |
| <div class="btn large" onclick="doOpen('x-ttp://www.invalid.com/', '_blank');">Invalid Scheme</div> |
| <div class="btn large" onclick="doOpen('http://www.inv;alid.com/', '_blank');">Invalid Host</div> |
| <div class="btn large" onclick="doOpen('nonexistent.html', '_blank');">Missing File</div> |
| <h1>CSS / JS Injection</h1> |
| <div class="btn large" onclick="doOpen('inject.html', '_blank');">Original Document</div> |
| <div class="btn large" onclick="openWithStyle('inject.html','inject.css');">CSS File Injection</div> |
| <div class="btn large" onclick="openWithStyle('inject.html','inject.css', true);">CSS File Injection (CB)</div> |
| <div class="btn large" onclick="openWithStyle('inject.html');">CSS Literal Injection</div> |
| <div class="btn large" onclick="openWithStyle('inject.html', null, true);">CSS Literal Injection (CB)</div> |
| <div class="btn large" onclick="openWithScript('inject.html', 'inject.js');">Script File Injection</div> |
| <div class="btn large" onclick="openWithScript('inject.html', 'inject.js', true);">Script File Injection (CB)</div> |
| <div class="btn large" onclick="openWithScript('inject.html');">Script Literal Injection</div> |
| <div class="btn large" onclick="openWithScript('inject.html', null, true);">Script Literal Injection (CB)</div> |
| <h1>Open Hidden </h1> |
| <div class="btn large" onclick="openHidden('http://google.com',true);">google.com hidden</div> |
| <div class="btn large" onclick="showHidden();">show hidden</div> |
| <div class="btn large" onclick="closeHidden();">close hidden</div> |
| <div class="btn large" onclick="openHidden('http://google.com',false);">google.com not hidden</div> |
| <h1>Clearing Cache</h1> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_blank', 'clearcache=yes');">Clear Browser Cache</div> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_blank', 'clearsessioncache=yes');">Clear Session Cache</div> |
| <h1>Video tag</h1> |
| <div class="btn large" onclick="doOpen('video.html', '_blank');">remote video</div> |
| <h2> </h2><div class="backBtn" onclick="backHome();">Back</div> |
| </body> |
| </html> |