| <!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 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" onclick="backHome();">Back</div> |
| |
| <h1>Local URL</h1> |
| <div class="btn large" onclick="doOpen('local.html');">target = Default</div> |
| Expected result: opens successfully in CordovaWebView. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('local.html', '_self');">target=_self</div> |
| Expected result: opens successfully in CordovaWebView. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('local.html', '_system');">target=_system</div> |
| Expected result: fails to open. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('local.html', '_blank');">target=_blank</div> |
| Expected result: opens successfully in InAppBrowser with locationBar at top. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('local.html', 'random_string', 'location=no,disallowoverscroll=yes');">target=Random, location=no,disallowoverscroll=yes</div> |
| Expected result: opens successfully in InAppBrowser without locationBar. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('local.html', 'random_string', 'toolbarposition=bottom');">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" onclick="doOpen('local.html', 'random_string', 'toolbarposition=top');">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" onclick="doOpen('local.html', 'random_string', 'toolbarposition=top,location=no');">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" onclick="doOpen('http://www.google.com');">target=Default<span style="vertical-align:super">*</span></div> |
| Expected result: open successfully in CordovaWebView to www.google.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_self');">target=_self<span style="vertical-align:super">*</span></div> |
| Expected result: open successfully in CordovaWebView to www.google.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_system');">target=_system</div> |
| Expected result: open successfully in system browser to www.google.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_blank');">target=_blank</div> |
| Expected result: open successfully in InAppBrowser to www.google.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.google.com', 'random_string');">target=Random</div> |
| Expected result: open successfully in InAppBrowser to www.google.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.google.com', 'random_string', 'location=no');">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" onclick="doOpen('http://www.apple.com');">target=Default</div> |
| Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist). |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', '_self');">target=_self</div> |
| Expected result: open successfully in InAppBrowser to apple.com (_self enforces whitelist). |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', '_system');">target=_system</div> |
| Expected result: open successfully in system browser to apple.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', '_blank');">target=_blank</div> |
| Expected result: open successfully in InAppBrowser to apple.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', 'random_string');">target=Random</div> |
| Expected result: open successfully in InAppBrowser to apple.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.apple.com', 'random_string', 'location=no');">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" onclick="doOpen('http://google.com', 'random_string', '', 1);">http://google.com</div> |
| Expected result: should 301 and open successfully in InAppBrowser to www.google.com. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://goo.gl/pUFqg', 'random_string', '', 2);">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" onclick="doOpen('http://www.stluciadance.com/prospectus_file/sample.pdf');">Remote URL</div> |
| Expected result: InAppBrowser opens. PDF should render on iOS. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('local.pdf', '_blank');">Local URL</div> |
| Expected result: InAppBrowser opens. PDF should render on iOS. |
| |
| <h1>Invalid URL</h1> |
| |
| <div class="btn large" onclick="doOpen('x-ttp://www.invalid.com/', '_blank');">Invalid Scheme</div> |
| Expected result: fail to load in InAppBrowser. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.inv;alid.com/', '_blank');">Invalid Host</div> |
| Expected result: fail to load in InAppBrowser. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('nonexistent.html', '_blank');">Missing Local File</div> |
| Expected result: fail to load in InAppBrowser (404). |
| |
| <h1>CSS / JS Injection</h1> |
| |
| <div class="btn large" onclick="doOpen('inject.html', '_blank');">Original Document</div> |
| Expected result: open successfully in InAppBrowser without text "Style updated from..." |
| |
| <p/> |
| <div class="btn large" onclick="openWithStyle('inject.html','inject.css');">CSS File Injection</div> |
| Expected result: open successfully in InAppBrowser with "Style updated from file". |
| |
| <p/> |
| <div class="btn large" onclick="openWithStyle('inject.html','inject.css', true);">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" onclick="openWithStyle('inject.html');">CSS Literal Injection</div> |
| Expected result: open successfully in InAppBrowser with "Style updated from literal". |
| |
| <p/> |
| <div class="btn large" onclick="openWithStyle('inject.html', null, true);">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" onclick="openWithScript('inject.html', 'inject.js');">Script File Injection</div> |
| Expected result: open successfully in InAppBrowser with text "Script file successfully injected" |
| |
| <p/> |
| <div class="btn large" onclick="openWithScript('inject.html', 'inject.js', true);">Script File Injection (callback)</div> |
| Expected result: open successfully in InAppBrowser with text "InAppBrowser - Script / Style Injection Test" and alert dialog with the text "Results verified". |
| |
| <p/> |
| <div class="btn large" onclick="openWithScript('inject.html');">Script Literal Injection</div> |
| Expected result: open successfully in InAppBrowser with the text "abc" in small font in the top left corner. |
| |
| <p/> |
| <div class="btn large" onclick="openWithScript('inject.html', null, true);">Script Literal Injection (callback)</div> |
| Expected result: open successfully in InAppBrowser with text "InAppBrowser - Script / Style Injection Test" and alert dialog with the text "Results verified". |
| |
| <h1>Open Hidden </h1> |
| <div class="btn large" onclick="openHidden('http://google.com',true);">create hidden</div> |
| Expected result: no additional browser window. Alert appears with the text "background window loaded". |
| |
| <p/> |
| <div class="btn large" onclick="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" onclick="closeHidden();">close hidden</div> |
| Expected result: no output. But click on "show hidden" again and nothing should be shown. |
| |
| <p/> |
| <div class="btn large" onclick="openHidden('http://google.com',false);">google.com not hidden</div> |
| Expected result: open successfully in InAppBrowser to www.google.com |
| |
| <h1>Clearing Cache</h1> |
| |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_blank', 'clearcache=yes');">Clear Browser Cache</div> |
| Expected result: ? |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('http://www.google.com', '_blank', 'clearsessioncache=yes');">Clear Session Cache</div> |
| Expected result: ? |
| |
| <h1>Video tag</h1> |
| |
| <div class="btn large" onclick="doOpen('video.html', '_blank');">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" onclick="doOpen('local.html#anchor1', '_blank');">Anchor1</div> |
| Expected result: open successfully in InAppBrowser to the local page, scrolled to the top. |
| |
| <p/> |
| <div class="btn large" onclick="doOpen('local.html#anchor2', '_blank');">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" onclick="backHome();">Back</div> |
| |
| </body> |
| </html> |