diff --git a/docs/inappbrowser.md b/docs/inappbrowser.md new file mode 100644 index 0000000..abe3b4d --- /dev/null +++ b/docs/inappbrowser.md @@ -0,0 +1,434 @@ +--- +license: 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. +--- + +InAppBrowser +============ + +> The InAppBrowser is a web-browser that is shown in your app when you use the `window.open` call. + + var ref = window.open('http://apache.org', '_blank', 'location=yes'); + +Description +----------- + +The object returned from a call to `window.open`. + +Methods +---------- + +- addEventListener +- removeEventListener +- close + +Permissions +----------- + +### Android + +#### app/res/xml/config.xml + + + +### iOS + +#### config.xml + + + + +### Windows Phone 7 + 8 + +#### config.xml + + + + + +addEventListener +================ + +> Adds a listener for an event from the InAppBrowser. + + ref.addEventListener(eventname, callback); + +- __ref:__ reference to the InAppBrowser window (`InAppBrowser`) +- __eventname:__ the event to listen for (`String`) + + loadstart - event fired when the InAppBrowser starts to load a URL + loadstop - event fired when the InAppBrowser finished loading a URL + loaderror - event fired when the InAppBrowser encounters an error loading a URL + exit - event fired when the InAppBrowser window is closed + +- __callback:__ the function that is called when the event is fired. +The function is passed an `InAppBrowserEvent` object. + +Supported Platforms +------------------- + +- Android +- iOS +- Windows Phone 7 + 8 + +Quick Example +------------- + + var ref = window.open('http://apache.org', '_blank', 'location=yes'); + ref.addEventListener('loadstart', function() { alert(event.url); }); + +Full Example +------------ + + + + + InAppBrowser.addEventListener Example + + + + + + + + +removeEventListener +=================== + +> Removes a listener for an event from the InAppBrowser. + + ref.removeEventListener(eventname, callback); + +- __ref:__ reference to the InAppBrowser window (`InAppBrowser`) +- __eventname:__ the event to stop listening for (`String`) + + loadstart - event fired when the InAppBrowser starts to load a URL + loadstop - event fired when the InAppBrowser finished loading a URL + loaderror - event fired when the InAppBrowser encounters an error loading a URL + exit - event fired when the InAppBrowser window is closed + +- __callback:__ the function that was to be called when the event is fired. +The function is passed an `InAppBrowserEvent` object. + +Supported Platforms +------------------- + +- Android +- iOS +- Windows Phone 7 + 8 + +Quick Example +------------- + + var ref = window.open('http://apache.org', '_blank', 'location=yes'); + var myCallback = function() { alert(event.url); } + ref.addEventListener('loadstart', myCallback); + ref.removeEventListener('loadstart', myCallback); + +Full Example +------------ + + + + + InAppBrowser.removeEventListener Example + + + + + + + + +close +===== + +> Closes the InAppBrowser window. + + ref.close(); + +- __ref:__ reference to the InAppBrowser window (`InAppBrowser`) + +Supported Platforms +------------------- + +- Android +- iOS +- Windows Phone 7 + 8 +- BlackBerry 10 + +Quick Example +------------- + + var ref = window.open('http://apache.org', '_blank', 'location=yes'); + ref.close(); + +Full Example +------------ + + + + + InAppBrowser.close Example + + + + + + + + +executeScript +============= + +> Injects JavaScript code into the InAppBrowser window + + ref.executeScript(details, callback); + +- __ref:__ reference to the InAppBrowser window (`InAppBrowser`) +- __injectDetails:__ details of the script ot run (`Object`) + - Supported keys: (exactly one of "file" or "code" should be present) + + "file" - URL of the script to inject + "code" - Text of the script to inject + +- __callback:__ the function that is to be called in the Cordova application after the JavaScript code is injected. + - If the injected script is of type "code", then the callback will be called with a single argument, which is + the return value of the script, wrapped in an Array. (For multi-line scripts, this is the return value of the + last statement, or the last expression evaluated.) + +Supported Platforms +------------------- + +- Android +- iOS + +Quick Example +------------- + + var ref = window.open('http://apache.org', '_blank', 'location=yes'); + ref.addEventListener('loadstop', function() { + ref.executeSript({file: "myscript.js"}); + }); + +Full Example +------------ + + + + + InAppBrowser.executeScript Example + + + + + + + + +insertCSS +========= + +> Injects CSS into the InAppBrowser window + + ref.insertCSS(details, callback); + +- __ref:__ reference to the InAppBrowser window (`InAppBrowser`) +- __injectDetails:__ details of the script ot run (`Object`) + - Supported keys: (exactly one of "file" or "code" should be present) + + "file" - URL of the stylesheet to inject + "code" - Text of the stylesheet to inject + +- __callback:__ the function that is to be called in the Cordova application after the CSS is injected. + +Supported Platforms +------------------- + +- Android +- iOS + +Quick Example +------------- + + var ref = window.open('http://apache.org', '_blank', 'location=yes'); + ref.addEventListener('loadstop', function() { + ref.insertCSS({file: "mystyles.css"}); + }); + +Full Example +------------ + + + + + InAppBrowser.executeScript Example + + + + + + + + +InAppBrowserEvent +================= + +The object that is passed to the callback function from an addEventListener call on an InAppBrowser object. + +Properties +---------- + +- __type:__ the eventname (`String`) - one of loadstart, loadstop, loaderror or exit +- __url:__ the URL that was loaded (`String`) +- __code:__ the error code (`Number`) - only in the case of loaderror +- __message:__ the error message (`String`) - only in the case of loaderror diff --git a/docs/window.open.md b/docs/window.open.md new file mode 100644 index 0000000..60fb50e --- /dev/null +++ b/docs/window.open.md @@ -0,0 +1,95 @@ +--- +license: 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. +--- + +window.open +=========== + +Opens a URL in a new InAppBrowser instance, the current browser instance, or the system browser. + + var ref = window.open(url, target, options); + +- __ref:__ reference to the InAppBrowser window (`InAppBrowser`) +- __url:__ the URL to load (`String`). Call encodeURI() on this if you have Unicode characters in your URL. +- __target:__ the target to load the URL in (`String`) (Optional, Default: "_self") + + _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser + _blank - always open in the InAppBrowser + _system - always open in the system web browser + + +- __options:__ options for the InAppBrowser (`String`) (Optional, Default: "location=yes") + + The options string must not contain any blank space, each feature name and value must be separated by a comma. Feature names are case insensitive. Only the value below is supported on all platforms: + + - __location__ - set to 'yes' or 'no' to turn the location bar on or off for the InAppBrowser + + iOS only + -------- + - __enableViewportScale__ - set to 'yes' or 'no' to prevent viewport scaling through a meta tag (defaults to 'no') + - __mediaPlaybackRequiresUserAction__ - set to 'yes' or 'no' to not allow autoplayed HTML5 video (defaults to 'no') + - __allowInlineMediaPlayback__ - set to 'yes' or 'no' to allow inline HTML5 media playback, also, the video element in the HTML document must also include the webkit-playsinline attribute (defaults to 'no') + - __keyboardDisplayRequiresUserAction__ - set to 'yes' or 'no' to open the keyboard when form elements get focus via the JavaScript focus() call (defaults to 'yes') + - __suppressesIncrementalRendering__ - set to 'yes' or 'no' to wait until all new view content has been received before it is rendered (defaults to 'no') + - __presentationstyle__ - set to 'pagesheet', 'formsheet' or 'fullscreen' to set the [presentation style](http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalPresentationStyle) (defaults to 'fullscreen') + - __transitionstyle__ - set to 'fliphorizontal', 'crossdissolve' or 'coververtical' to set the [transition style](http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instp/UIViewController/modalTransitionStyle) (defaults to 'coververtical') + +Supported Platforms +------------------- + +- Android +- iOS +- BlackBerry 10 +- Windows Phone 7 + 8 + +Quick Example +------------- + + var ref = window.open('http://apache.org', '_blank', 'location=yes'); + var ref2 = window.open(encodeURI('http://ja.m.wikipedia.org/wiki/ハングル'), '_blank', 'location=yes'); + +Full Example +------------ + + + + + window.open Example + + + + + + + + diff --git a/test/.DS_Store b/test/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/test/.DS_Store differ diff --git a/test/cordova-incl.js b/test/cordova-incl.js new file mode 100644 index 0000000..dbcd1a6 --- /dev/null +++ b/test/cordova-incl.js @@ -0,0 +1,70 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +var PLAT; +if (/Android/.exec(navigator.userAgent)) { + PLAT = 'android'; +} else if (/(iPad)|(iPhone)|(iPod)/.exec(navigator.userAgent)) { + PLAT = 'ios'; +} else if (/(BB10)|(PlayBook)|(BlackBerry)/.exec(navigator.userAgent)) { + PLAT = 'blackberry'; +} + +var scripts = document.getElementsByTagName('script'); +var currentPath = scripts[scripts.length - 1].src; +var platformCordovaPath = currentPath.replace("cordova-incl.js", "cordova." + PLAT + ".js"); +var normalCordovaPath = currentPath.replace("cordova-incl.js", "cordova.js"); +var cordovaPath = normalCordovaPath; + +if (PLAT) { + // XHR to local file is an error on some platforms, windowsphone for one + try { + var xhr = new XMLHttpRequest(); + xhr.open("GET", platformCordovaPath, false); + xhr.onreadystatechange = function() { + + if (this.readyState == this.DONE && this.responseText.length > 0) { + if(parseInt(this.status) >= 400){ + cordovaPath = normalCordovaPath; + }else{ + cordovaPath = platformCordovaPath; + } + } + }; + xhr.send(null); + } + catch(e){ + cordovaPath = normalCordovaPath; + } // access denied! +} + +if (!window._doNotWriteCordovaScript) { + document.write(''); +} + +function backHome() { + if (window.device && device.platform && device.platform.toLowerCase() == 'android') { + navigator.app.backHistory(); + } + else { + window.history.go(-1); + } +} diff --git a/test/inappbrowser/index.html b/test/inappbrowser/index.html new file mode 100644 index 0000000..1840c17 --- /dev/null +++ b/test/inappbrowser/index.html @@ -0,0 +1,230 @@ + + + + + + + + + Cordova Mobile Spec + + + + + + + + +

