Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c98bc5b3f | ||
|
|
c5061ec333 | ||
|
|
932f078e2d | ||
|
|
1c32236353 | ||
|
|
34c29dc2ec | ||
|
|
aa6c1519d2 | ||
|
|
2fc9f3da1f | ||
|
|
bddf86c3ce | ||
|
|
25f306d11e | ||
|
|
04de070dcd | ||
|
|
22c7a0e51e | ||
|
|
9399ed3955 | ||
|
|
749d55c676 | ||
|
|
fceea502a3 | ||
|
|
aa9a5db941 | ||
|
|
e282cc9e38 | ||
|
|
7dbad601f0 | ||
|
|
5680f18bb4 | ||
|
|
a5dedae631 | ||
|
|
d0dd10103c | ||
|
|
497a23efc7 | ||
|
|
6f373f7ed9 | ||
|
|
300f1e782e | ||
|
|
4d3c7b17d2 | ||
|
|
a5201cc1e3 | ||
|
|
942d17981e | ||
|
|
17ba417572 | ||
|
|
77085aa547 | ||
|
|
26702cb072 | ||
|
|
39e64c988a | ||
|
|
cd31b3a64d | ||
|
|
4c07917c0a | ||
|
|
24e6a1feeb | ||
|
|
b62b9edde3 | ||
|
|
985d94ee00 | ||
|
|
e807bc3dc0 | ||
|
|
0ce0eed585 | ||
|
|
736c8ddec0 | ||
|
|
9206d82df4 | ||
|
|
bc554fdf95 | ||
|
|
43f8935541 | ||
|
|
2136cad49a | ||
|
|
9795b2e9dc | ||
|
|
255c5269c3 | ||
|
|
21fe13e809 | ||
|
|
3f9af4fd88 | ||
|
|
57d14da151 | ||
|
|
21a1638ccf | ||
|
|
b0bdb1088b | ||
|
|
6163f17aeb | ||
|
|
176890f305 | ||
|
|
2bd006b71e | ||
|
|
aac2db29b5 | ||
|
|
97c6f2ba8a | ||
|
|
f75b30857b | ||
|
|
25d152b578 | ||
|
|
4aeaf81e1e | ||
|
|
20611efe67 | ||
|
|
e819041fd4 | ||
|
|
034b599315 | ||
|
|
f448ce88ab | ||
|
|
ea239151d2 | ||
|
|
496ecc720f | ||
|
|
30525d545a | ||
|
|
8a549547cb | ||
|
|
65ee3d142f | ||
|
|
fadb170e50 | ||
|
|
9768ec2ef0 | ||
|
|
d2b644e5d5 | ||
|
|
e5101ba8e1 | ||
|
|
d49d6ec62f | ||
|
|
a8060219d5 | ||
|
|
e5868f8ecb | ||
|
|
b3348cff6c | ||
|
|
aa81c3267a | ||
|
|
a8f79e1fd6 | ||
|
|
c7972b6cff | ||
|
|
ce7a796cb0 | ||
|
|
a76a0a3920 | ||
|
|
5ef5171003 | ||
|
|
8a6bc01814 | ||
|
|
8df4b7d03b | ||
|
|
8cd786b603 | ||
|
|
ef5eddac9a | ||
|
|
4d4d479b3c | ||
|
|
3d8b04f982 | ||
|
|
12bc5d7d8b | ||
|
|
e5862bf820 |
5
NOTICE
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
Apache Cordova
|
||||||
|
Copyright 2012 The Apache Software Foundation
|
||||||
|
|
||||||
|
This product includes software developed at
|
||||||
|
The Apache Software Foundation (http://www.apache.org/).
|
||||||
25
README.md
@@ -1,5 +1,22 @@
|
|||||||
cordova-plugin-inappbrowser
|
<!---
|
||||||
-----------------------------
|
license: Licensed to the Apache Software Foundation (ASF) under one
|
||||||
To install this plugin, follow the [Command-line Interface Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
|
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
|
||||||
|
|
||||||
If you are not using the Cordova Command-line Interface, follow [Using Plugman to Manage Plugins](http://cordova.apache.org/docs/en/edge/plugin_ref_plugman.md.html).
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.inappbrowser
|
||||||
|
|
||||||
|
Plugin documentation: [doc/index.md](doc/index.md)
|
||||||
|
|||||||
@@ -32,3 +32,68 @@
|
|||||||
* Rename CHANGELOG.md -> RELEASENOTES.md
|
* Rename CHANGELOG.md -> RELEASENOTES.md
|
||||||
* [CB-4792] Added keepCallback to the show function.
|
* [CB-4792] Added keepCallback to the show function.
|
||||||
* [CB-4752] Incremented plugin version on dev branch.
|
* [CB-4752] Incremented plugin version on dev branch.
|
||||||
|
|
||||||
|
### 0.2.3 (Oct 9, 2013)
|
||||||
|
* [CB-4915] Incremented plugin version on dev branch.
|
||||||
|
* [CB-4926] Fixes inappbrowser plugin loading for windows8
|
||||||
|
|
||||||
|
### 0.2.4 (Oct 28, 2013)
|
||||||
|
* CB-5128: added repo + issue tag to plugin.xml for inappbrowser plugin
|
||||||
|
* CB-4995 Fix crash when WebView is quickly opened then closed.
|
||||||
|
* CB-4930 - iOS - InAppBrowser should take into account the status bar
|
||||||
|
* [CB-5010] Incremented plugin version on dev branch.
|
||||||
|
* [CB-5010] Updated version and RELEASENOTES.md for release 0.2.3
|
||||||
|
* CB-4858 - Run IAB methods on the UI thread.
|
||||||
|
* CB-4858 Convert relative URLs to absolute URLs in JS
|
||||||
|
* CB-3747 Fix back button having different dismiss logic from the close button.
|
||||||
|
* CB-5021 Expose closeDialog() as a public function and make it safe to call multiple times.
|
||||||
|
* CB-5021 Make it safe to call close() multiple times
|
||||||
|
|
||||||
|
### 0.2.5 (Dec 4, 2013)
|
||||||
|
* Remove merge conflict tag
|
||||||
|
* [CB-4724] fixed UriFormatException
|
||||||
|
* add ubuntu platform
|
||||||
|
* CB-3420 WP feature hidden=yes implemented
|
||||||
|
* Added amazon-fireos platform. Change to use amazon-fireos as the platform if user agent string contains 'cordova-amazon-fireos'
|
||||||
|
|
||||||
|
### 0.3.0 (Jan 02, 2014)
|
||||||
|
* CB-5592 Android: Add MIME type to Intent when opening file:/// URLs
|
||||||
|
* CB-5594 iOS: Add disallowoverscroll option.
|
||||||
|
* CB-5658 Add doc/index.md for InAppBrowser plugin
|
||||||
|
* CB-5595 Add toolbarposition=top option.
|
||||||
|
* Apply CB-5193 to InAppBrowser (Fix DB quota exception)
|
||||||
|
* CB-5593 iOS: Make InAppBrowser localizable
|
||||||
|
* CB-5591 Change window.escape to encodeURIComponent
|
||||||
|
|
||||||
|
### 0.3.1 (Feb 05, 2014)
|
||||||
|
* CB-5756: Android: Use WebView.evaluateJavascript for script injection on Android 4.4+
|
||||||
|
* Didn't test on ICS or lower, getDrawable isn't supported until Jellybean
|
||||||
|
* add ubuntu platform
|
||||||
|
* Adding drawables to the inAppBrowser. This doesn't look quite right, but it's a HUGE improvement over the previous settings
|
||||||
|
* CB-5756: Android: Use WebView.evaluateJavascript for script injection on Android 4.4+
|
||||||
|
* Remove alive from InAppBrowser.js since it didn't catch the case where the browser is closed by the user.
|
||||||
|
* CB-5733 Fix IAB.close() not working if called before show() animation is done
|
||||||
|
|
||||||
|
### 0.3.2 (Feb 26, 2014)
|
||||||
|
* Validate that callbackId is correctly formed
|
||||||
|
* CB-6035 Move js-module so it is not loaded on unsupported platforms
|
||||||
|
* Removed some iOS6 Deprecations
|
||||||
|
|
||||||
|
### 0.3.3 (Mar 5, 2014)
|
||||||
|
* CB-5534 Fix video/audio does not stop playing when browser is closed
|
||||||
|
* CB-6172 Fix broken install on case-sensitive file-systems
|
||||||
|
|
||||||
|
|
||||||
|
### 0.4.0 (Apr 17, 2014)
|
||||||
|
* CB-6360: [ios] Fix for crash on iOS < 6.0 (closes #37)
|
||||||
|
* CB-3324: [WP8] Add support for back-button inappbrowser [WP8] if there is no history -> InAppBrowser is closed
|
||||||
|
* [WP] await async calls, resolve warnings
|
||||||
|
* [WP] Make InAppBrowser work with embedded files, using system behavior
|
||||||
|
* CB-6402: [WP8] pass empty string instead of null for [optional] windowFeatures string
|
||||||
|
* CB-6422: [windows8] use cordova/exec/proxy
|
||||||
|
* CB-6389 CB-3617: Add clearcache and clearsessioncache options to iOS (like Android)
|
||||||
|
* Doc update: event name and example param (closes #31)
|
||||||
|
* CB-6253: [WP] Add Network Capability to WMAppManifest.xml
|
||||||
|
* CB-6212: [iOS] fix warnings compiled under arm64 64-bit
|
||||||
|
* CB-6218: Update docs for BB10
|
||||||
|
* CB-6460: Update license headers
|
||||||
|
|||||||
276
doc/index.md
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
# org.apache.cordova.inappbrowser
|
||||||
|
|
||||||
|
This plugin provides a web browser view that displays when calling `window.open()`, or when opening a link formed as `<a target="_blank">`.
|
||||||
|
|
||||||
|
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
||||||
|
|
||||||
|
__NOTE__: The InAppBrowser window behaves like a standard web browser,
|
||||||
|
and can't access Cordova APIs.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
cordova plugin add org.apache.cordova.inappbrowser
|
||||||
|
|
||||||
|
## 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 the URL contains Unicode characters.
|
||||||
|
|
||||||
|
- __target__: The target in which to load the URL, an optional parameter that defaults to `_self`. _(String)_
|
||||||
|
|
||||||
|
- `_self`: Opens in the Cordova WebView if the URL is in the white list, otherwise it opens in the `InAppBrowser`.
|
||||||
|
- `_blank`: Opens in the `InAppBrowser`.
|
||||||
|
- `_system`: Opens in the system's web browser.
|
||||||
|
|
||||||
|
- __options__: Options for the `InAppBrowser`. Optional, defaulting to: `location=yes`. _(String)_
|
||||||
|
|
||||||
|
The `options` string must not contain any blank space, and each feature's name/value pairs must be separated by a comma. Feature names are case insensitive. All platforms support the value below:
|
||||||
|
|
||||||
|
- __location__: Set to `yes` or `no` to turn the `InAppBrowser`'s location bar on or off.
|
||||||
|
|
||||||
|
Android only:
|
||||||
|
|
||||||
|
- __closebuttoncaption__: set to a string to use as the __Done__ button's caption.
|
||||||
|
- __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally.
|
||||||
|
- __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened
|
||||||
|
- __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened
|
||||||
|
|
||||||
|
iOS only:
|
||||||
|
|
||||||
|
- __closebuttoncaption__: set to a string to use as the __Done__ button's caption. Note that you need to localize this value yourself.
|
||||||
|
- __disallowoverscroll__: Set to `yes` or `no` (default is `no`). Turns on/off the UIWebViewBounce property.
|
||||||
|
- __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally.
|
||||||
|
- __clearcache__: set to `yes` to have the browser's cookie cache cleared before the new window is opened
|
||||||
|
- __clearsessioncache__: set to `yes` to have the session cookie cache cleared before the new window is opened
|
||||||
|
- __toolbar__: set to `yes` or `no` to turn the toolbar on or off for the InAppBrowser (defaults to `yes`)
|
||||||
|
- __enableViewportScale__: Set to `yes` or `no` to prevent viewport scaling through a meta tag (defaults to `no`).
|
||||||
|
- __mediaPlaybackRequiresUserAction__: Set to `yes` or `no` to prevent HTML5 audio or video from autoplaying (defaults to `no`).
|
||||||
|
- __allowInlineMediaPlayback__: Set to `yes` or `no` to allow in-line HTML5 media playback, displaying within the browser window rather than a device-specific playback interface. The HTML's `video` element must also include the `webkit-playsinline` attribute (defaults to `no`)
|
||||||
|
- __keyboardDisplayRequiresUserAction__: Set to `yes` or `no` to open the keyboard when form elements receive focus via JavaScript's `focus()` call (defaults to `yes`).
|
||||||
|
- __suppressesIncrementalRendering__: Set to `yes` or `no` to wait until all new view content is received before being 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`).
|
||||||
|
- __toolbarposition__: Set to `top` or `bottom` (default is `bottom`). Causes the toolbar to be at the top or bottom of the window.
|
||||||
|
|
||||||
|
### Supported Platforms
|
||||||
|
|
||||||
|
- Amazon Fire OS
|
||||||
|
- Android
|
||||||
|
- BlackBerry 10
|
||||||
|
- iOS
|
||||||
|
- Windows Phone 7 and 8
|
||||||
|
|
||||||
|
### 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');
|
||||||
|
|
||||||
|
## InAppBrowser
|
||||||
|
|
||||||
|
The object returned from a call to `window.open`.
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
- addEventListener
|
||||||
|
- removeEventListener
|
||||||
|
- close
|
||||||
|
- show
|
||||||
|
- executeScript
|
||||||
|
- insertCSS
|
||||||
|
|
||||||
|
## 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 fires when the `InAppBrowser` starts to load a URL.
|
||||||
|
- __loadstop__: event fires when the `InAppBrowser` finishes loading a URL.
|
||||||
|
- __loaderror__: event fires when the `InAppBrowser` encounters an error when loading a URL.
|
||||||
|
- __exit__: event fires when the `InAppBrowser` window is closed.
|
||||||
|
|
||||||
|
- __callback__: the function that executes when the event fires. The function is passed an `InAppBrowserEvent` object as a parameter.
|
||||||
|
|
||||||
|
### InAppBrowserEvent Properties
|
||||||
|
|
||||||
|
- __type__: the eventname, either `loadstart`, `loadstop`, `loaderror`, or `exit`. _(String)_
|
||||||
|
|
||||||
|
- __url__: the URL that was loaded. _(String)_
|
||||||
|
|
||||||
|
- __code__: the error code, only in the case of `loaderror`. _(Number)_
|
||||||
|
|
||||||
|
- __message__: the error message, only in the case of `loaderror`. _(String)_
|
||||||
|
|
||||||
|
|
||||||
|
### Supported Platforms
|
||||||
|
|
||||||
|
- Amazon Fire OS
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
- Windows Phone 7 and 8
|
||||||
|
|
||||||
|
### Quick Example
|
||||||
|
|
||||||
|
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
||||||
|
ref.addEventListener('loadstart', function(event) { alert(event.url); });
|
||||||
|
|
||||||
|
## 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 fires when the `InAppBrowser` starts to load a URL.
|
||||||
|
- __loadstop__: event fires when the `InAppBrowser` finishes loading a URL.
|
||||||
|
- __loaderror__: event fires when the `InAppBrowser` encounters an error loading a URL.
|
||||||
|
- __exit__: event fires when the `InAppBrowser` window is closed.
|
||||||
|
|
||||||
|
- __callback__: the function to execute when the event fires.
|
||||||
|
The function is passed an `InAppBrowserEvent` object.
|
||||||
|
|
||||||
|
### Supported Platforms
|
||||||
|
|
||||||
|
- Amazon Fire OS
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
- Windows Phone 7 and 8
|
||||||
|
|
||||||
|
### Quick Example
|
||||||
|
|
||||||
|
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
||||||
|
var myCallback = function(event) { alert(event.url); }
|
||||||
|
ref.addEventListener('loadstart', myCallback);
|
||||||
|
ref.removeEventListener('loadstart', myCallback);
|
||||||
|
|
||||||
|
## close
|
||||||
|
|
||||||
|
> Closes the `InAppBrowser` window.
|
||||||
|
|
||||||
|
ref.close();
|
||||||
|
|
||||||
|
- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_
|
||||||
|
|
||||||
|
### Supported Platforms
|
||||||
|
|
||||||
|
- Amazon Fire OS
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
- Windows Phone 7 and 8
|
||||||
|
|
||||||
|
### Quick Example
|
||||||
|
|
||||||
|
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
||||||
|
ref.close();
|
||||||
|
|
||||||
|
## show
|
||||||
|
|
||||||
|
> Displays an InAppBrowser window that was opened hidden. Calling this has no effect if the InAppBrowser was already visible.
|
||||||
|
|
||||||
|
ref.show();
|
||||||
|
|
||||||
|
- __ref__: reference to the InAppBrowser window (`InAppBrowser`)
|
||||||
|
|
||||||
|
### Supported Platforms
|
||||||
|
|
||||||
|
- Amazon Fire OS
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
|
||||||
|
### Quick Example
|
||||||
|
|
||||||
|
var ref = window.open('http://apache.org', '_blank', 'hidden=yes');
|
||||||
|
// some time later...
|
||||||
|
ref.show();
|
||||||
|
|
||||||
|
## executeScript
|
||||||
|
|
||||||
|
> Injects JavaScript code into the `InAppBrowser` window
|
||||||
|
|
||||||
|
ref.executeScript(details, callback);
|
||||||
|
|
||||||
|
- __ref__: reference to the `InAppBrowser` window. _(InAppBrowser)_
|
||||||
|
|
||||||
|
- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_
|
||||||
|
- __file__: URL of the script to inject.
|
||||||
|
- __code__: Text of the script to inject.
|
||||||
|
|
||||||
|
- __callback__: the function that executes after the JavaScript code is injected.
|
||||||
|
- If the injected script is of type `code`, the callback executes
|
||||||
|
with a single parameter, 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
|
||||||
|
|
||||||
|
- Amazon Fire OS
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
|
||||||
|
### Quick Example
|
||||||
|
|
||||||
|
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
||||||
|
ref.addEventListener('loadstop', function() {
|
||||||
|
ref.executeScript({file: "myscript.js"});
|
||||||
|
});
|
||||||
|
|
||||||
|
## insertCSS
|
||||||
|
|
||||||
|
> Injects CSS into the `InAppBrowser` window.
|
||||||
|
|
||||||
|
ref.insertCSS(details, callback);
|
||||||
|
|
||||||
|
- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_
|
||||||
|
|
||||||
|
- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_
|
||||||
|
- __file__: URL of the stylesheet to inject.
|
||||||
|
- __code__: Text of the stylesheet to inject.
|
||||||
|
|
||||||
|
- __callback__: the function that executes after the CSS is injected.
|
||||||
|
|
||||||
|
### Supported Platforms
|
||||||
|
|
||||||
|
- Amazon Fire OS
|
||||||
|
- Android
|
||||||
|
- iOS
|
||||||
|
|
||||||
|
### Quick Example
|
||||||
|
|
||||||
|
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
||||||
|
ref.addEventListener('loadstop', function() {
|
||||||
|
ref.insertCSS({file: "mystyles.css"});
|
||||||
|
});
|
||||||
|
|
||||||
@@ -1,427 +0,0 @@
|
|||||||
---
|
|
||||||
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 displays in the app when calling `window.open`.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
<plugin name="InAppBrowser" value="org.apache.cordova.InAppBrowser" />
|
|
||||||
|
|
||||||
### iOS
|
|
||||||
|
|
||||||
#### config.xml
|
|
||||||
|
|
||||||
<plugin name="InAppBrowser" value="CDVInAppBrowser" />
|
|
||||||
|
|
||||||
### Windows Phone 7 + 8
|
|
||||||
|
|
||||||
#### config.xml
|
|
||||||
|
|
||||||
<plugin name="InAppBrowser" />
|
|
||||||
|
|
||||||
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 fires when the `InAppBrowser` starts to load a URL.
|
|
||||||
- __loadstop__: event fires when the `InAppBrowser` finishes loading a URL.
|
|
||||||
- __loaderror__: event fires when the `InAppBrowser` encounters an error when loading a URL.
|
|
||||||
- __exit__: event fires when the `InAppBrowser` window is closed.
|
|
||||||
|
|
||||||
- __callback__: the function that executes when the event fires. The function is passed an `InAppBrowserEvent` object as a parameter.
|
|
||||||
|
|
||||||
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
|
|
||||||
------------
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>InAppBrowser.addEventListener Example</title>
|
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
|
|
||||||
// Wait for device API libraries to load
|
|
||||||
//
|
|
||||||
document.addEventListener("deviceready", onDeviceReady, false);
|
|
||||||
|
|
||||||
// device APIs are available
|
|
||||||
//
|
|
||||||
function onDeviceReady() {
|
|
||||||
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
|
||||||
ref.addEventListener('loadstart', function(event) { alert('start: ' + event.url); });
|
|
||||||
ref.addEventListener('loadstop', function(event) { alert('stop: ' + event.url); });
|
|
||||||
ref.addEventListener('loaderror', function(event) { alert('error: ' + event.message); });
|
|
||||||
ref.addEventListener('exit', function(event) { alert(event.type); });
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
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 fires when the `InAppBrowser` starts to load a URL.
|
|
||||||
- __loadstop__: event fires when the `InAppBrowser` finishes loading a URL.
|
|
||||||
- __loaderror__: event fires when the `InAppBrowser` encounters an error loading a URL.
|
|
||||||
- __exit__: event fires when the `InAppBrowser` window is closed.
|
|
||||||
|
|
||||||
- __callback__: the function to execute when the event fires.
|
|
||||||
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
|
|
||||||
------------
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>InAppBrowser.removeEventListener Example</title>
|
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
|
|
||||||
// Wait for device API libraries to load
|
|
||||||
//
|
|
||||||
document.addEventListener("deviceready", onDeviceReady, false);
|
|
||||||
|
|
||||||
// Global InAppBrowser reference
|
|
||||||
var iabRef = null;
|
|
||||||
|
|
||||||
function iabLoadStart(event) {
|
|
||||||
alert(event.type + ' - ' + event.url);
|
|
||||||
}
|
|
||||||
|
|
||||||
function iabLoadStop(event) {
|
|
||||||
alert(event.type + ' - ' + event.url);
|
|
||||||
}
|
|
||||||
|
|
||||||
function iabLoadError(event) {
|
|
||||||
alert(event.type + ' - ' + event.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
function iabClose(event) {
|
|
||||||
alert(event.type);
|
|
||||||
iabRef.removeEventListener('loadstart', iabLoadStart);
|
|
||||||
iabRef.removeEventListener('loadstop', iabLoadStop);
|
|
||||||
iabRef.removeEventListener('loaderror', iabLoadError);
|
|
||||||
iabRef.removeEventListener('exit', iabClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
// device APIs are available
|
|
||||||
//
|
|
||||||
function onDeviceReady() {
|
|
||||||
iabRef = window.open('http://apache.org', '_blank', 'location=yes');
|
|
||||||
iabRef.addEventListener('loadstart', iabLoadStart);
|
|
||||||
iabRef.addEventListener('loadstop', iabLoadStop);
|
|
||||||
iabRef.removeEventListener('loaderror', iabLoadError);
|
|
||||||
iabRef.addEventListener('exit', iabClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
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
|
|
||||||
------------
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>InAppBrowser.close Example</title>
|
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
|
|
||||||
// Wait for device API libraries to load
|
|
||||||
//
|
|
||||||
document.addEventListener("deviceready", onDeviceReady, false);
|
|
||||||
|
|
||||||
// device APIs are available
|
|
||||||
//
|
|
||||||
function onDeviceReady() {
|
|
||||||
var ref = window.open('http://apache.org', '_blank', 'location=yes');
|
|
||||||
// close InAppBrowser after 5 seconds
|
|
||||||
setTimeout(function() {
|
|
||||||
ref.close();
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
executeScript
|
|
||||||
=============
|
|
||||||
|
|
||||||
> Injects JavaScript code into the `InAppBrowser` window
|
|
||||||
|
|
||||||
ref.executeScript(details, callback);
|
|
||||||
|
|
||||||
- __ref__: reference to the `InAppBrowser` window. _(InAppBrowser)_
|
|
||||||
- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_
|
|
||||||
- __file__: URL of the script to inject.
|
|
||||||
- __code__: Text of the script to inject.
|
|
||||||
- __callback__: the function that executes after the JavaScript code is injected.
|
|
||||||
- If the injected script is of type `code`, the callback executes
|
|
||||||
with a single parameter, 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
|
|
||||||
------------
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>InAppBrowser.executeScript Example</title>
|
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
|
|
||||||
// Wait for device API libraries to load
|
|
||||||
//
|
|
||||||
document.addEventListener("deviceready", onDeviceReady, false);
|
|
||||||
|
|
||||||
// Global InAppBrowser reference
|
|
||||||
var iabRef = null;
|
|
||||||
|
|
||||||
// Inject our custom JavaScript into the InAppBrowser window
|
|
||||||
//
|
|
||||||
function replaceHeaderImage() {
|
|
||||||
iabRef.executeScript({
|
|
||||||
code: "var img=document.querySelector('#header img'); img.src='http://cordova.apache.org/images/cordova_bot.png';"
|
|
||||||
}, function() {
|
|
||||||
alert("Image Element Successfully Hijacked");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function iabClose(event) {
|
|
||||||
iabRef.removeEventListener('loadstop', replaceHeaderImage);
|
|
||||||
iabRef.removeEventListener('exit', iabClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
// device APIs are available
|
|
||||||
//
|
|
||||||
function onDeviceReady() {
|
|
||||||
iabRef = window.open('http://apache.org', '_blank', 'location=yes');
|
|
||||||
iabRef.addEventListener('loadstop', replaceHeaderImage);
|
|
||||||
iabRef.addEventListener('exit', iabClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
insertCSS
|
|
||||||
=========
|
|
||||||
|
|
||||||
> Injects CSS into the `InAppBrowser` window.
|
|
||||||
|
|
||||||
ref.insertCSS(details, callback);
|
|
||||||
|
|
||||||
- __ref__: reference to the `InAppBrowser` window _(InAppBrowser)_
|
|
||||||
- __injectDetails__: details of the script to run, specifying either a `file` or `code` key. _(Object)_
|
|
||||||
- __file__: URL of the stylesheet to inject.
|
|
||||||
- __code__: Text of the stylesheet to inject.
|
|
||||||
- __callback__: the function that executes 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
|
|
||||||
------------
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>InAppBrowser.executeScript Example</title>
|
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
|
|
||||||
// Wait for device API libraries to load
|
|
||||||
//
|
|
||||||
document.addEventListener("deviceready", onDeviceReady, false);
|
|
||||||
|
|
||||||
// Global InAppBrowser reference
|
|
||||||
var iabRef = null;
|
|
||||||
|
|
||||||
// Inject our custom CSS into the InAppBrowser window
|
|
||||||
//
|
|
||||||
function changeBackgroundColor() {
|
|
||||||
iabRef.executeScript({
|
|
||||||
code: "body { background: #ffff00"
|
|
||||||
}, function() {
|
|
||||||
alert("Styles Altered");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function iabClose(event) {
|
|
||||||
iabRef.removeEventListener('loadstop', changeBackgroundColor);
|
|
||||||
iabRef.removeEventListener('exit', iabClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
// device APIs are available
|
|
||||||
//
|
|
||||||
function onDeviceReady() {
|
|
||||||
iabRef = window.open('http://apache.org', '_blank', 'location=yes');
|
|
||||||
iabRef.addEventListener('loadstop', changeBackgroundColor);
|
|
||||||
iabRef.addEventListener('exit', iabClose);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
||||||
InAppBrowserEvent
|
|
||||||
=================
|
|
||||||
|
|
||||||
The object that is passed to the callback function from an
|
|
||||||
`addEventListener` call on an `InAppBrowser` object.
|
|
||||||
|
|
||||||
Properties
|
|
||||||
----------
|
|
||||||
|
|
||||||
- __type__: the eventname, either `loadstart`, `loadstop`, `loaderror`, or `exit`. _(String)_
|
|
||||||
- __url__: the URL that was loaded. _(String)_
|
|
||||||
- __code__: the error code, only in the case of `loaderror`. _(Number)_
|
|
||||||
- __message__: the error message, only in the case of `loaderror`. _(String)_
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
---
|
|
||||||
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 the URL contains Unicode characters.
|
|
||||||
- __target__: The target in which to load the URL, an optional parameter that defaults to `_self`. _(String)_
|
|
||||||
|
|
||||||
- `_self`: Opens in the Cordova WebView if the URL is in the white list, otherwise it opens in the `InAppBrowser`.
|
|
||||||
- `_blank`: Opens in the `InAppBrowser`.
|
|
||||||
- `_system`: Opens in the system's web browser.
|
|
||||||
|
|
||||||
- __options__: Options for the `InAppBrowser`. Optional, defaulting to: `location=yes`. _(String)_
|
|
||||||
|
|
||||||
The `options` string must not contain any blank space, and each feature's name/value pairs must be separated by a comma. Feature names are case insensitive. All platforms support the value below:
|
|
||||||
|
|
||||||
- __location__: Set to `yes` or `no` to turn the `InAppBrowser`'s location bar on or off.
|
|
||||||
|
|
||||||
Android only
|
|
||||||
------------
|
|
||||||
- __closebuttoncaption__ - set to a string that will be the caption for the "Done" button.
|
|
||||||
|
|
||||||
iOS only
|
|
||||||
--------
|
|
||||||
- __closebuttoncaption__ - set to a string that will be the caption for the "Done" button. Note that you will have to localize this value yourself.
|
|
||||||
- __toolbar__ - set to 'yes' or 'no' to turn the toolbar on or off for the InAppBrowser (defaults to 'yes')
|
|
||||||
- __enableViewportScale__: Set to `yes` or `no` to prevent viewport scaling through a meta tag (defaults to `no`).
|
|
||||||
- __mediaPlaybackRequiresUserAction__: Set to `yes` or `no` to prevent HTML5 audio or video from autoplaying (defaults to `no`).
|
|
||||||
- __allowInlineMediaPlayback__: Set to `yes` or `no` to allow inline HTML5 media playback, displaying within the browser window rather than a device-specific playback interface. The HTML's `video` element must also include the `webkit-playsinline` attribute (defaults to `no`)
|
|
||||||
- __keyboardDisplayRequiresUserAction__: Set to `yes` or `no` to open the keyboard when form elements receive focus via JavaScript's `focus()` call (defaults to `yes`).
|
|
||||||
- __suppressesIncrementalRendering__: Set to `yes` or `no` to wait until all new view content is received before being 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
|
|
||||||
------------
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>window.open Example</title>
|
|
||||||
|
|
||||||
<script type="text/javascript" charset="utf-8" src="cordova-x.x.x.js"></script>
|
|
||||||
<script type="text/javascript" charset="utf-8">
|
|
||||||
|
|
||||||
// Wait for device API libraries to load
|
|
||||||
//
|
|
||||||
document.addEventListener("deviceready", onDeviceReady, false);
|
|
||||||
|
|
||||||
// device APIs are available
|
|
||||||
//
|
|
||||||
function onDeviceReady() {
|
|
||||||
// external url
|
|
||||||
var ref = window.open(encodeURI('http://apache.org'), '_blank', 'location=yes');
|
|
||||||
// relative document
|
|
||||||
ref = window.open('next.html', '_self');
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
106
plugin.xml
@@ -1,20 +1,43 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
||||||
id="org.apache.cordova.inappbrowser"
|
id="org.apache.cordova.inappbrowser"
|
||||||
version="0.2.2">
|
version="0.4.0">
|
||||||
|
|
||||||
<name>InAppBrowser</name>
|
<name>InAppBrowser</name>
|
||||||
<description>Cordova InAppBrowser Plugin</description>
|
<description>Cordova InAppBrowser Plugin</description>
|
||||||
<license>Apache 2.0</license>
|
<license>Apache 2.0</license>
|
||||||
<keywords>cordova,in,app,browser,inappbrowser</keywords>
|
<keywords>cordova,in,app,browser,inappbrowser</keywords>
|
||||||
|
<repo>https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git</repo>
|
||||||
|
<issue>https://issues.apache.org/jira/browse/CB/component/12320641</issue>
|
||||||
|
|
||||||
|
<engines>
|
||||||
<js-module src="www/InAppBrowser.js" name="InAppBrowser">
|
<engine name="cordova" version=">=3.1.0" /><!-- Needs cordova/urlutil -->
|
||||||
<clobbers target="window.open" />
|
</engines>
|
||||||
</js-module>
|
|
||||||
|
|
||||||
<!-- android -->
|
<!-- android -->
|
||||||
<platform name="android">
|
<platform name="android">
|
||||||
|
<js-module src="www/inappbrowser.js" name="inappbrowser">
|
||||||
|
<clobbers target="window.open" />
|
||||||
|
</js-module>
|
||||||
<config-file target="res/xml/config.xml" parent="/*">
|
<config-file target="res/xml/config.xml" parent="/*">
|
||||||
<feature name="InAppBrowser">
|
<feature name="InAppBrowser">
|
||||||
<param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/>
|
<param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/>
|
||||||
@@ -22,11 +45,58 @@
|
|||||||
</config-file>
|
</config-file>
|
||||||
|
|
||||||
<source-file src="src/android/InAppBrowser.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
<source-file src="src/android/InAppBrowser.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
|
<source-file src="src/android/InAppBrowserDialog.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
<source-file src="src/android/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
<source-file src="src/android/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
|
|
||||||
|
<!-- drawable src/android/resources -->
|
||||||
|
<resource-file src="src/android/res/drawable-hdpi/ic_action_next_item.png" target="res/drawable-hdpi/ic_action_next_item.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-mdpi/ic_action_next_item.png" target="res/drawable-mdpi/ic_action_next_item.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xhdpi/ic_action_next_item.png" target="res/drawable-xhdpi/ic_action_next_item.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xxhdpi/ic_action_next_item.png" target="res/drawable-xxhdpi/ic_action_next_item.png" />
|
||||||
|
|
||||||
|
<resource-file src="src/android/res/drawable-hdpi/ic_action_previous_item.png" target="res/drawable-hdpi/ic_action_previous_item.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-mdpi/ic_action_previous_item.png" target="res/drawable-mdpi/ic_action_previous_item.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xhdpi/ic_action_previous_item.png" target="res/drawable-xhdpi/ic_action_previous_item.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xxhdpi/ic_action_previous_item.png" target="res/drawable-xxhdpi/ic_action_previous_item.png" />
|
||||||
|
|
||||||
|
<resource-file src="src/android/res/drawable-hdpi/ic_action_remove.png" target="res/drawable-hdpi/ic_action_remove.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-mdpi/ic_action_remove.png" target="res/drawable-mdpi/ic_action_remove.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xhdpi/ic_action_remove.png" target="res/drawable-xhdpi/ic_action_remove.png" />
|
||||||
|
<resource-file src="src/android/res/drawable-xxhdpi/ic_action_remove.png" target="res/drawable-xxhdpi/ic_action_remove.png" />
|
||||||
|
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
|
<!-- amazon-fireos -->
|
||||||
|
<platform name="amazon-fireos">
|
||||||
|
<js-module src="www/inappbrowser.js" name="inappbrowser">
|
||||||
|
<clobbers target="window.open" />
|
||||||
|
</js-module>
|
||||||
|
<config-file target="res/xml/config.xml" parent="/*">
|
||||||
|
<feature name="InAppBrowser">
|
||||||
|
<param name="android-package" value="org.apache.cordova.inappbrowser.InAppBrowser"/>
|
||||||
|
</feature>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<source-file src="src/amazon/InAppBrowser.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
|
<source-file src="src/amazon/InAppChromeClient.java" target-dir="src/org/apache/cordova/inappbrowser" />
|
||||||
|
</platform>
|
||||||
|
|
||||||
|
<!-- ubuntu -->
|
||||||
|
<platform name="ubuntu">
|
||||||
|
<js-module src="www/inappbrowser.js" name="inappbrowser">
|
||||||
|
<clobbers target="window.open" />
|
||||||
|
</js-module>
|
||||||
|
<header-file src="src/ubuntu/inappbrowser.h" />
|
||||||
|
<source-file src="src/ubuntu/inappbrowser.cpp" />
|
||||||
|
<resource-file src="src/ubuntu/InAppBrowser.qml" />
|
||||||
|
<resource-file src="src/ubuntu/close.png" />
|
||||||
|
</platform>
|
||||||
|
|
||||||
<!-- ios -->
|
<!-- ios -->
|
||||||
<platform name="ios">
|
<platform name="ios">
|
||||||
|
<js-module src="www/inappbrowser.js" name="inappbrowser">
|
||||||
|
<clobbers target="window.open" />
|
||||||
|
</js-module>
|
||||||
<config-file target="config.xml" parent="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
<feature name="InAppBrowser">
|
<feature name="InAppBrowser">
|
||||||
<param name="ios-package" value="CDVInAppBrowser" />
|
<param name="ios-package" value="CDVInAppBrowser" />
|
||||||
@@ -39,15 +109,15 @@
|
|||||||
<framework src="CoreGraphics.framework" />
|
<framework src="CoreGraphics.framework" />
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
<!-- blackberry10 -->
|
|
||||||
<!-- <platform name="blackberry10">
|
|
||||||
<config-file target="www/config.xml" parent="/widget">
|
|
||||||
<feature name="InAppBrowser" value="InAppBrowser"/>
|
|
||||||
</config-file>
|
|
||||||
</platform>
|
|
||||||
-->
|
|
||||||
<!-- wp7 -->
|
<!-- wp7 -->
|
||||||
<platform name="wp7">
|
<platform name="wp7">
|
||||||
|
<config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities">
|
||||||
|
<Capability Name="ID_CAP_NETWORKING"/>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<js-module src="www/inappbrowser.js" name="inappbrowser">
|
||||||
|
<clobbers target="window.open" />
|
||||||
|
</js-module>
|
||||||
<config-file target="config.xml" parent="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
<feature name="InAppBrowser">
|
<feature name="InAppBrowser">
|
||||||
<param name="wp-package" value="InAppBrowser"/>
|
<param name="wp-package" value="InAppBrowser"/>
|
||||||
@@ -59,6 +129,13 @@
|
|||||||
|
|
||||||
<!-- wp8 -->
|
<!-- wp8 -->
|
||||||
<platform name="wp8">
|
<platform name="wp8">
|
||||||
|
<config-file target="Properties/WMAppManifest.xml" parent="/Deployment/App/Capabilities">
|
||||||
|
<Capability Name="ID_CAP_NETWORKING"/>
|
||||||
|
</config-file>
|
||||||
|
|
||||||
|
<js-module src="www/inappbrowser.js" name="inappbrowser">
|
||||||
|
<clobbers target="window.open" />
|
||||||
|
</js-module>
|
||||||
<config-file target="config.xml" parent="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
<feature name="InAppBrowser">
|
<feature name="InAppBrowser">
|
||||||
<param name="wp-package" value="InAppBrowser"/>
|
<param name="wp-package" value="InAppBrowser"/>
|
||||||
@@ -70,6 +147,9 @@
|
|||||||
|
|
||||||
<!-- windows8 -->
|
<!-- windows8 -->
|
||||||
<platform name="windows8">
|
<platform name="windows8">
|
||||||
|
<js-module src="www/inappbrowser.js" name="inappbrowser">
|
||||||
|
<clobbers target="window.open" />
|
||||||
|
</js-module>
|
||||||
<js-module src="www/windows8/InAppBrowserProxy.js" name="InAppBrowserProxy">
|
<js-module src="www/windows8/InAppBrowserProxy.js" name="InAppBrowserProxy">
|
||||||
<merges target="" />
|
<merges target="" />
|
||||||
</js-module>
|
</js-module>
|
||||||
|
|||||||
769
src/amazon/InAppBrowser.java
Normal file
@@ -0,0 +1,769 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.inappbrowser;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.WindowManager.LayoutParams;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import com.amazon.android.webkit.AmazonWebChromeClient;
|
||||||
|
import com.amazon.android.webkit.AmazonGeolocationPermissions.Callback;
|
||||||
|
import com.amazon.android.webkit.AmazonJsPromptResult;
|
||||||
|
import com.amazon.android.webkit.AmazonWebSettings;
|
||||||
|
import com.amazon.android.webkit.AmazonWebStorage;
|
||||||
|
import com.amazon.android.webkit.AmazonWebView;
|
||||||
|
import com.amazon.android.webkit.AmazonWebViewClient;
|
||||||
|
import com.amazon.android.webkit.AmazonCookieManager;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import org.apache.cordova.CallbackContext;
|
||||||
|
import org.apache.cordova.Config;
|
||||||
|
import org.apache.cordova.CordovaArgs;
|
||||||
|
import org.apache.cordova.CordovaPlugin;
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.LOG;
|
||||||
|
import org.apache.cordova.PluginResult;
|
||||||
|
import org.apache.cordova.CordovaActivity;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
public class InAppBrowser extends CordovaPlugin {
|
||||||
|
|
||||||
|
private static final String NULL = "null";
|
||||||
|
protected static final String LOG_TAG = "InAppBrowser";
|
||||||
|
private static final String SELF = "_self";
|
||||||
|
private static final String SYSTEM = "_system";
|
||||||
|
// private static final String BLANK = "_blank";
|
||||||
|
private static final String EXIT_EVENT = "exit";
|
||||||
|
private static final String LOCATION = "location";
|
||||||
|
private static final String HIDDEN = "hidden";
|
||||||
|
private static final String LOAD_START_EVENT = "loadstart";
|
||||||
|
private static final String LOAD_STOP_EVENT = "loadstop";
|
||||||
|
private static final String LOAD_ERROR_EVENT = "loaderror";
|
||||||
|
private static final String CLOSE_BUTTON_CAPTION = "closebuttoncaption";
|
||||||
|
private static final String CLEAR_ALL_CACHE = "clearcache";
|
||||||
|
private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
|
||||||
|
|
||||||
|
private Dialog dialog;
|
||||||
|
private AmazonWebView inAppWebView;
|
||||||
|
private EditText edittext;
|
||||||
|
private CallbackContext callbackContext;
|
||||||
|
private boolean showLocationBar = true;
|
||||||
|
private boolean openWindowHidden = false;
|
||||||
|
private String buttonLabel = "Done";
|
||||||
|
private boolean clearAllCache= false;
|
||||||
|
private boolean clearSessionCache=false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the request and returns PluginResult.
|
||||||
|
*
|
||||||
|
* @param action The action to execute.
|
||||||
|
* @param args JSONArry of arguments for the plugin.
|
||||||
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
|
* @return A PluginResult object with a status and message.
|
||||||
|
*/
|
||||||
|
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
|
||||||
|
if (action.equals("open")) {
|
||||||
|
this.callbackContext = callbackContext;
|
||||||
|
final String url = args.getString(0);
|
||||||
|
String t = args.optString(1);
|
||||||
|
if (t == null || t.equals("") || t.equals(NULL)) {
|
||||||
|
t = SELF;
|
||||||
|
}
|
||||||
|
final String target = t;
|
||||||
|
final HashMap<String, Boolean> features = parseFeature(args.optString(2));
|
||||||
|
|
||||||
|
Log.d(LOG_TAG, "target = " + target);
|
||||||
|
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String result = "";
|
||||||
|
// SELF
|
||||||
|
if (SELF.equals(target)) {
|
||||||
|
Log.d(LOG_TAG, "in self");
|
||||||
|
// load in webview
|
||||||
|
if (url.startsWith("file://") || url.startsWith("javascript:")
|
||||||
|
|| Config.isUrlWhiteListed(url)) {
|
||||||
|
webView.loadUrl(url);
|
||||||
|
}
|
||||||
|
//Load the dialer
|
||||||
|
else if (url.startsWith(AmazonWebView.SCHEME_TEL))
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// load in InAppBrowser
|
||||||
|
else {
|
||||||
|
result = showWebPage(url, features);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SYSTEM
|
||||||
|
else if (SYSTEM.equals(target)) {
|
||||||
|
Log.d(LOG_TAG, "in system");
|
||||||
|
result = openExternal(url);
|
||||||
|
}
|
||||||
|
// BLANK - or anything else
|
||||||
|
else {
|
||||||
|
Log.d(LOG_TAG, "in blank");
|
||||||
|
result = showWebPage(url, features);
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result);
|
||||||
|
pluginResult.setKeepCallback(true);
|
||||||
|
callbackContext.sendPluginResult(pluginResult);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (action.equals("close")) {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
else if (action.equals("injectScriptCode")) {
|
||||||
|
String jsWrapper = null;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId());
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectScriptFile")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectStyleCode")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectStyleFile")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("show")) {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
|
||||||
|
pluginResult.setKeepCallback(true);
|
||||||
|
this.callbackContext.sendPluginResult(pluginResult);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the view navigates.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onReset() {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by AccelBroker when listener is to be shut down.
|
||||||
|
* Stop listener.
|
||||||
|
*/
|
||||||
|
public void onDestroy() {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inject an object (script or style) into the InAppBrowser AmazonWebView.
|
||||||
|
*
|
||||||
|
* This is a helper method for the inject{Script|Style}{Code|File} API calls, which
|
||||||
|
* provides a consistent method for injecting JavaScript code into the document.
|
||||||
|
*
|
||||||
|
* If a wrapper string is supplied, then the source string will be JSON-encoded (adding
|
||||||
|
* quotes) and wrapped using string formatting. (The wrapper string should have a single
|
||||||
|
* '%s' marker)
|
||||||
|
*
|
||||||
|
* @param source The source object (filename or script/style text) to inject into
|
||||||
|
* the document.
|
||||||
|
* @param jsWrapper A JavaScript string to wrap the source string in, so that the object
|
||||||
|
* is properly injected, or null if the source string is JavaScript text
|
||||||
|
* which should be executed directly.
|
||||||
|
*/
|
||||||
|
private void injectDeferredObject(String source, String jsWrapper) {
|
||||||
|
final String scriptToInject;
|
||||||
|
if (jsWrapper != null) {
|
||||||
|
org.json.JSONArray jsonEsc = new org.json.JSONArray();
|
||||||
|
jsonEsc.put(source);
|
||||||
|
String jsonRepr = jsonEsc.toString();
|
||||||
|
String jsonSourceString = jsonRepr.substring(1, jsonRepr.length()-1);
|
||||||
|
scriptToInject = String.format(jsWrapper, jsonSourceString);
|
||||||
|
} else {
|
||||||
|
scriptToInject = source;
|
||||||
|
}
|
||||||
|
final String finalScriptToInject = scriptToInject;
|
||||||
|
// This action will have the side-effect of blurring the currently focused element
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
inAppWebView.loadUrl("javascript:" + finalScriptToInject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put the list of features into a hash map
|
||||||
|
*
|
||||||
|
* @param optString
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private HashMap<String, Boolean> parseFeature(String optString) {
|
||||||
|
if (optString.equals(NULL)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
HashMap<String, Boolean> map = new HashMap<String, Boolean>();
|
||||||
|
StringTokenizer features = new StringTokenizer(optString, ",");
|
||||||
|
StringTokenizer option;
|
||||||
|
while(features.hasMoreElements()) {
|
||||||
|
option = new StringTokenizer(features.nextToken(), "=");
|
||||||
|
if (option.hasMoreElements()) {
|
||||||
|
String key = option.nextToken();
|
||||||
|
if (key.equalsIgnoreCase(CLOSE_BUTTON_CAPTION)) {
|
||||||
|
this.buttonLabel = option.nextToken();
|
||||||
|
} else {
|
||||||
|
Boolean value = option.nextToken().equals("no") ? Boolean.FALSE : Boolean.TRUE;
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a new browser with the specified URL.
|
||||||
|
*
|
||||||
|
* @param url The url to load.
|
||||||
|
* @param usePhoneGap Load url in PhoneGap webview
|
||||||
|
* @return "" if ok, or error message.
|
||||||
|
*/
|
||||||
|
public String openExternal(String url) {
|
||||||
|
try {
|
||||||
|
Intent intent = null;
|
||||||
|
intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
this.cordova.getActivity().startActivity(intent);
|
||||||
|
return "";
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
Log.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString());
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the dialog
|
||||||
|
*/
|
||||||
|
public void closeDialog() {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (dialog != null) {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if it is possible to go back one page in history, then does so.
|
||||||
|
*/
|
||||||
|
private void goBack() {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (InAppBrowser.this.inAppWebView.canGoBack()) {
|
||||||
|
InAppBrowser.this.inAppWebView.goBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if it is possible to go forward one page in history, then does so.
|
||||||
|
*/
|
||||||
|
private void goForward() {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (InAppBrowser.this.inAppWebView.canGoForward()) {
|
||||||
|
InAppBrowser.this.inAppWebView.goForward();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigate to the new page
|
||||||
|
*
|
||||||
|
* @param url to load
|
||||||
|
*/
|
||||||
|
private void navigate(final String url) {
|
||||||
|
InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);
|
||||||
|
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
if (!url.startsWith("http") && !url.startsWith("file:")) {
|
||||||
|
InAppBrowser.this.inAppWebView.loadUrl("http://" + url);
|
||||||
|
} else {
|
||||||
|
InAppBrowser.this.inAppWebView.loadUrl(url);
|
||||||
|
}
|
||||||
|
InAppBrowser.this.inAppWebView.requestFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we show the location bar?
|
||||||
|
*
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private boolean getShowLocationBar() {
|
||||||
|
return this.showLocationBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a new browser with the specified URL.
|
||||||
|
*
|
||||||
|
* @param url The url to load.
|
||||||
|
* @param jsonObject
|
||||||
|
*/
|
||||||
|
public String showWebPage(final String url, HashMap<String, Boolean> features) {
|
||||||
|
// Determine if we should hide the location bar.
|
||||||
|
showLocationBar = true;
|
||||||
|
openWindowHidden = false;
|
||||||
|
if (features != null) {
|
||||||
|
Boolean show = features.get(LOCATION);
|
||||||
|
if (show != null) {
|
||||||
|
showLocationBar = show.booleanValue();
|
||||||
|
}
|
||||||
|
Boolean hidden = features.get(HIDDEN);
|
||||||
|
if (hidden != null) {
|
||||||
|
openWindowHidden = hidden.booleanValue();
|
||||||
|
}
|
||||||
|
Boolean cache = features.get(CLEAR_ALL_CACHE);
|
||||||
|
if (cache != null) {
|
||||||
|
clearAllCache = cache.booleanValue();
|
||||||
|
} else {
|
||||||
|
cache = features.get(CLEAR_SESSION_CACHE);
|
||||||
|
if (cache != null) {
|
||||||
|
clearSessionCache = cache.booleanValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final CordovaWebView thatWebView = this.webView;
|
||||||
|
|
||||||
|
// Create dialog in new thread
|
||||||
|
Runnable runnable = new Runnable() {
|
||||||
|
/**
|
||||||
|
* Convert our DIP units to Pixels
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
private int dpToPixels(int dipValue) {
|
||||||
|
int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
(float) dipValue,
|
||||||
|
cordova.getActivity().getResources().getDisplayMetrics()
|
||||||
|
);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
// Let's create the main dialog
|
||||||
|
dialog = new Dialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
|
||||||
|
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
|
||||||
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
dialog.setCancelable(true);
|
||||||
|
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||||
|
public void onDismiss(DialogInterface dialog) {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Main container layout
|
||||||
|
LinearLayout main = new LinearLayout(cordova.getActivity());
|
||||||
|
main.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
|
||||||
|
// Toolbar layout
|
||||||
|
RelativeLayout toolbar = new RelativeLayout(cordova.getActivity());
|
||||||
|
//Please, no more black!
|
||||||
|
toolbar.setBackgroundColor(android.graphics.Color.LTGRAY);
|
||||||
|
toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44)));
|
||||||
|
toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));
|
||||||
|
toolbar.setHorizontalGravity(Gravity.LEFT);
|
||||||
|
toolbar.setVerticalGravity(Gravity.TOP);
|
||||||
|
|
||||||
|
// Action Button Container layout
|
||||||
|
RelativeLayout actionButtonContainer = new RelativeLayout(cordova.getActivity());
|
||||||
|
actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
|
||||||
|
actionButtonContainer.setHorizontalGravity(Gravity.LEFT);
|
||||||
|
actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);
|
||||||
|
actionButtonContainer.setId(1);
|
||||||
|
|
||||||
|
// Back button
|
||||||
|
Button back = new Button(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
|
backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);
|
||||||
|
back.setLayoutParams(backLayoutParams);
|
||||||
|
back.setContentDescription("Back Button");
|
||||||
|
back.setId(2);
|
||||||
|
back.setText("<");
|
||||||
|
back.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Forward button
|
||||||
|
Button forward = new Button(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
|
forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);
|
||||||
|
forward.setLayoutParams(forwardLayoutParams);
|
||||||
|
forward.setContentDescription("Forward Button");
|
||||||
|
forward.setId(3);
|
||||||
|
forward.setText(">");
|
||||||
|
forward.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
goForward();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Edit Text Box
|
||||||
|
edittext = new EditText(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
|
textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);
|
||||||
|
textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);
|
||||||
|
edittext.setLayoutParams(textLayoutParams);
|
||||||
|
edittext.setId(4);
|
||||||
|
edittext.setSingleLine(true);
|
||||||
|
edittext.setText(url);
|
||||||
|
edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
|
||||||
|
edittext.setImeOptions(EditorInfo.IME_ACTION_GO);
|
||||||
|
edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE
|
||||||
|
edittext.setOnKeyListener(new View.OnKeyListener() {
|
||||||
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||||
|
// If the event is a key-down event on the "enter" button
|
||||||
|
if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
|
||||||
|
navigate(edittext.getText().toString());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close button
|
||||||
|
Button close = new Button(cordova.getActivity());
|
||||||
|
RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
|
||||||
|
closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||||
|
close.setLayoutParams(closeLayoutParams);
|
||||||
|
forward.setContentDescription("Close Button");
|
||||||
|
close.setId(5);
|
||||||
|
close.setText(buttonLabel);
|
||||||
|
close.setOnClickListener(new View.OnClickListener() {
|
||||||
|
public void onClick(View v) {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// WebView
|
||||||
|
inAppWebView = new AmazonWebView(cordova.getActivity());
|
||||||
|
|
||||||
|
CordovaActivity app = (CordovaActivity) cordova.getActivity();
|
||||||
|
cordova.getFactory().initializeWebView(inAppWebView, 0x00FF00, false, null);
|
||||||
|
|
||||||
|
inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
|
||||||
|
inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView));
|
||||||
|
AmazonWebViewClient client = new InAppBrowserClient(thatWebView, edittext);
|
||||||
|
inAppWebView.setWebViewClient(client);
|
||||||
|
AmazonWebSettings settings = inAppWebView.getSettings();
|
||||||
|
settings.setJavaScriptEnabled(true);
|
||||||
|
settings.setJavaScriptCanOpenWindowsAutomatically(true);
|
||||||
|
settings.setBuiltInZoomControls(true);
|
||||||
|
settings.setPluginState(com.amazon.android.webkit.AmazonWebSettings.PluginState.ON);
|
||||||
|
|
||||||
|
//Toggle whether this is enabled or not!
|
||||||
|
Bundle appSettings = cordova.getActivity().getIntent().getExtras();
|
||||||
|
boolean enableDatabase = appSettings == null ? true : appSettings.getBoolean("InAppBrowserStorageEnabled", true);
|
||||||
|
if (enableDatabase) {
|
||||||
|
String databasePath = cordova.getActivity().getApplicationContext().getDir("inAppBrowserDB", Context.MODE_PRIVATE).getPath();
|
||||||
|
settings.setDatabasePath(databasePath);
|
||||||
|
settings.setDatabaseEnabled(true);
|
||||||
|
}
|
||||||
|
settings.setDomStorageEnabled(true);
|
||||||
|
|
||||||
|
if (clearAllCache) {
|
||||||
|
AmazonCookieManager.getInstance().removeAllCookie();
|
||||||
|
} else if (clearSessionCache) {
|
||||||
|
AmazonCookieManager.getInstance().removeSessionCookie();
|
||||||
|
}
|
||||||
|
|
||||||
|
inAppWebView.loadUrl(url);
|
||||||
|
inAppWebView.setId(6);
|
||||||
|
inAppWebView.getSettings().setLoadWithOverviewMode(true);
|
||||||
|
inAppWebView.getSettings().setUseWideViewPort(true);
|
||||||
|
inAppWebView.requestFocus();
|
||||||
|
inAppWebView.requestFocusFromTouch();
|
||||||
|
|
||||||
|
// Add the back and forward buttons to our action button container layout
|
||||||
|
actionButtonContainer.addView(back);
|
||||||
|
actionButtonContainer.addView(forward);
|
||||||
|
|
||||||
|
// Add the views to our toolbar
|
||||||
|
toolbar.addView(actionButtonContainer);
|
||||||
|
toolbar.addView(edittext);
|
||||||
|
toolbar.addView(close);
|
||||||
|
|
||||||
|
// Don't add the toolbar if its been disabled
|
||||||
|
if (getShowLocationBar()) {
|
||||||
|
// Add our toolbar to our main view/layout
|
||||||
|
main.addView(toolbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add our webview to our main view/layout
|
||||||
|
main.addView(inAppWebView);
|
||||||
|
|
||||||
|
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
|
||||||
|
lp.copyFrom(dialog.getWindow().getAttributes());
|
||||||
|
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||||
|
lp.height = WindowManager.LayoutParams.MATCH_PARENT;
|
||||||
|
|
||||||
|
dialog.setContentView(main);
|
||||||
|
dialog.show();
|
||||||
|
dialog.getWindow().setAttributes(lp);
|
||||||
|
// the goal of openhidden is to load the url and not display it
|
||||||
|
// Show() needs to be called to cause the URL to be loaded
|
||||||
|
if(openWindowHidden) {
|
||||||
|
dialog.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.cordova.getActivity().runOnUiThread(runnable);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new plugin success result and send it back to JavaScript
|
||||||
|
*
|
||||||
|
* @param obj a JSONObject contain event payload information
|
||||||
|
*/
|
||||||
|
private void sendUpdate(JSONObject obj, boolean keepCallback) {
|
||||||
|
sendUpdate(obj, keepCallback, PluginResult.Status.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new plugin result and send it back to JavaScript
|
||||||
|
*
|
||||||
|
* @param obj a JSONObject contain event payload information
|
||||||
|
* @param status the status code to return to the JavaScript environment
|
||||||
|
*/
|
||||||
|
private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) {
|
||||||
|
if (callbackContext != null) {
|
||||||
|
PluginResult result = new PluginResult(status, obj);
|
||||||
|
result.setKeepCallback(keepCallback);
|
||||||
|
callbackContext.sendPluginResult(result);
|
||||||
|
if (!keepCallback) {
|
||||||
|
callbackContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The webview client receives notifications about appView
|
||||||
|
*/
|
||||||
|
public class InAppBrowserClient extends AmazonWebViewClient {
|
||||||
|
EditText edittext;
|
||||||
|
CordovaWebView webView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param mContext
|
||||||
|
* @param edittext
|
||||||
|
*/
|
||||||
|
public InAppBrowserClient(CordovaWebView webView, EditText mEditText) {
|
||||||
|
this.webView = webView;
|
||||||
|
this.edittext = mEditText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the host application that a page has started loading.
|
||||||
|
*
|
||||||
|
* @param view The webview initiating the callback.
|
||||||
|
* @param url The url of the page.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onPageStarted(AmazonWebView view, String url, Bitmap favicon) {
|
||||||
|
super.onPageStarted(view, url, favicon);
|
||||||
|
String newloc = "";
|
||||||
|
if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {
|
||||||
|
newloc = url;
|
||||||
|
}
|
||||||
|
// If dialing phone (tel:5551212)
|
||||||
|
else if (url.startsWith(AmazonWebView.SCHEME_TEL)) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (url.startsWith("geo:") || url.startsWith(AmazonWebView.SCHEME_MAILTO) || url.startsWith("market:")) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setData(Uri.parse(url));
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If sms:5551212?body=This is the message
|
||||||
|
else if (url.startsWith("sms:")) {
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
|
||||||
|
// Get address
|
||||||
|
String address = null;
|
||||||
|
int parmIndex = url.indexOf('?');
|
||||||
|
if (parmIndex == -1) {
|
||||||
|
address = url.substring(4);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
address = url.substring(4, parmIndex);
|
||||||
|
|
||||||
|
// If body, then set sms body
|
||||||
|
Uri uri = Uri.parse(url);
|
||||||
|
String query = uri.getQuery();
|
||||||
|
if (query != null) {
|
||||||
|
if (query.startsWith("body=")) {
|
||||||
|
intent.putExtra("sms_body", query.substring(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intent.setData(Uri.parse("sms:" + address));
|
||||||
|
intent.putExtra("address", address);
|
||||||
|
intent.setType("vnd.android-dir/mms-sms");
|
||||||
|
cordova.getActivity().startActivity(intent);
|
||||||
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newloc = "http://" + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!newloc.equals(edittext.getText().toString())) {
|
||||||
|
edittext.setText(newloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("type", LOAD_START_EVENT);
|
||||||
|
obj.put("url", newloc);
|
||||||
|
|
||||||
|
sendUpdate(obj, true);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
Log.d(LOG_TAG, "Should never happen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPageFinished(AmazonWebView view, String url) {
|
||||||
|
super.onPageFinished(view, url);
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("type", LOAD_STOP_EVENT);
|
||||||
|
obj.put("url", url);
|
||||||
|
|
||||||
|
sendUpdate(obj, true);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
Log.d(LOG_TAG, "Should never happen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onReceivedError(AmazonWebView view, int errorCode, String description, String failingUrl) {
|
||||||
|
super.onReceivedError(view, errorCode, description, failingUrl);
|
||||||
|
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("type", LOAD_ERROR_EVENT);
|
||||||
|
obj.put("url", failingUrl);
|
||||||
|
obj.put("code", errorCode);
|
||||||
|
obj.put("message", description);
|
||||||
|
|
||||||
|
sendUpdate(obj, true, PluginResult.Status.ERROR);
|
||||||
|
} catch (JSONException ex) {
|
||||||
|
Log.d(LOG_TAG, "Should never happen");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
146
src/amazon/InAppChromeClient.java
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.inappbrowser;
|
||||||
|
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.LOG;
|
||||||
|
import org.apache.cordova.PluginResult;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import com.amazon.android.webkit.AmazonWebChromeClient;
|
||||||
|
import com.amazon.android.webkit.AmazonGeolocationPermissions.Callback;
|
||||||
|
import com.amazon.android.webkit.AmazonJsPromptResult;
|
||||||
|
import com.amazon.android.webkit.AmazonWebStorage;
|
||||||
|
import com.amazon.android.webkit.AmazonWebView;
|
||||||
|
import com.amazon.android.webkit.AmazonWebViewClient;
|
||||||
|
|
||||||
|
public class InAppChromeClient extends AmazonWebChromeClient {
|
||||||
|
|
||||||
|
private CordovaWebView webView;
|
||||||
|
private String LOG_TAG = "InAppChromeClient";
|
||||||
|
private long MAX_QUOTA = 100 * 1024 * 1024;
|
||||||
|
|
||||||
|
public InAppChromeClient(CordovaWebView webView) {
|
||||||
|
super();
|
||||||
|
this.webView = webView;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Handle database quota exceeded notification.
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @param databaseIdentifier
|
||||||
|
* @param currentQuota
|
||||||
|
* @param estimatedSize
|
||||||
|
* @param totalUsedQuota
|
||||||
|
* @param quotaUpdater
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long currentQuota, long estimatedSize,
|
||||||
|
long totalUsedQuota, AmazonWebStorage.QuotaUpdater quotaUpdater)
|
||||||
|
{
|
||||||
|
LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
|
||||||
|
|
||||||
|
if (estimatedSize < MAX_QUOTA)
|
||||||
|
{
|
||||||
|
//increase for 1Mb
|
||||||
|
long newQuota = estimatedSize;
|
||||||
|
LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota);
|
||||||
|
quotaUpdater.updateQuota(newQuota);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Set the quota to whatever it is and force an error
|
||||||
|
// TODO: get docs on how to handle this properly
|
||||||
|
quotaUpdater.updateQuota(currentQuota);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instructs the client to show a prompt to ask the user to set the Geolocation permission state for the specified origin.
|
||||||
|
*
|
||||||
|
* @param origin
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
|
||||||
|
super.onGeolocationPermissionsShowPrompt(origin, callback);
|
||||||
|
callback.invoke(origin, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the client to display a prompt dialog to the user.
|
||||||
|
* If the client returns true, WebView will assume that the client will
|
||||||
|
* handle the prompt dialog and call the appropriate JsPromptResult method.
|
||||||
|
*
|
||||||
|
* The prompt bridge provided for the InAppBrowser is capable of executing any
|
||||||
|
* oustanding callback belonging to the InAppBrowser plugin. Care has been
|
||||||
|
* taken that other callbacks cannot be triggered, and that no other code
|
||||||
|
* execution is possible.
|
||||||
|
*
|
||||||
|
* To trigger the bridge, the prompt default value should be of the form:
|
||||||
|
*
|
||||||
|
* gap-iab://<callbackId>
|
||||||
|
*
|
||||||
|
* where <callbackId> is the string id of the callback to trigger (something
|
||||||
|
* like "InAppBrowser0123456789")
|
||||||
|
*
|
||||||
|
* If present, the prompt message is expected to be a JSON-encoded value to
|
||||||
|
* pass to the callback. A JSON_EXCEPTION is returned if the JSON is invalid.
|
||||||
|
*
|
||||||
|
* @param view
|
||||||
|
* @param url
|
||||||
|
* @param message
|
||||||
|
* @param defaultValue
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean onJsPrompt(AmazonWebView view, String url, String message, String defaultValue, AmazonJsPromptResult result) {
|
||||||
|
// See if the prompt string uses the 'gap-iab' protocol. If so, the remainder should be the id of a callback to execute.
|
||||||
|
if (defaultValue != null && defaultValue.startsWith("gap")) {
|
||||||
|
if(defaultValue.startsWith("gap-iab://")) {
|
||||||
|
PluginResult scriptResult;
|
||||||
|
String scriptCallbackId = defaultValue.substring(10);
|
||||||
|
if (scriptCallbackId.startsWith("InAppBrowser")) {
|
||||||
|
if(message == null || message.length() == 0) {
|
||||||
|
scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray());
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray(message));
|
||||||
|
} catch(JSONException e) {
|
||||||
|
scriptResult = new PluginResult(PluginResult.Status.JSON_EXCEPTION, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.webView.sendPluginResult(scriptResult, scriptCallbackId);
|
||||||
|
result.confirm("");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Anything else with a gap: prefix should get this message
|
||||||
|
LOG.w(LOG_TAG, "InAppBrowser does not support Cordova API calls: " + url + " " + defaultValue);
|
||||||
|
result.cancel();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,27 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova.inappbrowser;
|
package org.apache.cordova.inappbrowser;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
|
|
||||||
import org.apache.cordova.Config;
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
|
||||||
import org.apache.cordova.CallbackContext;
|
|
||||||
import org.apache.cordova.CordovaPlugin;
|
|
||||||
import org.apache.cordova.LOG;
|
|
||||||
import org.apache.cordova.PluginResult;
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Dialog;
|
import org.apache.cordova.inappbrowser.InAppBrowserDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -52,11 +40,7 @@ import android.view.WindowManager.LayoutParams;
|
|||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.webkit.CookieManager;
|
import android.webkit.CookieManager;
|
||||||
import android.webkit.WebChromeClient;
|
|
||||||
import android.webkit.GeolocationPermissions.Callback;
|
|
||||||
import android.webkit.JsPromptResult;
|
|
||||||
import android.webkit.WebSettings;
|
import android.webkit.WebSettings;
|
||||||
import android.webkit.WebStorage;
|
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -64,6 +48,19 @@ import android.widget.EditText;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
|
|
||||||
|
import org.apache.cordova.CallbackContext;
|
||||||
|
import org.apache.cordova.Config;
|
||||||
|
import org.apache.cordova.CordovaArgs;
|
||||||
|
import org.apache.cordova.CordovaPlugin;
|
||||||
|
import org.apache.cordova.CordovaWebView;
|
||||||
|
import org.apache.cordova.LOG;
|
||||||
|
import org.apache.cordova.PluginResult;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
public class InAppBrowser extends CordovaPlugin {
|
public class InAppBrowser extends CordovaPlugin {
|
||||||
|
|
||||||
@@ -82,7 +79,7 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
private static final String CLEAR_ALL_CACHE = "clearcache";
|
private static final String CLEAR_ALL_CACHE = "clearcache";
|
||||||
private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
|
private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
|
||||||
|
|
||||||
private Dialog dialog;
|
private InAppBrowserDialog dialog;
|
||||||
private WebView inAppWebView;
|
private WebView inAppWebView;
|
||||||
private EditText edittext;
|
private EditText edittext;
|
||||||
private CallbackContext callbackContext;
|
private CallbackContext callbackContext;
|
||||||
@@ -100,120 +97,134 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
* @param callbackId The callback id used when calling back into JavaScript.
|
* @param callbackId The callback id used when calling back into JavaScript.
|
||||||
* @return A PluginResult object with a status and message.
|
* @return A PluginResult object with a status and message.
|
||||||
*/
|
*/
|
||||||
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
|
||||||
try {
|
if (action.equals("open")) {
|
||||||
if (action.equals("open")) {
|
this.callbackContext = callbackContext;
|
||||||
this.callbackContext = callbackContext;
|
final String url = args.getString(0);
|
||||||
String url = args.getString(0);
|
String t = args.optString(1);
|
||||||
String target = args.optString(1);
|
if (t == null || t.equals("") || t.equals(NULL)) {
|
||||||
if (target == null || target.equals("") || target.equals(NULL)) {
|
t = SELF;
|
||||||
target = SELF;
|
}
|
||||||
}
|
final String target = t;
|
||||||
HashMap<String, Boolean> features = parseFeature(args.optString(2));
|
final HashMap<String, Boolean> features = parseFeature(args.optString(2));
|
||||||
|
|
||||||
Log.d(LOG_TAG, "target = " + target);
|
Log.d(LOG_TAG, "target = " + target);
|
||||||
|
|
||||||
url = updateUrl(url);
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
String result = "";
|
@Override
|
||||||
|
public void run() {
|
||||||
// SELF
|
String result = "";
|
||||||
if (SELF.equals(target)) {
|
// SELF
|
||||||
Log.d(LOG_TAG, "in self");
|
if (SELF.equals(target)) {
|
||||||
// load in webview
|
Log.d(LOG_TAG, "in self");
|
||||||
if (url.startsWith("file://") || url.startsWith("javascript:")
|
// load in webview
|
||||||
|| Config.isUrlWhiteListed(url)) {
|
if (url.startsWith("file://") || url.startsWith("javascript:")
|
||||||
this.webView.loadUrl(url);
|
|| Config.isUrlWhiteListed(url)) {
|
||||||
}
|
webView.loadUrl(url);
|
||||||
//Load the dialer
|
}
|
||||||
else if (url.startsWith(WebView.SCHEME_TEL))
|
//Load the dialer
|
||||||
{
|
else if (url.startsWith(WebView.SCHEME_TEL))
|
||||||
try {
|
{
|
||||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
try {
|
||||||
intent.setData(Uri.parse(url));
|
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||||
this.cordova.getActivity().startActivity(intent);
|
intent.setData(Uri.parse(url));
|
||||||
} catch (android.content.ActivityNotFoundException e) {
|
cordova.getActivity().startActivity(intent);
|
||||||
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
|
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// load in InAppBrowser
|
||||||
|
else {
|
||||||
|
result = showWebPage(url, features);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// load in InAppBrowser
|
// SYSTEM
|
||||||
|
else if (SYSTEM.equals(target)) {
|
||||||
|
Log.d(LOG_TAG, "in system");
|
||||||
|
result = openExternal(url);
|
||||||
|
}
|
||||||
|
// BLANK - or anything else
|
||||||
else {
|
else {
|
||||||
result = this.showWebPage(url, features);
|
Log.d(LOG_TAG, "in blank");
|
||||||
|
result = showWebPage(url, features);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result);
|
||||||
|
pluginResult.setKeepCallback(true);
|
||||||
|
callbackContext.sendPluginResult(pluginResult);
|
||||||
}
|
}
|
||||||
// SYSTEM
|
});
|
||||||
else if (SYSTEM.equals(target)) {
|
}
|
||||||
Log.d(LOG_TAG, "in system");
|
else if (action.equals("close")) {
|
||||||
result = this.openExternal(url);
|
closeDialog();
|
||||||
|
}
|
||||||
|
else if (action.equals("injectScriptCode")) {
|
||||||
|
String jsWrapper = null;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId());
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectScriptFile")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectStyleCode")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("injectStyleFile")) {
|
||||||
|
String jsWrapper;
|
||||||
|
if (args.getBoolean(1)) {
|
||||||
|
jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
||||||
|
} else {
|
||||||
|
jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)";
|
||||||
|
}
|
||||||
|
injectDeferredObject(args.getString(0), jsWrapper);
|
||||||
|
}
|
||||||
|
else if (action.equals("show")) {
|
||||||
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
dialog.show();
|
||||||
}
|
}
|
||||||
// BLANK - or anything else
|
});
|
||||||
else {
|
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
|
||||||
Log.d(LOG_TAG, "in blank");
|
pluginResult.setKeepCallback(true);
|
||||||
result = this.showWebPage(url, features);
|
this.callbackContext.sendPluginResult(pluginResult);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK, result);
|
return false;
|
||||||
pluginResult.setKeepCallback(true);
|
|
||||||
this.callbackContext.sendPluginResult(pluginResult);
|
|
||||||
}
|
|
||||||
else if (action.equals("close")) {
|
|
||||||
closeDialog();
|
|
||||||
this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK));
|
|
||||||
}
|
|
||||||
else if (action.equals("injectScriptCode")) {
|
|
||||||
String jsWrapper = null;
|
|
||||||
if (args.getBoolean(1)) {
|
|
||||||
jsWrapper = String.format("prompt(JSON.stringify([eval(%%s)]), 'gap-iab://%s')", callbackContext.getCallbackId());
|
|
||||||
}
|
|
||||||
injectDeferredObject(args.getString(0), jsWrapper);
|
|
||||||
}
|
|
||||||
else if (action.equals("injectScriptFile")) {
|
|
||||||
String jsWrapper;
|
|
||||||
if (args.getBoolean(1)) {
|
|
||||||
jsWrapper = String.format("(function(d) { var c = d.createElement('script'); c.src = %%s; c.onload = function() { prompt('', 'gap-iab://%s'); }; d.body.appendChild(c); })(document)", callbackContext.getCallbackId());
|
|
||||||
} else {
|
|
||||||
jsWrapper = "(function(d) { var c = d.createElement('script'); c.src = %s; d.body.appendChild(c); })(document)";
|
|
||||||
}
|
|
||||||
injectDeferredObject(args.getString(0), jsWrapper);
|
|
||||||
}
|
|
||||||
else if (action.equals("injectStyleCode")) {
|
|
||||||
String jsWrapper;
|
|
||||||
if (args.getBoolean(1)) {
|
|
||||||
jsWrapper = String.format("(function(d) { var c = d.createElement('style'); c.innerHTML = %%s; d.body.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
|
||||||
} else {
|
|
||||||
jsWrapper = "(function(d) { var c = d.createElement('style'); c.innerHTML = %s; d.body.appendChild(c); })(document)";
|
|
||||||
}
|
|
||||||
injectDeferredObject(args.getString(0), jsWrapper);
|
|
||||||
}
|
|
||||||
else if (action.equals("injectStyleFile")) {
|
|
||||||
String jsWrapper;
|
|
||||||
if (args.getBoolean(1)) {
|
|
||||||
jsWrapper = String.format("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%s; d.head.appendChild(c); prompt('', 'gap-iab://%s');})(document)", callbackContext.getCallbackId());
|
|
||||||
} else {
|
|
||||||
jsWrapper = "(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %s; d.head.appendChild(c); })(document)";
|
|
||||||
}
|
|
||||||
injectDeferredObject(args.getString(0), jsWrapper);
|
|
||||||
}
|
|
||||||
else if (action.equals("show")) {
|
|
||||||
Runnable runnable = new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.cordova.getActivity().runOnUiThread(runnable);
|
|
||||||
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
|
|
||||||
pluginResult.setKeepCallback(true);
|
|
||||||
this.callbackContext.sendPluginResult(pluginResult);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
this.callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the view navigates.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onReset() {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by AccelBroker when listener is to be shut down.
|
||||||
|
* Stop listener.
|
||||||
|
*/
|
||||||
|
public void onDestroy() {
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inject an object (script or style) into the InAppBrowser WebView.
|
* Inject an object (script or style) into the InAppBrowser WebView.
|
||||||
*
|
*
|
||||||
@@ -241,8 +252,19 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
} else {
|
} else {
|
||||||
scriptToInject = source;
|
scriptToInject = source;
|
||||||
}
|
}
|
||||||
// This action will have the side-effect of blurring the currently focused element
|
final String finalScriptToInject = scriptToInject;
|
||||||
this.inAppWebView.loadUrl("javascript:" + scriptToInject);
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
|
||||||
|
// This action will have the side-effect of blurring the currently focused element
|
||||||
|
inAppWebView.loadUrl("javascript:" + finalScriptToInject);
|
||||||
|
} else {
|
||||||
|
inAppWebView.evaluateJavascript(finalScriptToInject, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,20 +296,6 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert relative URL to full path
|
|
||||||
*
|
|
||||||
* @param url
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String updateUrl(String url) {
|
|
||||||
Uri newUrl = Uri.parse(url);
|
|
||||||
if (newUrl.isRelative()) {
|
|
||||||
url = this.webView.getUrl().substring(0, this.webView.getUrl().lastIndexOf("/")+1) + url;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a new browser with the specified URL.
|
* Display a new browser with the specified URL.
|
||||||
*
|
*
|
||||||
@@ -299,7 +307,14 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
try {
|
try {
|
||||||
Intent intent = null;
|
Intent intent = null;
|
||||||
intent = new Intent(Intent.ACTION_VIEW);
|
intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setData(Uri.parse(url));
|
// Omitting the MIME type for file: URLs causes "No Activity found to handle Intent".
|
||||||
|
// Adding the MIME type to http: URLs causes them to not be handled by the downloader.
|
||||||
|
Uri uri = Uri.parse(url);
|
||||||
|
if ("file".equals(uri.getScheme())) {
|
||||||
|
intent.setDataAndType(uri, webView.getResourceApi().getMimeType(uri));
|
||||||
|
} else {
|
||||||
|
intent.setData(uri);
|
||||||
|
}
|
||||||
this.cordova.getActivity().startActivity(intent);
|
this.cordova.getActivity().startActivity(intent);
|
||||||
return "";
|
return "";
|
||||||
} catch (android.content.ActivityNotFoundException e) {
|
} catch (android.content.ActivityNotFoundException e) {
|
||||||
@@ -311,30 +326,38 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
/**
|
/**
|
||||||
* Closes the dialog
|
* Closes the dialog
|
||||||
*/
|
*/
|
||||||
private void closeDialog() {
|
public void closeDialog() {
|
||||||
try {
|
final WebView childView = this.inAppWebView;
|
||||||
final WebView childView = this.inAppWebView;
|
// The JS protects against multiple calls, so this should happen only when
|
||||||
Runnable runnable = new Runnable() {
|
// closeDialog() is called by other native code.
|
||||||
|
if (childView == null) {
|
||||||
@Override
|
return;
|
||||||
public void run() {
|
}
|
||||||
childView.loadUrl("about:blank");
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
childView.setWebViewClient(new WebViewClient() {
|
||||||
|
// NB: wait for about:blank before dismissing
|
||||||
|
public void onPageFinished(WebView view, String url) {
|
||||||
|
if (dialog != null) {
|
||||||
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
});
|
||||||
|
// NB: From SDK 19: "If you call methods on WebView from any thread
|
||||||
this.cordova.getActivity().runOnUiThread(runnable);
|
// other than your app's UI thread, it can cause unexpected results."
|
||||||
|
// http://developer.android.com/guide/webapps/migrating.html#Threads
|
||||||
|
childView.loadUrl("about:blank");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("type", EXIT_EVENT);
|
obj.put("type", EXIT_EVENT);
|
||||||
|
|
||||||
sendUpdate(obj, false);
|
sendUpdate(obj, false);
|
||||||
} catch (JSONException ex) {
|
} catch (JSONException ex) {
|
||||||
Log.d(LOG_TAG, "Should never happen");
|
Log.d(LOG_TAG, "Should never happen");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialog != null) {
|
|
||||||
dialog.dismiss();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -382,6 +405,10 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
return this.showLocationBar;
|
return this.showLocationBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InAppBrowser getInAppBrowser(){
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a new browser with the specified URL.
|
* Display a new browser with the specified URL.
|
||||||
*
|
*
|
||||||
@@ -432,22 +459,11 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
// Let's create the main dialog
|
// Let's create the main dialog
|
||||||
dialog = new Dialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
|
dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
|
||||||
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
|
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
|
||||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
dialog.setCancelable(true);
|
dialog.setCancelable(true);
|
||||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
dialog.setInAppBroswer(getInAppBrowser());
|
||||||
public void onDismiss(DialogInterface dialog) {
|
|
||||||
try {
|
|
||||||
JSONObject obj = new JSONObject();
|
|
||||||
obj.put("type", EXIT_EVENT);
|
|
||||||
|
|
||||||
sendUpdate(obj, false);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.d(LOG_TAG, "Should never happen");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Main container layout
|
// Main container layout
|
||||||
LinearLayout main = new LinearLayout(cordova.getActivity());
|
LinearLayout main = new LinearLayout(cordova.getActivity());
|
||||||
@@ -476,7 +492,20 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
back.setLayoutParams(backLayoutParams);
|
back.setLayoutParams(backLayoutParams);
|
||||||
back.setContentDescription("Back Button");
|
back.setContentDescription("Back Button");
|
||||||
back.setId(2);
|
back.setId(2);
|
||||||
|
/*
|
||||||
back.setText("<");
|
back.setText("<");
|
||||||
|
*/
|
||||||
|
Resources activityRes = cordova.getActivity().getResources();
|
||||||
|
int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName());
|
||||||
|
Drawable backIcon = activityRes.getDrawable(backResId);
|
||||||
|
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
|
||||||
|
{
|
||||||
|
back.setBackgroundDrawable(backIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
back.setBackground(backIcon);
|
||||||
|
}
|
||||||
back.setOnClickListener(new View.OnClickListener() {
|
back.setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
goBack();
|
goBack();
|
||||||
@@ -490,7 +519,17 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
forward.setLayoutParams(forwardLayoutParams);
|
forward.setLayoutParams(forwardLayoutParams);
|
||||||
forward.setContentDescription("Forward Button");
|
forward.setContentDescription("Forward Button");
|
||||||
forward.setId(3);
|
forward.setId(3);
|
||||||
forward.setText(">");
|
//forward.setText(">");
|
||||||
|
int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", cordova.getActivity().getPackageName());
|
||||||
|
Drawable fwdIcon = activityRes.getDrawable(fwdResId);
|
||||||
|
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
|
||||||
|
{
|
||||||
|
forward.setBackgroundDrawable(fwdIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
forward.setBackground(fwdIcon);
|
||||||
|
}
|
||||||
forward.setOnClickListener(new View.OnClickListener() {
|
forward.setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
goForward();
|
goForward();
|
||||||
@@ -527,7 +566,17 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
close.setLayoutParams(closeLayoutParams);
|
close.setLayoutParams(closeLayoutParams);
|
||||||
forward.setContentDescription("Close Button");
|
forward.setContentDescription("Close Button");
|
||||||
close.setId(5);
|
close.setId(5);
|
||||||
close.setText(buttonLabel);
|
//close.setText(buttonLabel);
|
||||||
|
int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName());
|
||||||
|
Drawable closeIcon = activityRes.getDrawable(closeResId);
|
||||||
|
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
|
||||||
|
{
|
||||||
|
close.setBackgroundDrawable(closeIcon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close.setBackground(closeIcon);
|
||||||
|
}
|
||||||
close.setOnClickListener(new View.OnClickListener() {
|
close.setOnClickListener(new View.OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
closeDialog();
|
closeDialog();
|
||||||
@@ -620,10 +669,16 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
*
|
*
|
||||||
* @param obj a JSONObject contain event payload information
|
* @param obj a JSONObject contain event payload information
|
||||||
* @param status the status code to return to the JavaScript environment
|
* @param status the status code to return to the JavaScript environment
|
||||||
*/ private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) {
|
*/
|
||||||
PluginResult result = new PluginResult(status, obj);
|
private void sendUpdate(JSONObject obj, boolean keepCallback, PluginResult.Status status) {
|
||||||
result.setKeepCallback(keepCallback);
|
if (callbackContext != null) {
|
||||||
this.callbackContext.sendPluginResult(result);
|
PluginResult result = new PluginResult(status, obj);
|
||||||
|
result.setKeepCallback(keepCallback);
|
||||||
|
callbackContext.sendPluginResult(result);
|
||||||
|
if (!keepCallback) {
|
||||||
|
callbackContext = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
54
src/android/InAppBrowserDialog.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova.inappbrowser;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Oliver on 22/11/2013.
|
||||||
|
*/
|
||||||
|
public class InAppBrowserDialog extends Dialog {
|
||||||
|
Context context;
|
||||||
|
InAppBrowser inAppBrowser = null;
|
||||||
|
|
||||||
|
public InAppBrowserDialog(Context context, int theme) {
|
||||||
|
super(context, theme);
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInAppBroswer(InAppBrowser browser) {
|
||||||
|
this.inAppBrowser = browser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBackPressed () {
|
||||||
|
if (this.inAppBrowser == null) {
|
||||||
|
this.dismiss();
|
||||||
|
} else {
|
||||||
|
// better to go through the in inAppBrowser
|
||||||
|
// because it does a clean up
|
||||||
|
this.inAppBrowser.closeDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +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.
|
||||||
|
*/
|
||||||
package org.apache.cordova.inappbrowser;
|
package org.apache.cordova.inappbrowser;
|
||||||
|
|
||||||
import org.apache.cordova.CordovaWebView;
|
import org.apache.cordova.CordovaWebView;
|
||||||
@@ -38,20 +56,7 @@ public class InAppChromeClient extends WebChromeClient {
|
|||||||
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
|
long totalUsedQuota, WebStorage.QuotaUpdater quotaUpdater)
|
||||||
{
|
{
|
||||||
LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
|
LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota);
|
||||||
|
quotaUpdater.updateQuota(MAX_QUOTA);
|
||||||
if (estimatedSize < MAX_QUOTA)
|
|
||||||
{
|
|
||||||
//increase for 1Mb
|
|
||||||
long newQuota = estimatedSize;
|
|
||||||
LOG.d(LOG_TAG, "calling quotaUpdater.updateQuota newQuota: %d", newQuota);
|
|
||||||
quotaUpdater.updateQuota(newQuota);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Set the quota to whatever it is and force an error
|
|
||||||
// TODO: get docs on how to handle this properly
|
|
||||||
quotaUpdater.updateQuota(currentQuota);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
BIN
src/android/res/drawable-hdpi/ic_action_next_item.png
Normal file
|
After Width: | Height: | Size: 593 B |
BIN
src/android/res/drawable-hdpi/ic_action_previous_item.png
Normal file
|
After Width: | Height: | Size: 599 B |
BIN
src/android/res/drawable-hdpi/ic_action_remove.png
Normal file
|
After Width: | Height: | Size: 438 B |
BIN
src/android/res/drawable-mdpi/ic_action_next_item.png
Normal file
|
After Width: | Height: | Size: 427 B |
BIN
src/android/res/drawable-mdpi/ic_action_previous_item.png
Normal file
|
After Width: | Height: | Size: 438 B |
BIN
src/android/res/drawable-mdpi/ic_action_remove.png
Normal file
|
After Width: | Height: | Size: 328 B |
BIN
src/android/res/drawable-xhdpi/ic_action_next_item.png
Normal file
|
After Width: | Height: | Size: 727 B |
BIN
src/android/res/drawable-xhdpi/ic_action_previous_item.png
Normal file
|
After Width: | Height: | Size: 744 B |
BIN
src/android/res/drawable-xhdpi/ic_action_remove.png
Normal file
|
After Width: | Height: | Size: 536 B |
BIN
src/android/res/drawable-xxhdpi/ic_action_next_item.png
Normal file
|
After Width: | Height: | Size: 1021 B |
BIN
src/android/res/drawable-xxhdpi/ic_action_previous_item.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/android/res/drawable-xxhdpi/ic_action_remove.png
Normal file
|
After Width: | Height: | Size: 681 B |
@@ -1,3 +1,21 @@
|
|||||||
|
<!---
|
||||||
|
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.
|
||||||
|
-->
|
||||||
# BlackBerry 10 In-App-Browser Plugin
|
# BlackBerry 10 In-App-Browser Plugin
|
||||||
|
|
||||||
The in app browser functionality is entirely contained within common js. There is no native implementation required.
|
The in app browser functionality is entirely contained within common js. There is no native implementation required.
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
@property (nonatomic, retain) CDVInAppBrowserViewController* inAppBrowserViewController;
|
@property (nonatomic, retain) CDVInAppBrowserViewController* inAppBrowserViewController;
|
||||||
@property (nonatomic, copy) NSString* callbackId;
|
@property (nonatomic, copy) NSString* callbackId;
|
||||||
|
@property (nonatomic, copy) NSRegularExpression *callbackIdPattern;
|
||||||
|
|
||||||
- (void)open:(CDVInvokedUrlCommand*)command;
|
- (void)open:(CDVInvokedUrlCommand*)command;
|
||||||
- (void)close:(CDVInvokedUrlCommand*)command;
|
- (void)close:(CDVInvokedUrlCommand*)command;
|
||||||
@@ -38,11 +39,36 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface CDVInAppBrowserOptions : NSObject {}
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL location;
|
||||||
|
@property (nonatomic, assign) BOOL toolbar;
|
||||||
|
@property (nonatomic, copy) NSString* closebuttoncaption;
|
||||||
|
@property (nonatomic, copy) NSString* toolbarposition;
|
||||||
|
@property (nonatomic, assign) BOOL clearcache;
|
||||||
|
@property (nonatomic, assign) BOOL clearsessioncache;
|
||||||
|
|
||||||
|
@property (nonatomic, copy) NSString* presentationstyle;
|
||||||
|
@property (nonatomic, copy) NSString* transitionstyle;
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL enableviewportscale;
|
||||||
|
@property (nonatomic, assign) BOOL mediaplaybackrequiresuseraction;
|
||||||
|
@property (nonatomic, assign) BOOL allowinlinemediaplayback;
|
||||||
|
@property (nonatomic, assign) BOOL keyboarddisplayrequiresuseraction;
|
||||||
|
@property (nonatomic, assign) BOOL suppressesincrementalrendering;
|
||||||
|
@property (nonatomic, assign) BOOL hidden;
|
||||||
|
@property (nonatomic, assign) BOOL disallowoverscroll;
|
||||||
|
|
||||||
|
+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@interface CDVInAppBrowserViewController : UIViewController <UIWebViewDelegate>{
|
@interface CDVInAppBrowserViewController : UIViewController <UIWebViewDelegate>{
|
||||||
@private
|
@private
|
||||||
NSString* _userAgent;
|
NSString* _userAgent;
|
||||||
NSString* _prevUserAgent;
|
NSString* _prevUserAgent;
|
||||||
NSInteger _userAgentLockToken;
|
NSInteger _userAgentLockToken;
|
||||||
|
CDVInAppBrowserOptions *_browserOptions;
|
||||||
CDVWebViewDelegate* _webViewDelegate;
|
CDVWebViewDelegate* _webViewDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,29 +87,9 @@
|
|||||||
- (void)close;
|
- (void)close;
|
||||||
- (void)navigateTo:(NSURL*)url;
|
- (void)navigateTo:(NSURL*)url;
|
||||||
- (void)showLocationBar:(BOOL)show;
|
- (void)showLocationBar:(BOOL)show;
|
||||||
- (void)showToolBar:(BOOL)show;
|
- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition;
|
||||||
- (void)setCloseButtonTitle:(NSString*)title;
|
- (void)setCloseButtonTitle:(NSString*)title;
|
||||||
|
|
||||||
- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent;
|
- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface CDVInAppBrowserOptions : NSObject {}
|
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL location;
|
|
||||||
@property (nonatomic, assign) BOOL toolbar;
|
|
||||||
@property (nonatomic, copy) NSString* closebuttoncaption;
|
|
||||||
|
|
||||||
@property (nonatomic, copy) NSString* presentationstyle;
|
|
||||||
@property (nonatomic, copy) NSString* transitionstyle;
|
|
||||||
|
|
||||||
@property (nonatomic, assign) BOOL enableviewportscale;
|
|
||||||
@property (nonatomic, assign) BOOL mediaplaybackrequiresuseraction;
|
|
||||||
@property (nonatomic, assign) BOOL allowinlinemediaplayback;
|
|
||||||
@property (nonatomic, assign) BOOL keyboarddisplayrequiresuseraction;
|
|
||||||
@property (nonatomic, assign) BOOL suppressesincrementalrendering;
|
|
||||||
@property (nonatomic, assign) BOOL hidden;
|
|
||||||
|
|
||||||
+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options;
|
|
||||||
|
|
||||||
@end
|
|
||||||
@@ -26,19 +26,28 @@
|
|||||||
#define kInAppBrowserTargetSystem @"_system"
|
#define kInAppBrowserTargetSystem @"_system"
|
||||||
#define kInAppBrowserTargetBlank @"_blank"
|
#define kInAppBrowserTargetBlank @"_blank"
|
||||||
|
|
||||||
|
#define kInAppBrowserToolbarBarPositionBottom @"bottom"
|
||||||
|
#define kInAppBrowserToolbarBarPositionTop @"top"
|
||||||
|
|
||||||
#define TOOLBAR_HEIGHT 44.0
|
#define TOOLBAR_HEIGHT 44.0
|
||||||
#define LOCATIONBAR_HEIGHT 21.0
|
#define LOCATIONBAR_HEIGHT 21.0
|
||||||
#define FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT))
|
#define FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT))
|
||||||
|
|
||||||
#pragma mark CDVInAppBrowser
|
#pragma mark CDVInAppBrowser
|
||||||
|
|
||||||
|
@interface CDVInAppBrowser () {
|
||||||
|
NSInteger _previousStatusBarStyle;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation CDVInAppBrowser
|
@implementation CDVInAppBrowser
|
||||||
|
|
||||||
- (CDVInAppBrowser*)initWithWebView:(UIWebView*)theWebView
|
- (CDVInAppBrowser*)initWithWebView:(UIWebView*)theWebView
|
||||||
{
|
{
|
||||||
self = [super initWithWebView:theWebView];
|
self = [super initWithWebView:theWebView];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
// your initialization here
|
_previousStatusBarStyle = -1;
|
||||||
|
_callbackIdPattern = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -51,12 +60,12 @@
|
|||||||
|
|
||||||
- (void)close:(CDVInvokedUrlCommand*)command
|
- (void)close:(CDVInvokedUrlCommand*)command
|
||||||
{
|
{
|
||||||
if (self.inAppBrowserViewController != nil) {
|
if (self.inAppBrowserViewController == nil) {
|
||||||
[self.inAppBrowserViewController close];
|
NSLog(@"IAB.close() called but it was already closed.");
|
||||||
self.inAppBrowserViewController = nil;
|
return;
|
||||||
}
|
}
|
||||||
|
// Things are cleaned up in browserExit.
|
||||||
self.callbackId = nil;
|
[self.inAppBrowserViewController close];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isSystemUrl:(NSURL*)url
|
- (BOOL) isSystemUrl:(NSURL*)url
|
||||||
@@ -105,9 +114,33 @@
|
|||||||
|
|
||||||
- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options
|
- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options
|
||||||
{
|
{
|
||||||
|
CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options];
|
||||||
|
|
||||||
|
if (browserOptions.clearcache) {
|
||||||
|
NSHTTPCookie *cookie;
|
||||||
|
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||||
|
for (cookie in [storage cookies])
|
||||||
|
{
|
||||||
|
if (![cookie.domain isEqual: @".^filecookies^"]) {
|
||||||
|
[storage deleteCookie:cookie];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browserOptions.clearsessioncache) {
|
||||||
|
NSHTTPCookie *cookie;
|
||||||
|
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
|
||||||
|
for (cookie in [storage cookies])
|
||||||
|
{
|
||||||
|
if (![cookie.domain isEqual: @".^filecookies^"] && cookie.isSessionOnly) {
|
||||||
|
[storage deleteCookie:cookie];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (self.inAppBrowserViewController == nil) {
|
if (self.inAppBrowserViewController == nil) {
|
||||||
NSString* originalUA = [CDVUserAgentUtil originalUserAgent];
|
NSString* originalUA = [CDVUserAgentUtil originalUserAgent];
|
||||||
self.inAppBrowserViewController = [[CDVInAppBrowserViewController alloc] initWithUserAgent:originalUA prevUserAgent:[self.commandDelegate userAgent]];
|
self.inAppBrowserViewController = [[CDVInAppBrowserViewController alloc] initWithUserAgent:originalUA prevUserAgent:[self.commandDelegate userAgent] browserOptions: browserOptions];
|
||||||
self.inAppBrowserViewController.navigationDelegate = self;
|
self.inAppBrowserViewController.navigationDelegate = self;
|
||||||
|
|
||||||
if ([self.viewController conformsToProtocol:@protocol(CDVScreenOrientationDelegate)]) {
|
if ([self.viewController conformsToProtocol:@protocol(CDVScreenOrientationDelegate)]) {
|
||||||
@@ -115,10 +148,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options];
|
|
||||||
[self.inAppBrowserViewController showLocationBar:browserOptions.location];
|
[self.inAppBrowserViewController showLocationBar:browserOptions.location];
|
||||||
[self.inAppBrowserViewController showToolBar:browserOptions.toolbar];
|
[self.inAppBrowserViewController showToolBar:browserOptions.toolbar :browserOptions.toolbarposition];
|
||||||
if (browserOptions.closebuttoncaption != nil) {
|
if (browserOptions.closebuttoncaption != nil) {
|
||||||
[self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption];
|
[self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption];
|
||||||
}
|
}
|
||||||
@@ -144,6 +175,18 @@
|
|||||||
}
|
}
|
||||||
self.inAppBrowserViewController.modalTransitionStyle = transitionStyle;
|
self.inAppBrowserViewController.modalTransitionStyle = transitionStyle;
|
||||||
|
|
||||||
|
// prevent webView from bouncing
|
||||||
|
if (browserOptions.disallowoverscroll) {
|
||||||
|
if ([self.inAppBrowserViewController.webView respondsToSelector:@selector(scrollView)]) {
|
||||||
|
((UIScrollView*)[self.inAppBrowserViewController.webView scrollView]).bounces = NO;
|
||||||
|
} else {
|
||||||
|
for (id subview in self.inAppBrowserViewController.webView.subviews) {
|
||||||
|
if ([[subview class] isSubclassOfClass:[UIScrollView class]]) {
|
||||||
|
((UIScrollView*)subview).bounces = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// UIWebView options
|
// UIWebView options
|
||||||
self.inAppBrowserViewController.webView.scalesPageToFit = browserOptions.enableviewportscale;
|
self.inAppBrowserViewController.webView.scalesPageToFit = browserOptions.enableviewportscale;
|
||||||
@@ -154,19 +197,34 @@
|
|||||||
self.inAppBrowserViewController.webView.suppressesIncrementalRendering = browserOptions.suppressesincrementalrendering;
|
self.inAppBrowserViewController.webView.suppressesIncrementalRendering = browserOptions.suppressesincrementalrendering;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! browserOptions.hidden) {
|
|
||||||
if (self.viewController.modalViewController != self.inAppBrowserViewController) {
|
|
||||||
[self.viewController presentModalViewController:self.inAppBrowserViewController animated:YES];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[self.inAppBrowserViewController navigateTo:url];
|
[self.inAppBrowserViewController navigateTo:url];
|
||||||
|
if (!browserOptions.hidden) {
|
||||||
|
[self show:nil];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)show:(CDVInvokedUrlCommand*)command
|
- (void)show:(CDVInvokedUrlCommand*)command
|
||||||
{
|
{
|
||||||
if ([self.inAppBrowserViewController isViewLoaded] && self.inAppBrowserViewController.view.window)
|
if (self.inAppBrowserViewController == nil) {
|
||||||
|
NSLog(@"Tried to show IAB after it was closed.");
|
||||||
return;
|
return;
|
||||||
[self.viewController presentModalViewController:self.inAppBrowserViewController animated:YES];
|
}
|
||||||
|
if (_previousStatusBarStyle != -1) {
|
||||||
|
NSLog(@"Tried to show IAB while already shown");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
|
||||||
|
|
||||||
|
UINavigationController* nav = [[UINavigationController alloc]
|
||||||
|
initWithRootViewController:self.inAppBrowserViewController];
|
||||||
|
nav.navigationBarHidden = YES;
|
||||||
|
// Run later to avoid the "took a long time" log message.
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if (self.inAppBrowserViewController != nil) {
|
||||||
|
[self.viewController presentModalViewController:nav animated:YES];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options
|
- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options
|
||||||
@@ -222,7 +280,7 @@
|
|||||||
NSString* jsWrapper = nil;
|
NSString* jsWrapper = nil;
|
||||||
|
|
||||||
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
|
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
|
||||||
jsWrapper = [NSString stringWithFormat:@"_cdvIframeBridge.src='gap-iab://%@/'+window.escape(JSON.stringify([eval(%%@)]));", command.callbackId];
|
jsWrapper = [NSString stringWithFormat:@"_cdvIframeBridge.src='gap-iab://%@/'+encodeURIComponent(JSON.stringify([eval(%%@)]));", command.callbackId];
|
||||||
}
|
}
|
||||||
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
||||||
}
|
}
|
||||||
@@ -263,6 +321,23 @@
|
|||||||
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)isValidCallbackId:(NSString *)callbackId
|
||||||
|
{
|
||||||
|
NSError *err = nil;
|
||||||
|
// Initialize on first use
|
||||||
|
if (self.callbackIdPattern == nil) {
|
||||||
|
self.callbackIdPattern = [NSRegularExpression regularExpressionWithPattern:@"^InAppBrowser[0-9]{1,10}$" options:0 error:&err];
|
||||||
|
if (err != nil) {
|
||||||
|
// Couldn't initialize Regex; No is safer than Yes.
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ([self.callbackIdPattern firstMatchInString:callbackId options:0 range:NSMakeRange(0, [callbackId length])]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The iframe bridge provided for the InAppBrowser is capable of executing any oustanding callback belonging
|
* The iframe bridge provided for the InAppBrowser is capable of executing any oustanding callback belonging
|
||||||
* to the InAppBrowser plugin. Care has been taken that other callbacks cannot be triggered, and that no
|
* to the InAppBrowser plugin. Care has been taken that other callbacks cannot be triggered, and that no
|
||||||
@@ -289,7 +364,7 @@
|
|||||||
NSString* scriptCallbackId = [url host];
|
NSString* scriptCallbackId = [url host];
|
||||||
CDVPluginResult* pluginResult = nil;
|
CDVPluginResult* pluginResult = nil;
|
||||||
|
|
||||||
if ([scriptCallbackId hasPrefix:@"InAppBrowser"]) {
|
if ([self isValidCallbackId:scriptCallbackId]) {
|
||||||
NSString* scriptResult = [url path];
|
NSString* scriptResult = [url path];
|
||||||
NSError* __autoreleasing error = nil;
|
NSError* __autoreleasing error = nil;
|
||||||
|
|
||||||
@@ -343,7 +418,7 @@
|
|||||||
if (self.callbackId != nil) {
|
if (self.callbackId != nil) {
|
||||||
NSString* url = [self.inAppBrowserViewController.currentURL absoluteString];
|
NSString* url = [self.inAppBrowserViewController.currentURL absoluteString];
|
||||||
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
|
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
|
||||||
messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInt:error.code], @"message": error.localizedDescription}];
|
messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInteger:error.code], @"message": error.localizedDescription}];
|
||||||
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
|
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
|
||||||
|
|
||||||
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
||||||
@@ -355,13 +430,20 @@
|
|||||||
if (self.callbackId != nil) {
|
if (self.callbackId != nil) {
|
||||||
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
|
||||||
messageAsDictionary:@{@"type":@"exit"}];
|
messageAsDictionary:@{@"type":@"exit"}];
|
||||||
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
|
|
||||||
|
|
||||||
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
|
||||||
|
self.callbackId = nil;
|
||||||
}
|
}
|
||||||
|
// Set navigationDelegate to nil to ensure no callbacks are received from it.
|
||||||
|
self.inAppBrowserViewController.navigationDelegate = nil;
|
||||||
// Don't recycle the ViewController since it may be consuming a lot of memory.
|
// Don't recycle the ViewController since it may be consuming a lot of memory.
|
||||||
// Also - this is required for the PDF/User-Agent bug work-around.
|
// Also - this is required for the PDF/User-Agent bug work-around.
|
||||||
self.inAppBrowserViewController = nil;
|
self.inAppBrowserViewController = nil;
|
||||||
|
|
||||||
|
_previousStatusBarStyle = -1;
|
||||||
|
|
||||||
|
if (IsAtLeastiOSVersion(@"7.0")) {
|
||||||
|
[[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -372,12 +454,13 @@
|
|||||||
|
|
||||||
@synthesize currentURL;
|
@synthesize currentURL;
|
||||||
|
|
||||||
- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent
|
- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
_userAgent = userAgent;
|
_userAgent = userAgent;
|
||||||
_prevUserAgent = prevUserAgent;
|
_prevUserAgent = prevUserAgent;
|
||||||
|
_browserOptions = browserOptions;
|
||||||
_webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self];
|
_webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self];
|
||||||
[self createViews];
|
[self createViews];
|
||||||
}
|
}
|
||||||
@@ -390,10 +473,10 @@
|
|||||||
// We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included
|
// We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included
|
||||||
|
|
||||||
CGRect webViewBounds = self.view.bounds;
|
CGRect webViewBounds = self.view.bounds;
|
||||||
|
BOOL toolbarIsAtBottom = ![_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop];
|
||||||
webViewBounds.size.height -= FOOTER_HEIGHT;
|
webViewBounds.size.height -= _browserOptions.location ? FOOTER_HEIGHT : TOOLBAR_HEIGHT;
|
||||||
|
|
||||||
self.webView = [[UIWebView alloc] initWithFrame:webViewBounds];
|
self.webView = [[UIWebView alloc] initWithFrame:webViewBounds];
|
||||||
|
|
||||||
self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
|
self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
|
||||||
|
|
||||||
[self.view addSubview:self.webView];
|
[self.view addSubview:self.webView];
|
||||||
@@ -435,10 +518,13 @@
|
|||||||
UIBarButtonItem* fixedSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
|
UIBarButtonItem* fixedSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
|
||||||
fixedSpaceButton.width = 20;
|
fixedSpaceButton.width = 20;
|
||||||
|
|
||||||
self.toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, (self.view.bounds.size.height - TOOLBAR_HEIGHT), self.view.bounds.size.width, TOOLBAR_HEIGHT)];
|
float toolbarY = toolbarIsAtBottom ? self.view.bounds.size.height - TOOLBAR_HEIGHT : 0.0;
|
||||||
|
CGRect toolbarFrame = CGRectMake(0.0, toolbarY, self.view.bounds.size.width, TOOLBAR_HEIGHT);
|
||||||
|
|
||||||
|
self.toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame];
|
||||||
self.toolbar.alpha = 1.000;
|
self.toolbar.alpha = 1.000;
|
||||||
self.toolbar.autoresizesSubviews = YES;
|
self.toolbar.autoresizesSubviews = YES;
|
||||||
self.toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
|
self.toolbar.autoresizingMask = toolbarIsAtBottom ? (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin) : UIViewAutoresizingFlexibleWidth;
|
||||||
self.toolbar.barStyle = UIBarStyleBlackOpaque;
|
self.toolbar.barStyle = UIBarStyleBlackOpaque;
|
||||||
self.toolbar.clearsContextBeforeDrawing = NO;
|
self.toolbar.clearsContextBeforeDrawing = NO;
|
||||||
self.toolbar.clipsToBounds = NO;
|
self.toolbar.clipsToBounds = NO;
|
||||||
@@ -450,7 +536,9 @@
|
|||||||
self.toolbar.userInteractionEnabled = YES;
|
self.toolbar.userInteractionEnabled = YES;
|
||||||
|
|
||||||
CGFloat labelInset = 5.0;
|
CGFloat labelInset = 5.0;
|
||||||
self.addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelInset, (self.view.bounds.size.height - FOOTER_HEIGHT), self.view.bounds.size.width - labelInset, LOCATIONBAR_HEIGHT)];
|
float locationBarY = toolbarIsAtBottom ? self.view.bounds.size.height - FOOTER_HEIGHT : self.view.bounds.size.height - LOCATIONBAR_HEIGHT;
|
||||||
|
|
||||||
|
self.addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelInset, locationBarY, self.view.bounds.size.width - labelInset, LOCATIONBAR_HEIGHT)];
|
||||||
self.addressLabel.adjustsFontSizeToFitWidth = NO;
|
self.addressLabel.adjustsFontSizeToFitWidth = NO;
|
||||||
self.addressLabel.alpha = 1.000;
|
self.addressLabel.alpha = 1.000;
|
||||||
self.addressLabel.autoresizesSubviews = YES;
|
self.addressLabel.autoresizesSubviews = YES;
|
||||||
@@ -463,23 +551,27 @@
|
|||||||
self.addressLabel.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}");
|
self.addressLabel.contentStretch = CGRectFromString(@"{{0, 0}, {1, 1}}");
|
||||||
self.addressLabel.enabled = YES;
|
self.addressLabel.enabled = YES;
|
||||||
self.addressLabel.hidden = NO;
|
self.addressLabel.hidden = NO;
|
||||||
self.addressLabel.lineBreakMode = UILineBreakModeTailTruncation;
|
self.addressLabel.lineBreakMode = NSLineBreakByTruncatingTail;
|
||||||
self.addressLabel.minimumFontSize = 10.000;
|
if (IsAtLeastiOSVersion(@"6.0")) {
|
||||||
|
self.addressLabel.minimumScaleFactor = 10.0/[UIFont labelFontSize];
|
||||||
|
} else {
|
||||||
|
self.addressLabel.minimumFontSize = 10.000;
|
||||||
|
}
|
||||||
self.addressLabel.multipleTouchEnabled = NO;
|
self.addressLabel.multipleTouchEnabled = NO;
|
||||||
self.addressLabel.numberOfLines = 1;
|
self.addressLabel.numberOfLines = 1;
|
||||||
self.addressLabel.opaque = NO;
|
self.addressLabel.opaque = NO;
|
||||||
self.addressLabel.shadowOffset = CGSizeMake(0.0, -1.0);
|
self.addressLabel.shadowOffset = CGSizeMake(0.0, -1.0);
|
||||||
self.addressLabel.text = @"Loading...";
|
self.addressLabel.text = NSLocalizedString(@"Loading...", nil);
|
||||||
self.addressLabel.textAlignment = UITextAlignmentLeft;
|
self.addressLabel.textAlignment = NSTextAlignmentLeft;
|
||||||
self.addressLabel.textColor = [UIColor colorWithWhite:1.000 alpha:1.000];
|
self.addressLabel.textColor = [UIColor colorWithWhite:1.000 alpha:1.000];
|
||||||
self.addressLabel.userInteractionEnabled = NO;
|
self.addressLabel.userInteractionEnabled = NO;
|
||||||
|
|
||||||
NSString* frontArrowString = @"►"; // create arrow from Unicode char
|
NSString* frontArrowString = NSLocalizedString(@"►", nil); // create arrow from Unicode char
|
||||||
self.forwardButton = [[UIBarButtonItem alloc] initWithTitle:frontArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goForward:)];
|
self.forwardButton = [[UIBarButtonItem alloc] initWithTitle:frontArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goForward:)];
|
||||||
self.forwardButton.enabled = YES;
|
self.forwardButton.enabled = YES;
|
||||||
self.forwardButton.imageInsets = UIEdgeInsetsZero;
|
self.forwardButton.imageInsets = UIEdgeInsetsZero;
|
||||||
|
|
||||||
NSString* backArrowString = @"◄"; // create arrow from Unicode char
|
NSString* backArrowString = NSLocalizedString(@"◄", nil); // create arrow from Unicode char
|
||||||
self.backButton = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goBack:)];
|
self.backButton = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goBack:)];
|
||||||
self.backButton.enabled = YES;
|
self.backButton.enabled = YES;
|
||||||
self.backButton.imageInsets = UIEdgeInsetsZero;
|
self.backButton.imageInsets = UIEdgeInsetsZero;
|
||||||
@@ -492,6 +584,11 @@
|
|||||||
[self.view addSubview:self.spinner];
|
[self.view addSubview:self.spinner];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setWebViewFrame : (CGRect) frame {
|
||||||
|
NSLog(@"Setting the WebView's frame to %@", NSStringFromCGRect(frame));
|
||||||
|
[self.webView setFrame:frame];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setCloseButtonTitle:(NSString*)title
|
- (void)setCloseButtonTitle:(NSString*)title
|
||||||
{
|
{
|
||||||
// the advantage of using UIBarButtonSystemItemDone is the system will localize it for you automatically
|
// the advantage of using UIBarButtonSystemItemDone is the system will localize it for you automatically
|
||||||
@@ -526,7 +623,7 @@
|
|||||||
|
|
||||||
CGRect webViewBounds = self.view.bounds;
|
CGRect webViewBounds = self.view.bounds;
|
||||||
webViewBounds.size.height -= FOOTER_HEIGHT;
|
webViewBounds.size.height -= FOOTER_HEIGHT;
|
||||||
self.webView.frame = webViewBounds;
|
[self setWebViewFrame:webViewBounds];
|
||||||
|
|
||||||
locationbarFrame.origin.y = webViewBounds.size.height;
|
locationbarFrame.origin.y = webViewBounds.size.height;
|
||||||
self.addressLabel.frame = locationbarFrame;
|
self.addressLabel.frame = locationbarFrame;
|
||||||
@@ -535,7 +632,7 @@
|
|||||||
|
|
||||||
CGRect webViewBounds = self.view.bounds;
|
CGRect webViewBounds = self.view.bounds;
|
||||||
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
|
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
|
||||||
self.webView.frame = webViewBounds;
|
[self setWebViewFrame:webViewBounds];
|
||||||
|
|
||||||
locationbarFrame.origin.y = webViewBounds.size.height;
|
locationbarFrame.origin.y = webViewBounds.size.height;
|
||||||
self.addressLabel.frame = locationbarFrame;
|
self.addressLabel.frame = locationbarFrame;
|
||||||
@@ -549,17 +646,15 @@
|
|||||||
// webView take up whole height less toolBar height
|
// webView take up whole height less toolBar height
|
||||||
CGRect webViewBounds = self.view.bounds;
|
CGRect webViewBounds = self.view.bounds;
|
||||||
webViewBounds.size.height -= TOOLBAR_HEIGHT;
|
webViewBounds.size.height -= TOOLBAR_HEIGHT;
|
||||||
self.webView.frame = webViewBounds;
|
[self setWebViewFrame:webViewBounds];
|
||||||
} else {
|
} else {
|
||||||
// no toolBar, expand webView to screen dimensions
|
// no toolBar, expand webView to screen dimensions
|
||||||
|
[self setWebViewFrame:self.view.bounds];
|
||||||
CGRect webViewBounds = self.view.bounds;
|
|
||||||
self.webView.frame = webViewBounds;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)showToolBar:(BOOL)show
|
- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition
|
||||||
{
|
{
|
||||||
CGRect toolbarFrame = self.toolbar.frame;
|
CGRect toolbarFrame = self.toolbar.frame;
|
||||||
CGRect locationbarFrame = self.addressLabel.frame;
|
CGRect locationbarFrame = self.addressLabel.frame;
|
||||||
@@ -573,30 +668,31 @@
|
|||||||
|
|
||||||
if (show) {
|
if (show) {
|
||||||
self.toolbar.hidden = NO;
|
self.toolbar.hidden = NO;
|
||||||
|
CGRect webViewBounds = self.view.bounds;
|
||||||
|
|
||||||
if (locationbarVisible) {
|
if (locationbarVisible) {
|
||||||
// locationBar at the bottom, move locationBar up
|
// locationBar at the bottom, move locationBar up
|
||||||
// put toolBar at the bottom
|
// put toolBar at the bottom
|
||||||
|
|
||||||
CGRect webViewBounds = self.view.bounds;
|
|
||||||
webViewBounds.size.height -= FOOTER_HEIGHT;
|
webViewBounds.size.height -= FOOTER_HEIGHT;
|
||||||
self.webView.frame = webViewBounds;
|
|
||||||
|
|
||||||
locationbarFrame.origin.y = webViewBounds.size.height;
|
locationbarFrame.origin.y = webViewBounds.size.height;
|
||||||
self.addressLabel.frame = locationbarFrame;
|
self.addressLabel.frame = locationbarFrame;
|
||||||
|
|
||||||
toolbarFrame.origin.y = (webViewBounds.size.height + LOCATIONBAR_HEIGHT);
|
|
||||||
self.toolbar.frame = toolbarFrame;
|
self.toolbar.frame = toolbarFrame;
|
||||||
} else {
|
} else {
|
||||||
// no locationBar, so put toolBar at the bottom
|
// no locationBar, so put toolBar at the bottom
|
||||||
|
|
||||||
CGRect webViewBounds = self.view.bounds;
|
CGRect webViewBounds = self.view.bounds;
|
||||||
webViewBounds.size.height -= TOOLBAR_HEIGHT;
|
webViewBounds.size.height -= TOOLBAR_HEIGHT;
|
||||||
self.webView.frame = webViewBounds;
|
|
||||||
|
|
||||||
toolbarFrame.origin.y = webViewBounds.size.height;
|
|
||||||
self.toolbar.frame = toolbarFrame;
|
self.toolbar.frame = toolbarFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ([toolbarPosition isEqualToString:kInAppBrowserToolbarBarPositionTop]) {
|
||||||
|
toolbarFrame.origin.y = 0;
|
||||||
|
webViewBounds.origin.y += toolbarFrame.size.height;
|
||||||
|
[self setWebViewFrame:webViewBounds];
|
||||||
|
} else {
|
||||||
|
toolbarFrame.origin.y = (webViewBounds.size.height + LOCATIONBAR_HEIGHT);
|
||||||
|
}
|
||||||
|
[self setWebViewFrame:webViewBounds];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
self.toolbar.hidden = YES;
|
self.toolbar.hidden = YES;
|
||||||
|
|
||||||
@@ -607,16 +703,14 @@
|
|||||||
// webView take up whole height less locationBar height
|
// webView take up whole height less locationBar height
|
||||||
CGRect webViewBounds = self.view.bounds;
|
CGRect webViewBounds = self.view.bounds;
|
||||||
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
|
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
|
||||||
self.webView.frame = webViewBounds;
|
[self setWebViewFrame:webViewBounds];
|
||||||
|
|
||||||
// move locationBar down
|
// move locationBar down
|
||||||
locationbarFrame.origin.y = webViewBounds.size.height;
|
locationbarFrame.origin.y = webViewBounds.size.height;
|
||||||
self.addressLabel.frame = locationbarFrame;
|
self.addressLabel.frame = locationbarFrame;
|
||||||
} else {
|
} else {
|
||||||
// no locationBar, expand webView to screen dimensions
|
// no locationBar, expand webView to screen dimensions
|
||||||
|
[self setWebViewFrame:self.view.bounds];
|
||||||
CGRect webViewBounds = self.view.bounds;
|
|
||||||
self.webView.frame = webViewBounds;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -632,22 +726,29 @@
|
|||||||
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
|
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
|
||||||
[super viewDidUnload];
|
[super viewDidUnload];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||||
|
{
|
||||||
|
return UIStatusBarStyleDefault;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)close
|
- (void)close
|
||||||
{
|
{
|
||||||
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
|
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
|
||||||
|
|
||||||
if ([self respondsToSelector:@selector(presentingViewController)]) {
|
|
||||||
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
|
|
||||||
} else {
|
|
||||||
[[self parentViewController] dismissModalViewControllerAnimated:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.currentURL = nil;
|
self.currentURL = nil;
|
||||||
|
|
||||||
if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) {
|
if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) {
|
||||||
[self.navigationDelegate browserExit];
|
[self.navigationDelegate browserExit];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run later to avoid the "took a long time" log message.
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
if ([self respondsToSelector:@selector(presentingViewController)]) {
|
||||||
|
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
|
||||||
|
} else {
|
||||||
|
[[self parentViewController] dismissModalViewControllerAnimated:YES];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)navigateTo:(NSURL*)url
|
- (void)navigateTo:(NSURL*)url
|
||||||
@@ -674,6 +775,34 @@
|
|||||||
{
|
{
|
||||||
[self.webView goForward];
|
[self.webView goForward];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewWillAppear:(BOOL)animated
|
||||||
|
{
|
||||||
|
if (IsAtLeastiOSVersion(@"7.0")) {
|
||||||
|
[[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]];
|
||||||
|
}
|
||||||
|
[self rePositionViews];
|
||||||
|
|
||||||
|
[super viewWillAppear:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// On iOS 7 the status bar is part of the view's dimensions, therefore it's height has to be taken into account.
|
||||||
|
// The height of it could be hardcoded as 20 pixels, but that would assume that the upcoming releases of iOS won't
|
||||||
|
// change that value.
|
||||||
|
//
|
||||||
|
- (float) getStatusBarOffset {
|
||||||
|
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
|
||||||
|
float statusBarOffset = IsAtLeastiOSVersion(@"7.0") ? MIN(statusBarFrame.size.width, statusBarFrame.size.height) : 0.0;
|
||||||
|
return statusBarOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) rePositionViews {
|
||||||
|
if ([_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop]) {
|
||||||
|
[self.webView setFrame:CGRectMake(self.webView.frame.origin.x, TOOLBAR_HEIGHT, self.webView.frame.size.width, self.webView.frame.size.height)];
|
||||||
|
[self.toolbar setFrame:CGRectMake(self.toolbar.frame.origin.x, [self getStatusBarOffset], self.toolbar.frame.size.width, self.toolbar.frame.size.height)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark UIWebViewDelegate
|
#pragma mark UIWebViewDelegate
|
||||||
|
|
||||||
@@ -681,7 +810,7 @@
|
|||||||
{
|
{
|
||||||
// loading url, start spinner, update back/forward
|
// loading url, start spinner, update back/forward
|
||||||
|
|
||||||
self.addressLabel.text = @"Loading...";
|
self.addressLabel.text = NSLocalizedString(@"Loading...", nil);
|
||||||
self.backButton.enabled = theWebView.canGoBack;
|
self.backButton.enabled = theWebView.canGoBack;
|
||||||
self.forwardButton.enabled = theWebView.canGoForward;
|
self.forwardButton.enabled = theWebView.canGoForward;
|
||||||
|
|
||||||
@@ -732,13 +861,13 @@
|
|||||||
- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
|
- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
|
||||||
{
|
{
|
||||||
// log fail message, stop spinner, update back/forward
|
// log fail message, stop spinner, update back/forward
|
||||||
NSLog(@"webView:didFailLoadWithError - %@", [error localizedDescription]);
|
NSLog(@"webView:didFailLoadWithError - %ld: %@", (long)error.code, [error localizedDescription]);
|
||||||
|
|
||||||
self.backButton.enabled = theWebView.canGoBack;
|
self.backButton.enabled = theWebView.canGoBack;
|
||||||
self.forwardButton.enabled = theWebView.canGoForward;
|
self.forwardButton.enabled = theWebView.canGoForward;
|
||||||
[self.spinner stopAnimating];
|
[self.spinner stopAnimating];
|
||||||
|
|
||||||
self.addressLabel.text = @"Load Error";
|
self.addressLabel.text = NSLocalizedString(@"Load Error", nil);
|
||||||
|
|
||||||
[self.navigationDelegate webView:theWebView didFailLoadWithError:error];
|
[self.navigationDelegate webView:theWebView didFailLoadWithError:error];
|
||||||
}
|
}
|
||||||
@@ -782,6 +911,9 @@
|
|||||||
self.location = YES;
|
self.location = YES;
|
||||||
self.toolbar = YES;
|
self.toolbar = YES;
|
||||||
self.closebuttoncaption = nil;
|
self.closebuttoncaption = nil;
|
||||||
|
self.toolbarposition = kInAppBrowserToolbarBarPositionBottom;
|
||||||
|
self.clearcache = NO;
|
||||||
|
self.clearsessioncache = NO;
|
||||||
|
|
||||||
self.enableviewportscale = NO;
|
self.enableviewportscale = NO;
|
||||||
self.mediaplaybackrequiresuseraction = NO;
|
self.mediaplaybackrequiresuseraction = NO;
|
||||||
@@ -789,6 +921,7 @@
|
|||||||
self.keyboarddisplayrequiresuseraction = YES;
|
self.keyboarddisplayrequiresuseraction = YES;
|
||||||
self.suppressesincrementalrendering = NO;
|
self.suppressesincrementalrendering = NO;
|
||||||
self.hidden = NO;
|
self.hidden = NO;
|
||||||
|
self.disallowoverscroll = NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|||||||
69
src/ubuntu/InAppBrowser.qml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2013 Canonical Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtWebKit 3.0
|
||||||
|
import Ubuntu.Components.Popups 0.1
|
||||||
|
import Ubuntu.Components 0.1
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
id: inappbrowser
|
||||||
|
property string url1
|
||||||
|
Rectangle {
|
||||||
|
border.color: "black"
|
||||||
|
width: parent.width
|
||||||
|
height: urlEntry.height
|
||||||
|
color: "gray"
|
||||||
|
TextInput {
|
||||||
|
id: urlEntry
|
||||||
|
width: parent.width - closeButton.width
|
||||||
|
text: url1
|
||||||
|
activeFocusOnPress: false
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: closeButton
|
||||||
|
width: height
|
||||||
|
x: parent.width - width
|
||||||
|
height: parent.height
|
||||||
|
source: "close.png"
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
root.exec("InAppBrowser", "close", [0, 0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WebView {
|
||||||
|
width: parent.width
|
||||||
|
y: urlEntry.height
|
||||||
|
height: parent.height - y
|
||||||
|
url: url1
|
||||||
|
onLoadingChanged: {
|
||||||
|
if (loadRequest.status) {
|
||||||
|
root.exec("InAppBrowser", "loadFinished", [loadRequest.status])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
src/ubuntu/close.png
Normal file
|
After Width: | Height: | Size: 461 B |
106
src/ubuntu/inappbrowser.cpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2013 Canonical Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QQuickView>
|
||||||
|
#include <QQuickItem>
|
||||||
|
|
||||||
|
#include "inappbrowser.h"
|
||||||
|
#include <cordova.h>
|
||||||
|
|
||||||
|
Inappbrowser::Inappbrowser(Cordova *cordova): CPlugin(cordova), _eventCb(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
const char code[] = "\
|
||||||
|
var component, object; \
|
||||||
|
function createObject() { \
|
||||||
|
component = Qt.createComponent(%1); \
|
||||||
|
if (component.status == Component.Ready) \
|
||||||
|
finishCreation(); \
|
||||||
|
else \
|
||||||
|
component.statusChanged.connect(finishCreation); \
|
||||||
|
} \
|
||||||
|
function finishCreation() { \
|
||||||
|
CordovaWrapper.object = component.createObject(root, \
|
||||||
|
{root: root, cordova: cordova, url1: %2}); \
|
||||||
|
} \
|
||||||
|
createObject()";
|
||||||
|
|
||||||
|
const char EXIT_EVENT[] = "'exit'";
|
||||||
|
const char LOADSTART_EVENT[] = "'loadstart'";
|
||||||
|
const char LOADSTOP_EVENT[] = "'loadstop'";
|
||||||
|
const char LOADERROR_EVENT[] = "'loaderror'";
|
||||||
|
|
||||||
|
void Inappbrowser::open(int cb, int, const QString &url, const QString &windowName, const QString &windowFeatures) {
|
||||||
|
assert(_eventCb == 0);
|
||||||
|
|
||||||
|
_eventCb = cb;
|
||||||
|
|
||||||
|
QString path = m_cordova->get_app_dir() + "/../qml/InAppBrowser.qml";
|
||||||
|
|
||||||
|
// TODO: relative url
|
||||||
|
QString qml = QString(code)
|
||||||
|
.arg(CordovaInternal::format(path)).arg(CordovaInternal::format(url));
|
||||||
|
m_cordova->execQML(qml);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inappbrowser::show(int, int) {
|
||||||
|
m_cordova->execQML("CordovaWrapper.object.visible = true");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inappbrowser::close(int, int) {
|
||||||
|
m_cordova->execQML("CordovaWrapper.object.destroy()");
|
||||||
|
this->callbackWithoutRemove(_eventCb, EXIT_EVENT);
|
||||||
|
_eventCb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inappbrowser::injectStyleFile(int cb, int, const QString&, bool) {
|
||||||
|
// TODO:
|
||||||
|
qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inappbrowser::injectStyleCode(int cb, int, const QString&, bool) {
|
||||||
|
// TODO:
|
||||||
|
qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inappbrowser::injectScriptFile(int cb, int, const QString&, bool) {
|
||||||
|
// TODO:
|
||||||
|
qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inappbrowser::injectScriptCode(int cb, int, const QString&, bool) {
|
||||||
|
// TODO:
|
||||||
|
qCritical() << "unimplemented " << __PRETTY_FUNCTION__;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Inappbrowser::loadFinished(int status) {
|
||||||
|
if (status == 2) {
|
||||||
|
this->callbackWithoutRemove(_eventCb, LOADERROR_EVENT);
|
||||||
|
}
|
||||||
|
if (status == 0) {
|
||||||
|
this->callbackWithoutRemove(_eventCb, LOADSTART_EVENT);
|
||||||
|
}
|
||||||
|
if (status == 3) {
|
||||||
|
this->callbackWithoutRemove(_eventCb, LOADSTOP_EVENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/ubuntu/inappbrowser.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2013 Canonical Ltd.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef INAPPBROWSER_H
|
||||||
|
#define INAPPBROWSER_H
|
||||||
|
|
||||||
|
#include <QtCore>
|
||||||
|
#include <cplugin.h>
|
||||||
|
|
||||||
|
class Inappbrowser: public CPlugin {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
Inappbrowser(Cordova *cordova);
|
||||||
|
|
||||||
|
virtual const QString fullName() override {
|
||||||
|
return Inappbrowser::fullID();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const QString shortName() override {
|
||||||
|
return "InAppBrowser";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QString fullID() {
|
||||||
|
return "InAppBrowser";
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void open(int cb, int, const QString &url, const QString &windowName, const QString &windowFeatures);
|
||||||
|
void show(int, int);
|
||||||
|
void close(int, int);
|
||||||
|
void injectStyleFile(int cb, int, const QString&, bool);
|
||||||
|
void injectStyleCode(int cb, int, const QString&, bool);
|
||||||
|
void injectScriptFile(int cb, int, const QString&, bool);
|
||||||
|
void injectScriptCode(int cb, int, const QString&, bool);
|
||||||
|
|
||||||
|
void loadFinished(int status);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _eventCb;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,21 +1,38 @@
|
|||||||
using System;
|
/*
|
||||||
using System.Net;
|
Licensed 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Documents;
|
|
||||||
using System.Windows.Ink;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Animation;
|
|
||||||
using System.Windows.Shapes;
|
|
||||||
using Microsoft.Phone.Controls;
|
using Microsoft.Phone.Controls;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Runtime.Serialization;
|
|
||||||
using WPCordovaClassLib.Cordova;
|
|
||||||
using WPCordovaClassLib.Cordova.Commands;
|
|
||||||
using WPCordovaClassLib.Cordova.JSON;
|
|
||||||
using Microsoft.Phone.Shell;
|
using Microsoft.Phone.Shell;
|
||||||
|
|
||||||
|
#if WP8
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.ApplicationModel;
|
||||||
|
using Windows.Storage;
|
||||||
|
using Windows.System;
|
||||||
|
|
||||||
|
//Use alias in case Cordova File Plugin is enabled. Then the File class will be declared in both and error will occur.
|
||||||
|
using IOFile = System.IO.File;
|
||||||
|
#else
|
||||||
using Microsoft.Phone.Tasks;
|
using Microsoft.Phone.Tasks;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace WPCordovaClassLib.Cordova.Commands
|
namespace WPCordovaClassLib.Cordova.Commands
|
||||||
{
|
{
|
||||||
@@ -36,12 +53,47 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
private static ApplicationBarIconButton backButton;
|
private static ApplicationBarIconButton backButton;
|
||||||
private static ApplicationBarIconButton fwdButton;
|
private static ApplicationBarIconButton fwdButton;
|
||||||
|
|
||||||
|
protected ApplicationBar AppBar;
|
||||||
|
|
||||||
|
protected bool ShowLocation {get;set;}
|
||||||
|
protected bool StartHidden {get;set;}
|
||||||
|
|
||||||
public void open(string options)
|
public void open(string options)
|
||||||
{
|
{
|
||||||
|
// reset defaults on ShowLocation + StartHidden features
|
||||||
|
ShowLocation = true;
|
||||||
|
StartHidden = false;
|
||||||
|
|
||||||
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||||
//BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
|
//BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
|
||||||
string urlLoc = args[0];
|
string urlLoc = args[0];
|
||||||
string target = args[1];
|
string target = args[1];
|
||||||
|
string featString = args[2];
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(featString))
|
||||||
|
{
|
||||||
|
string[] features = featString.Split(',');
|
||||||
|
foreach (string str in features)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] split = str.Split('=');
|
||||||
|
switch (split[0])
|
||||||
|
{
|
||||||
|
case "location":
|
||||||
|
ShowLocation = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase);
|
||||||
|
break;
|
||||||
|
case "hidden":
|
||||||
|
StartHidden = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// some sort of invalid param was passed, moving on ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
_self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
|
_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
|
_blank - always open in the InAppBrowser
|
||||||
@@ -59,8 +111,96 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
ShowSystemBrowser(urlLoc);
|
ShowSystemBrowser(urlLoc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(string options)
|
||||||
|
{
|
||||||
|
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||||
|
|
||||||
|
|
||||||
|
if (browser != null)
|
||||||
|
{
|
||||||
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||||
|
{
|
||||||
|
browser.Visibility = Visibility.Visible;
|
||||||
|
AppBar.IsVisible = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void injectScriptCode(string options)
|
||||||
|
{
|
||||||
|
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||||
|
|
||||||
|
bool bCallback = false;
|
||||||
|
if (bool.TryParse(args[1], out bCallback)) { };
|
||||||
|
|
||||||
|
string callbackId = args[2];
|
||||||
|
|
||||||
|
if (browser != null)
|
||||||
|
{
|
||||||
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||||
|
{
|
||||||
|
var res = browser.InvokeScript("eval", new string[] { args[0] });
|
||||||
|
|
||||||
|
if (bCallback)
|
||||||
|
{
|
||||||
|
PluginResult result = new PluginResult(PluginResult.Status.OK, res.ToString());
|
||||||
|
result.KeepCallback = false;
|
||||||
|
this.DispatchCommandResult(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void injectScriptFile(string options)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Error : Windows Phone org.apache.cordova.inappbrowser does not currently support executeScript");
|
||||||
|
string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||||
|
// throw new NotImplementedException("Windows Phone does not currently support 'executeScript'");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void injectStyleCode(string options)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Error : Windows Phone org.apache.cordova.inappbrowser does not currently support insertCSS");
|
||||||
|
return;
|
||||||
|
|
||||||
|
//string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||||
|
//bool bCallback = false;
|
||||||
|
//if (bool.TryParse(args[1], out bCallback)) { };
|
||||||
|
|
||||||
|
//string callbackId = args[2];
|
||||||
|
|
||||||
|
//if (browser != null)
|
||||||
|
//{
|
||||||
|
//Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||||
|
//{
|
||||||
|
// if (bCallback)
|
||||||
|
// {
|
||||||
|
// string cssInsertString = "try{(function(doc){var c = '<style>body{background-color:#ffff00;}</style>'; doc.head.innerHTML += c;})(document);}catch(ex){alert('oops : ' + ex.message);}";
|
||||||
|
// //cssInsertString = cssInsertString.Replace("_VALUE_", args[0]);
|
||||||
|
// Debug.WriteLine("cssInsertString = " + cssInsertString);
|
||||||
|
// var res = browser.InvokeScript("eval", new string[] { cssInsertString });
|
||||||
|
// if (bCallback)
|
||||||
|
// {
|
||||||
|
// PluginResult result = new PluginResult(PluginResult.Status.OK, res.ToString());
|
||||||
|
// result.KeepCallback = false;
|
||||||
|
// this.DispatchCommandResult(result);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
//});
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void injectStyleFile(string options)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("Error : Windows Phone org.apache.cordova.inappbrowser does not currently support insertCSS");
|
||||||
|
return;
|
||||||
|
|
||||||
|
//string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
|
||||||
|
//throw new NotImplementedException("Windows Phone does not currently support 'insertCSS'");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowCordovaBrowser(string url)
|
private void ShowCordovaBrowser(string url)
|
||||||
@@ -86,17 +226,57 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if WP8
|
||||||
|
private async void ShowSystemBrowser(string url)
|
||||||
|
{
|
||||||
|
var pathUri = new Uri(url, UriKind.Absolute);
|
||||||
|
if (pathUri.Scheme == Uri.UriSchemeHttp || pathUri.Scheme == Uri.UriSchemeHttps)
|
||||||
|
{
|
||||||
|
await Launcher.LaunchUriAsync(pathUri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var file = await GetFile(pathUri.AbsolutePath.Replace('/', Path.DirectorySeparatorChar));
|
||||||
|
if (file != null)
|
||||||
|
{
|
||||||
|
await Launcher.LaunchFileAsync(file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.WriteLine("File not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<StorageFile> GetFile(string fileName)
|
||||||
|
{
|
||||||
|
//first try to get the file from the isolated storage
|
||||||
|
var localFolder = ApplicationData.Current.LocalFolder;
|
||||||
|
if (IOFile.Exists(Path.Combine(localFolder.Path, fileName)))
|
||||||
|
{
|
||||||
|
return await localFolder.GetFileAsync(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if file is not found try to get it from the xap
|
||||||
|
var filePath = Path.Combine(Package.Current.InstalledLocation.Path, fileName);
|
||||||
|
if (IOFile.Exists(filePath))
|
||||||
|
{
|
||||||
|
return await StorageFile.GetFileFromPathAsync(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
#else
|
||||||
private void ShowSystemBrowser(string url)
|
private void ShowSystemBrowser(string url)
|
||||||
{
|
{
|
||||||
WebBrowserTask webBrowserTask = new WebBrowserTask();
|
WebBrowserTask webBrowserTask = new WebBrowserTask();
|
||||||
webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
|
webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
|
||||||
webBrowserTask.Show();
|
webBrowserTask.Show();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private void ShowInAppBrowser(string url)
|
private void ShowInAppBrowser(string url)
|
||||||
{
|
{
|
||||||
Uri loc = new Uri(url);
|
Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
|
||||||
|
|
||||||
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
Deployment.Current.Dispatcher.BeginInvoke(() =>
|
||||||
{
|
{
|
||||||
@@ -127,6 +307,12 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
|
browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
|
||||||
browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
|
browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
|
||||||
browser.Navigate(loc);
|
browser.Navigate(loc);
|
||||||
|
|
||||||
|
if (StartHidden)
|
||||||
|
{
|
||||||
|
browser.Visibility = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
|
||||||
//browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
|
//browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
|
||||||
grid.Children.Add(browser);
|
grid.Children.Add(browser);
|
||||||
}
|
}
|
||||||
@@ -156,6 +342,11 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
bar.Buttons.Add(closeBtn);
|
bar.Buttons.Add(closeBtn);
|
||||||
|
|
||||||
page.ApplicationBar = bar;
|
page.ApplicationBar = bar;
|
||||||
|
bar.IsVisible = !StartHidden;
|
||||||
|
AppBar = bar;
|
||||||
|
|
||||||
|
page.BackKeyPress += page_BackKeyPress;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -163,6 +354,23 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
|
{
|
||||||
|
#if WP8
|
||||||
|
if (browser.CanGoBack)
|
||||||
|
{
|
||||||
|
browser.GoBack();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
e.Cancel = true;
|
||||||
|
#else
|
||||||
|
browser.InvokeScript("execScript", "history.back();");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
|
void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -195,7 +403,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
{
|
{
|
||||||
#if WP8
|
#if WP8
|
||||||
browser.GoBack();
|
browser.GoBack();
|
||||||
#else
|
#else
|
||||||
browser.InvokeScript("execScript", "history.back();");
|
browser.InvokeScript("execScript", "history.back();");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -230,8 +438,10 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
grid.Children.Remove(browser);
|
grid.Children.Remove(browser);
|
||||||
}
|
}
|
||||||
page.ApplicationBar = null;
|
page.ApplicationBar = null;
|
||||||
|
page.BackKeyPress -= page_BackKeyPress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
browser = null;
|
browser = null;
|
||||||
string message = "{\"type\":\"exit\"}";
|
string message = "{\"type\":\"exit\"}";
|
||||||
PluginResult result = new PluginResult(PluginResult.Status.OK, message);
|
PluginResult result = new PluginResult(PluginResult.Status.OK, message);
|
||||||
@@ -251,7 +461,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.AbsoluteUri + "\"}";
|
string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.OriginalString + "\"}";
|
||||||
PluginResult result = new PluginResult(PluginResult.Status.OK, message);
|
PluginResult result = new PluginResult(PluginResult.Status.OK, message);
|
||||||
result.KeepCallback = true;
|
result.KeepCallback = true;
|
||||||
this.DispatchCommandResult(result);
|
this.DispatchCommandResult(result);
|
||||||
@@ -259,7 +469,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
|
|
||||||
void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
|
void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
|
||||||
{
|
{
|
||||||
string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
|
string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.OriginalString + "\"}";
|
||||||
PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
|
PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
|
||||||
result.KeepCallback = true;
|
result.KeepCallback = true;
|
||||||
this.DispatchCommandResult(result);
|
this.DispatchCommandResult(result);
|
||||||
@@ -267,11 +477,11 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
|
|
||||||
void browser_Navigating(object sender, NavigatingEventArgs e)
|
void browser_Navigating(object sender, NavigatingEventArgs e)
|
||||||
{
|
{
|
||||||
string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.AbsoluteUri + "\"}";
|
string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.OriginalString + "\"}";
|
||||||
PluginResult result = new PluginResult(PluginResult.Status.OK, message);
|
PluginResult result = new PluginResult(PluginResult.Status.OK, message);
|
||||||
result.KeepCallback = true;
|
result.KeepCallback = true;
|
||||||
this.DispatchCommandResult(result);
|
this.DispatchCommandResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
test/.DS_Store
vendored
70
test/cordova-incl.js
vendored
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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('<script type="text/javascript" charset="utf-8" src="' + cordovaPath + '"></script>');
|
|
||||||
}
|
|
||||||
|
|
||||||
function backHome() {
|
|
||||||
if (window.device && device.platform && device.platform.toLowerCase() == 'android') {
|
|
||||||
navigator.app.backHistory();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
window.history.go(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,258 +0,0 @@
|
|||||||
<!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>
|
|
||||||
<h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
<!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>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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";
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
<!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>
|
|
||||||
</head>
|
|
||||||
<body id="stage" class="theme">
|
|
||||||
<h1>InAppBrowser - Local URL</h1>
|
|
||||||
<div id="info">
|
|
||||||
You have successfully loaded a local URL
|
|
||||||
</div>
|
|
||||||
<div>User-Agent = <span id="u-a"></span></div>
|
|
||||||
<div><a href="http://www.google.com">Visit Google</a></div>
|
|
||||||
<div><a href="http://www.yahoo.com">Visit Yahoo</a></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>
|
|
||||||
<h2> </h2><div class="backBtn" onclick="backHome();">Back</div>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
function updateUserAgent() {
|
|
||||||
document.getElementById("u-a").textContent = navigator.userAgent;
|
|
||||||
}
|
|
||||||
updateUserAgent();
|
|
||||||
window.setInterval(updateUserAgent, 1500);
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
<!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 onload="init();" id="stage" class="theme">
|
|
||||||
<h1>Apache Cordova Tests</h1>
|
|
||||||
<div id="info">
|
|
||||||
<h4>Platform: <span id="platform"> </span></h4>
|
|
||||||
<h4>Version: <span id="version"> </span></h4>
|
|
||||||
<h4>UUID: <span id="uuid"> </span></h4>
|
|
||||||
<h4>Name: <span id="name"> </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="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>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
163
test/main.js
@@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
164
test/master.css
@@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* 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%;
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
var exec = require('cordova/exec');
|
var exec = require('cordova/exec');
|
||||||
var channel = require('cordova/channel');
|
var channel = require('cordova/channel');
|
||||||
var modulemapper = require('cordova/modulemapper');
|
var modulemapper = require('cordova/modulemapper');
|
||||||
|
var urlutil = require('cordova/urlutil');
|
||||||
|
|
||||||
function InAppBrowser() {
|
function InAppBrowser() {
|
||||||
this.channels = {
|
this.channels = {
|
||||||
@@ -77,17 +78,20 @@ InAppBrowser.prototype = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
module.exports = function(strUrl, strWindowName, strWindowFeatures) {
|
module.exports = function(strUrl, strWindowName, strWindowFeatures) {
|
||||||
var iab = new InAppBrowser();
|
|
||||||
var cb = function(eventname) {
|
|
||||||
iab._eventHandler(eventname);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Don't catch calls that write to existing frames (e.g. named iframes).
|
// Don't catch calls that write to existing frames (e.g. named iframes).
|
||||||
if (window.frames && window.frames[strWindowName]) {
|
if (window.frames && window.frames[strWindowName]) {
|
||||||
var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
|
var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
|
||||||
return origOpenFunc.apply(window, arguments);
|
return origOpenFunc.apply(window, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strUrl = urlutil.makeAbsolute(strUrl);
|
||||||
|
var iab = new InAppBrowser();
|
||||||
|
var cb = function(eventname) {
|
||||||
|
iab._eventHandler(eventname);
|
||||||
|
};
|
||||||
|
|
||||||
|
strWindowFeatures = strWindowFeatures || "";
|
||||||
|
|
||||||
exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
|
exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
|
||||||
return iab;
|
return iab;
|
||||||
};
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
cordova.define("org.apache.cordova.inappbrowser.InAppBrowserProxy", function(require, exports, module) { /*
|
/*
|
||||||
*
|
*
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
* or more contributor license agreements. See the NOTICE file
|
* or more contributor license agreements. See the NOTICE file
|
||||||
@@ -19,7 +19,8 @@ cordova.define("org.apache.cordova.inappbrowser.InAppBrowserProxy", function(req
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*global Windows:true */
|
/*jslint sloppy:true */
|
||||||
|
/*global Windows:true, require, document, setTimeout, window, module */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -30,27 +31,29 @@ var browserWrap;
|
|||||||
|
|
||||||
var IAB = {
|
var IAB = {
|
||||||
|
|
||||||
close: function (win,lose) {
|
close: function (win, lose) {
|
||||||
if (browserWrap) {
|
if (browserWrap) {
|
||||||
browserWrap.parentNode.removeChild(browserWrap);
|
browserWrap.parentNode.removeChild(browserWrap);
|
||||||
browserWrap = null;
|
browserWrap = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
show: function (win,lose) {
|
show: function (win, lose) {
|
||||||
|
/* empty block, ran out of bacon?
|
||||||
if (browserWrap) {
|
if (browserWrap) {
|
||||||
|
|
||||||
}
|
}*/
|
||||||
},
|
},
|
||||||
open: function (win,lose,args) {
|
open: function (win, lose, args) {
|
||||||
var strUrl = args[0];
|
var strUrl = args[0],
|
||||||
var target = args[1];
|
target = args[1],
|
||||||
var features = args[2];
|
features = args[2],
|
||||||
|
url,
|
||||||
|
elem;
|
||||||
|
|
||||||
if (target == "_system") {
|
if (target === "_system") {
|
||||||
var url = new Windows.Foundation.Uri(strUrl)
|
url = new Windows.Foundation.Uri(strUrl);
|
||||||
Windows.System.Launcher.launchUriAsync(url);
|
Windows.System.Launcher.launchUriAsync(url);
|
||||||
}
|
} else if (target === "_blank") {
|
||||||
else if (target == "_blank") {
|
|
||||||
if (!browserWrap) {
|
if (!browserWrap) {
|
||||||
browserWrap = document.createElement("div");
|
browserWrap = document.createElement("div");
|
||||||
browserWrap.style.position = "absolute";
|
browserWrap.style.position = "absolute";
|
||||||
@@ -64,28 +67,27 @@ var IAB = {
|
|||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
IAB.close();
|
IAB.close();
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
};
|
||||||
|
|
||||||
document.body.appendChild(browserWrap);
|
document.body.appendChild(browserWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
var elem = document.createElement("iframe");
|
elem = document.createElement("iframe");
|
||||||
elem.style.width = (window.innerWidth - 80)+ "px";
|
elem.style.width = (window.innerWidth - 80) + "px";
|
||||||
elem.style.height = (window.innerHeight - 80) + "px";
|
elem.style.height = (window.innerHeight - 80) + "px";
|
||||||
elem.style.borderWidth = "0px";
|
elem.style.borderWidth = "0px";
|
||||||
elem.name = "targetFrame";
|
elem.name = "targetFrame";
|
||||||
elem.src = strUrl;
|
elem.src = strUrl;
|
||||||
|
|
||||||
window.addEventListener("resize", function () {
|
window.addEventListener("resize", function () {
|
||||||
if (browserWrap && elem) {
|
if (browserWrap && elem) {
|
||||||
elem.style.width = (window.innerWidth - 80) + "px";
|
elem.style.width = (window.innerWidth - 80) + "px";
|
||||||
elem.style.height = (window.innerHeight - 80) + "px";
|
elem.style.height = (window.innerHeight - 80) + "px";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
browserWrap.appendChild(elem);
|
browserWrap.appendChild(elem);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
window.location = strUrl;
|
window.location = strUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,12 +95,12 @@ var IAB = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
injectScriptCode:function(code, bCB) {
|
injectScriptCode: function (code, bCB) {
|
||||||
|
|
||||||
// "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)"
|
// "(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)"
|
||||||
},
|
},
|
||||||
|
|
||||||
injectScriptFile:function(file, bCB) {
|
injectScriptFile: function (file, bCB) {
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -106,4 +108,4 @@ var IAB = {
|
|||||||
module.exports = IAB;
|
module.exports = IAB;
|
||||||
|
|
||||||
|
|
||||||
require("cordova/windows8/commandProxy").add("InAppBrowser",module.exports);
|
require("cordova/exec/proxy").add("InAppBrowser", module.exports);
|
||||||
|
|||||||