mirror of
https://github.com/shuto-cn/cordova-plugin-inappbrowser.git
synced 2026-05-04 00:00:06 +08:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 |
@@ -32,3 +32,26 @@
|
|||||||
* 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'
|
||||||
|
|||||||
+27
-1
@@ -2,12 +2,18 @@
|
|||||||
|
|
||||||
<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.2.5">
|
||||||
|
|
||||||
<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>
|
||||||
|
<engine name="cordova" version=">=3.1.0" /><!-- Needs cordova/urlutil -->
|
||||||
|
</engines>
|
||||||
|
|
||||||
<js-module src="www/InAppBrowser.js" name="InAppBrowser">
|
<js-module src="www/InAppBrowser.js" name="InAppBrowser">
|
||||||
<clobbers target="window.open" />
|
<clobbers target="window.open" />
|
||||||
@@ -25,6 +31,26 @@
|
|||||||
<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" />
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
|
<!-- amazon-fireos -->
|
||||||
|
<platform name="amazon-fireos">
|
||||||
|
<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">
|
||||||
|
<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">
|
||||||
<config-file target="config.xml" parent="/*">
|
<config-file target="config.xml" parent="/*">
|
||||||
|
|||||||
@@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+165
-165
@@ -18,20 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
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 android.app.Dialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -52,11 +38,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 +46,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 {
|
||||||
|
|
||||||
@@ -100,120 +95,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 +250,14 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
} else {
|
} else {
|
||||||
scriptToInject = source;
|
scriptToInject = source;
|
||||||
}
|
}
|
||||||
|
final String finalScriptToInject = scriptToInject;
|
||||||
// This action will have the side-effect of blurring the currently focused element
|
// This action will have the side-effect of blurring the currently focused element
|
||||||
this.inAppWebView.loadUrl("javascript:" + scriptToInject);
|
this.cordova.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
inAppWebView.loadUrl("javascript:" + finalScriptToInject);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,20 +289,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.
|
||||||
*
|
*
|
||||||
@@ -311,30 +312,30 @@ 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.loadUrl("about:blank");
|
||||||
|
if (dialog != null) {
|
||||||
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
});
|
||||||
|
try {
|
||||||
this.cordova.getActivity().runOnUiThread(runnable);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -438,14 +439,7 @@ public class InAppBrowser extends CordovaPlugin {
|
|||||||
dialog.setCancelable(true);
|
dialog.setCancelable(true);
|
||||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
|
||||||
public void onDismiss(DialogInterface dialog) {
|
public void onDismiss(DialogInterface dialog) {
|
||||||
try {
|
closeDialog();
|
||||||
JSONObject obj = new JSONObject();
|
|
||||||
obj.put("type", EXIT_EVENT);
|
|
||||||
|
|
||||||
sendUpdate(obj, false);
|
|
||||||
} catch (JSONException e) {
|
|
||||||
Log.d(LOG_TAG, "Should never happen");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -620,10 +614,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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+42
-10
@@ -32,6 +32,11 @@
|
|||||||
|
|
||||||
#pragma mark CDVInAppBrowser
|
#pragma mark CDVInAppBrowser
|
||||||
|
|
||||||
|
@interface CDVInAppBrowser () {
|
||||||
|
UIStatusBarStyle _previousStatusBarStyle;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation CDVInAppBrowser
|
@implementation CDVInAppBrowser
|
||||||
|
|
||||||
- (CDVInAppBrowser*)initWithWebView:(UIWebView*)theWebView
|
- (CDVInAppBrowser*)initWithWebView:(UIWebView*)theWebView
|
||||||
@@ -51,12 +56,8 @@
|
|||||||
|
|
||||||
- (void)close:(CDVInvokedUrlCommand*)command
|
- (void)close:(CDVInvokedUrlCommand*)command
|
||||||
{
|
{
|
||||||
if (self.inAppBrowserViewController != nil) {
|
// Things are cleaned up in browserExit.
|
||||||
[self.inAppBrowserViewController close];
|
[self.inAppBrowserViewController close];
|
||||||
self.inAppBrowserViewController = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.callbackId = nil;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isSystemUrl:(NSURL*)url
|
- (BOOL) isSystemUrl:(NSURL*)url
|
||||||
@@ -115,6 +116,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
|
||||||
|
|
||||||
CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options];
|
CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options];
|
||||||
[self.inAppBrowserViewController showLocationBar:browserOptions.location];
|
[self.inAppBrowserViewController showLocationBar:browserOptions.location];
|
||||||
@@ -155,8 +157,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! browserOptions.hidden) {
|
if (! browserOptions.hidden) {
|
||||||
|
|
||||||
|
UINavigationController* nav = [[UINavigationController alloc]
|
||||||
|
initWithRootViewController:self.inAppBrowserViewController];
|
||||||
|
nav.navigationBarHidden = YES;
|
||||||
|
|
||||||
if (self.viewController.modalViewController != self.inAppBrowserViewController) {
|
if (self.viewController.modalViewController != self.inAppBrowserViewController) {
|
||||||
[self.viewController presentModalViewController:self.inAppBrowserViewController animated:YES];
|
[self.viewController presentModalViewController:nav animated:YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[self.inAppBrowserViewController navigateTo:url];
|
[self.inAppBrowserViewController navigateTo:url];
|
||||||
@@ -166,7 +173,13 @@
|
|||||||
{
|
{
|
||||||
if ([self.inAppBrowserViewController isViewLoaded] && self.inAppBrowserViewController.view.window)
|
if ([self.inAppBrowserViewController isViewLoaded] && self.inAppBrowserViewController.view.window)
|
||||||
return;
|
return;
|
||||||
[self.viewController presentModalViewController:self.inAppBrowserViewController animated:YES];
|
|
||||||
|
_previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
|
||||||
|
|
||||||
|
UINavigationController* nav = [[UINavigationController alloc]
|
||||||
|
initWithRootViewController:self.inAppBrowserViewController];
|
||||||
|
nav.navigationBarHidden = YES;
|
||||||
|
[self.viewController presentModalViewController:nav animated:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options
|
- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options
|
||||||
@@ -355,13 +368,18 @@
|
|||||||
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;
|
||||||
|
|
||||||
|
if (IsAtLeastiOSVersion(@"7.0")) {
|
||||||
|
[[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -632,6 +650,11 @@
|
|||||||
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
|
[CDVUserAgentUtil releaseLock:&_userAgentLockToken];
|
||||||
[super viewDidUnload];
|
[super viewDidUnload];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIStatusBarStyle)preferredStatusBarStyle
|
||||||
|
{
|
||||||
|
return UIStatusBarStyleDefault;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)close
|
- (void)close
|
||||||
{
|
{
|
||||||
@@ -674,6 +697,15 @@
|
|||||||
{
|
{
|
||||||
[self.webView goForward];
|
[self.webView goForward];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewWillAppear:(BOOL)animated
|
||||||
|
{
|
||||||
|
if (IsAtLeastiOSVersion(@"7.0")) {
|
||||||
|
[[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]];
|
||||||
|
}
|
||||||
|
|
||||||
|
[super viewWillAppear:animated];
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark UIWebViewDelegate
|
#pragma mark UIWebViewDelegate
|
||||||
|
|
||||||
|
|||||||
@@ -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])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 461 B |
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
+137
-6
@@ -36,12 +36,45 @@ 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];
|
||||||
|
|
||||||
|
string[] features = featString.Split(',');
|
||||||
|
foreach (string str in features)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] split = str.Split('=');
|
||||||
|
switch (split[0])
|
||||||
|
{
|
||||||
|
case "location":
|
||||||
|
ShowLocation = split[1].ToLower().StartsWith("yes");
|
||||||
|
break;
|
||||||
|
case "hidden":
|
||||||
|
StartHidden = split[1].ToLower().StartsWith("yes");
|
||||||
|
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,10 +92,99 @@ 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)
|
||||||
{
|
{
|
||||||
Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
|
Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
|
||||||
@@ -96,7 +218,7 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
|
|
||||||
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 +249,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 +284,9 @@ namespace WPCordovaClassLib.Cordova.Commands
|
|||||||
bar.Buttons.Add(closeBtn);
|
bar.Buttons.Add(closeBtn);
|
||||||
|
|
||||||
page.ApplicationBar = bar;
|
page.ApplicationBar = bar;
|
||||||
|
bar.IsVisible = !StartHidden;
|
||||||
|
AppBar = bar;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -251,7 +382,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 +390,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,7 +398,7 @@ 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);
|
||||||
|
|||||||
Vendored
+4
-2
@@ -20,7 +20,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var PLAT;
|
var PLAT;
|
||||||
if (/Android/.exec(navigator.userAgent)) {
|
if (/cordova-amazon-fireos/.exec(navigator.userAgent)) {
|
||||||
|
PLAT = 'amazon-fireos';
|
||||||
|
}else if (/Android/.exec(navigator.userAgent)) {
|
||||||
PLAT = 'android';
|
PLAT = 'android';
|
||||||
} else if (/(iPad)|(iPhone)|(iPod)/.exec(navigator.userAgent)) {
|
} else if (/(iPad)|(iPhone)|(iPod)/.exec(navigator.userAgent)) {
|
||||||
PLAT = 'ios';
|
PLAT = 'ios';
|
||||||
@@ -61,7 +63,7 @@ if (!window._doNotWriteCordovaScript) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function backHome() {
|
function backHome() {
|
||||||
if (window.device && device.platform && device.platform.toLowerCase() == 'android') {
|
if (window.device && device.platform && (device.platform.toLowerCase() == 'android' || device.platform.toLowerCase() == 'amazon-fireos')) {
|
||||||
navigator.app.backHistory();
|
navigator.app.backHistory();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
+12
-6
@@ -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 = {
|
||||||
@@ -30,6 +31,7 @@ function InAppBrowser() {
|
|||||||
'loaderror' : channel.create('loaderror'),
|
'loaderror' : channel.create('loaderror'),
|
||||||
'exit' : channel.create('exit')
|
'exit' : channel.create('exit')
|
||||||
};
|
};
|
||||||
|
this._alive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
InAppBrowser.prototype = {
|
InAppBrowser.prototype = {
|
||||||
@@ -39,7 +41,10 @@ InAppBrowser.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
close: function (eventname) {
|
close: function (eventname) {
|
||||||
exec(null, null, "InAppBrowser", "close", []);
|
if (this._alive) {
|
||||||
|
this._alive = false;
|
||||||
|
exec(null, null, "InAppBrowser", "close", []);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
show: function (eventname) {
|
show: function (eventname) {
|
||||||
exec(null, null, "InAppBrowser", "show", []);
|
exec(null, null, "InAppBrowser", "show", []);
|
||||||
@@ -77,17 +82,18 @@ 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);
|
||||||
|
};
|
||||||
|
|
||||||
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/windows8/commandProxy").add("InAppBrowser", module.exports);
|
||||||
|
|||||||
Reference in New Issue
Block a user