231 lines
12 KiB
HTML
231 lines
12 KiB
HTML
<!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));
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
</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>
|
|
<h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
|
|
</body>
|
|
</html>
|