InAppBrowser

+
+ Make sure http://www.google.com is white listed.
+ Make sure http://www.apple.com is not in the white list.
In iOS, starred * tests will leave the app with no way to return.
+

User-Agent:

+
+
Back
+

Local URL

+
Default: CordovaWebView
+
Target=Self: CordovaWebView
+
Target=System: Error
+
Target=Blank: InAppBrowser
+
Target=Random: InAppBrowser
+
Target=Random, no location bar: InAppBrowser
+

White Listed URL

+
Default: CordovaWebView*
+
Target=Self: CordovaWebView*
+
Target=System: System Browser
+
Target=Blank: InAppBrowser
+
Target=Random: InAppBrowser
+
Target=Random, no location bar: InAppBrowser
+

Non White Listed URL

+
Default: InAppBrowser
+
Target=Self: InAppBrowser
+
Target=System: System
+
Target=Blank: InAppBrowser
+
Target=Random: InAppBrowser
+
Target=Random, no location bar: InAppBrowser
+

Page with redirect

+
http://google.com (should 301)
+
http://www.zhihu.com/answer/16714076 (should 302)
+

PDF URL

+
Remote URL
+
Local URL
+

INVALID URL

+
Invalid Scheme
+
Invalid Host
+
Missing File
+

CSS / JS Injection

+
Original Document
+
CSS File Injection
+
CSS File Injection (CB)
+
CSS Literal Injection
+
CSS Literal Injection (CB)
+
Script File Injection
+
Script File Injection (CB)
+
Script Literal Injection
+
Script Literal Injection (CB)
+

Back
+ + diff --git a/test/inappbrowser/inject.css b/test/inappbrowser/inject.css new file mode 100644 index 0000000..8e9904d --- /dev/null +++ b/test/inappbrowser/inject.css @@ -0,0 +1,3 @@ +#style-update-file { + display: block !important; +} diff --git a/test/inappbrowser/inject.html b/test/inappbrowser/inject.html new file mode 100644 index 0000000..0f1efdd --- /dev/null +++ b/test/inappbrowser/inject.html @@ -0,0 +1,43 @@ + + + + + + + + + Cordova Mobile Spec + + + +

InAppBrowser - Script / Style Injection Test

+ + + + + diff --git a/test/inappbrowser/inject.js b/test/inappbrowser/inject.js new file mode 100644 index 0000000..982c8bd --- /dev/null +++ b/test/inappbrowser/inject.js @@ -0,0 +1,2 @@ +var d = document.getElementById("header") +d.innerHTML = "Script file successfully injected"; diff --git a/test/inappbrowser/local.html b/test/inappbrowser/local.html new file mode 100644 index 0000000..d5edbf9 --- /dev/null +++ b/test/inappbrowser/local.html @@ -0,0 +1,51 @@ + + + + + + + + + Cordova Mobile Spec + + + + +

InAppBrowser - Local URL

+
+ You have successfully loaded a local URL +
+
User-Agent =
+
Visit Google
+
Visit Yahoo
+
Check out my remote PDF
+
Check out my local PDF
+

Back
+ + + diff --git a/test/inappbrowser/local.pdf b/test/inappbrowser/local.pdf new file mode 100644 index 0000000..b54f1b7 Binary files /dev/null and b/test/inappbrowser/local.pdf differ diff --git a/test/index.html b/test/index.html new file mode 100644 index 0000000..2c5447b --- /dev/null +++ b/test/index.html @@ -0,0 +1,65 @@ + + + + + + + + + Cordova Mobile Spec + + + + + + +

Apache Cordova Tests

+
+

Platform:

+

Version:

+

UUID:

+

Name:

+

Model:

+

Width: , Height: + , Color Depth:

+

User-Agent:

+
+ Automatic Test + Accelerometer + Audio Play/Record + Battery + Camera + Compass + Contacts + Events + Location + Lazy Loading of cordova-incl.js + Misc Content + Network + Notification + Splashscreen + Web SQL + Local Storage + Benchmarks + In App Browser + + diff --git a/test/main.js b/test/main.js new file mode 100644 index 0000000..66c1bd3 --- /dev/null +++ b/test/main.js @@ -0,0 +1,163 @@ +/* + * + * 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("platform").innerHTML = device.platform; + document.getElementById("version").innerHTML = device.version; + document.getElementById("uuid").innerHTML = device.uuid; + document.getElementById("name").innerHTML = device.name; + 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; +} diff --git a/test/master.css b/test/master.css new file mode 100644 index 0000000..e93c937 --- /dev/null +++ b/test/master.css @@ -0,0 +1,164 @@ +/* + * + * 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%; + }