summaryrefslogtreecommitdiff
path: root/StoneIsland/plugins/cordova-plugin-inappbrowser/src
diff options
context:
space:
mode:
Diffstat (limited to 'StoneIsland/plugins/cordova-plugin-inappbrowser/src')
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java846
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java146
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java739
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java11
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md43
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/de/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/es/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/fr/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/it/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ja/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ko/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/pl/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/zh/README.md24
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js171
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js187
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h112
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.h27
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.m63
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.h50
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.m90
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowser.h80
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowser.m (renamed from StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m)1030
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.h32
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.m127
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.h30
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.m89
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml92
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js32
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.pngbin461 -> 0 bytes
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp105
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h61
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js200
-rw-r--r--StoneIsland/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs515
33 files changed, 2041 insertions, 3029 deletions
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java
deleted file mode 100644
index 0263ea2c..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-package org.apache.cordova.inappbrowser;
-
-import android.annotation.SuppressLint;
-import org.apache.cordova.inappbrowser.InAppBrowserDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Build;
-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 ZOOM = "zoom";
- 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 CLEAR_ALL_CACHE = "clearcache";
- private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
-
- private InAppBrowserDialog dialog;
- private AmazonWebView inAppWebView;
- private EditText edittext;
- private CallbackContext callbackContext;
- private boolean showLocationBar = true;
- private boolean showZoomControls = true;
- private boolean openWindowHidden = false;
- 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)) {
- Log.d(LOG_TAG, "loading in webview");
- webView.loadUrl(url);
- }
- //Load the dialer
- else if (url.startsWith(AmazonWebView.SCHEME_TEL))
- {
- try {
- Log.d(LOG_TAG, "loading in dialer");
- 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 {
- Log.d(LOG_TAG, "loading in InAppBrowser");
- 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.cordova.getActivity().runOnUiThread(new Runnable() {
- @SuppressLint("NewApi")
- @Override
- public void run() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
- // This action will have the side-effect of blurring the currently focused element
- inAppWebView.loadUrl("javascript:" + finalScriptToInject);
- } /*else {
- inAppWebView.evaluateJavascript(finalScriptToInject, null);
- }*/
- }
- });
- }
-
- /**
- * 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();
- 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);
- // Omitting the MIME type for file: URLs causes "No Activity found to handle Intent".
- // Adding the MIME type to http: URLs causes them to not be handled by the downloader.
- Uri uri = Uri.parse(url);
- if ("file".equals(uri.getScheme())) {
- intent.setDataAndType(uri, webView.getResourceApi().getMimeType(uri));
- } else {
- intent.setData(uri);
- }
- this.cordova.getActivity().startActivity(intent);
- 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() {
- final AmazonWebView childView = this.inAppWebView;
- // The JS protects against multiple calls, so this should happen only when
- // closeDialog() is called by other native code.
- if (childView == null) {
- return;
- }
- this.cordova.getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- childView.setWebViewClient(new AmazonWebViewClient() {
- // NB: wait for about:blank before dismissing
- public void onPageFinished(AmazonWebView view, String url) {
- if (dialog != null) {
- dialog.dismiss();
- }
- }
- });
- // NB: From SDK 19: "If you call methods on WebView from any thread
- // other than your app's UI thread, it can cause unexpected results."
- // http://developer.android.com/guide/webapps/migrating.html#Threads
- childView.loadUrl("about:blank");
- }
- });
-
- try {
- JSONObject obj = new JSONObject();
- obj.put("type", EXIT_EVENT);
- sendUpdate(obj, false);
- } catch (JSONException ex) {
- Log.d(LOG_TAG, "Should never happen");
- }
- }
- /**
- * 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;
- }
-
- /**
- * Should we show the zoom controls?
- *
- * @return boolean
- */
- private boolean getShowZoomControls() {
- return this.showZoomControls;
- }
-
- private InAppBrowser getInAppBrowser(){
- return this;
- }
-
- /**
- * 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;
- showZoomControls = true;
- openWindowHidden = false;
- if (features != null) {
- Boolean show = features.get(LOCATION);
- if (show != null) {
- showLocationBar = show.booleanValue();
- }
- Boolean zoom = features.get(ZOOM);
- if (zoom != null) {
- showZoomControls = zoom.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;
- }
-
- @SuppressLint("NewApi")
- public void run() {
- // Let's create the main dialog
- dialog = new InAppBrowserDialog(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.setInAppBroswer(getInAppBrowser());
-
- // 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);
- Resources activityRes = cordova.getActivity().getResources();
- int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName());
- Drawable backIcon = activityRes.getDrawable(backResId);
- if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
- {
- back.setBackgroundDrawable(backIcon);
- }
- else
- {
- back.setBackground(backIcon);
- }
-
- back.setOnClickListener(new View.OnClickListener() {
- 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);
- int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", cordova.getActivity().getPackageName());
- Drawable fwdIcon = activityRes.getDrawable(fwdResId);
- if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
- {
- forward.setBackgroundDrawable(fwdIcon);
- }
- else
- {
- forward.setBackground(fwdIcon);
- }
- forward.setOnClickListener(new View.OnClickListener() {
- 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/Done 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);
- int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName());
- Drawable closeIcon = activityRes.getDrawable(closeResId);
- if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN)
- {
- close.setBackgroundDrawable(closeIcon);
- }
- else
- {
- close.setBackground(closeIcon);
- }
- close.setOnClickListener(new View.OnClickListener() {
- 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(getShowZoomControls());
- 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");
- }
- }
- }
-}
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java
deleted file mode 100644
index 37cf101f..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-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;
- }
-
-}
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java
index 8f4f3d97..b3e0e612 100644
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java
@@ -19,12 +19,21 @@
package org.apache.cordova.inappbrowser;
import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Parcelable;
import android.provider.Browser;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Color;
+import android.net.http.SslError;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -41,6 +50,12 @@ import android.view.inputmethod.InputMethodManager;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.HttpAuthHandler;
+import android.webkit.JavascriptInterface;
+import android.webkit.SslErrorHandler;
+import android.webkit.ValueCallback;
+import android.webkit.WebChromeClient;
+import android.webkit.WebResourceRequest;
+import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -49,6 +64,7 @@ import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
+import android.widget.TextView;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.Config;
@@ -65,6 +81,9 @@ import org.json.JSONObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.HashMap;
import java.util.StringTokenizer;
@@ -82,11 +101,27 @@ public class InAppBrowser extends CordovaPlugin {
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 MESSAGE_EVENT = "message";
private static final String CLEAR_ALL_CACHE = "clearcache";
private static final String CLEAR_SESSION_CACHE = "clearsessioncache";
private static final String HARDWARE_BACK_BUTTON = "hardwareback";
private static final String MEDIA_PLAYBACK_REQUIRES_USER_ACTION = "mediaPlaybackRequiresUserAction";
private static final String SHOULD_PAUSE = "shouldPauseOnSuspend";
+ private static final Boolean DEFAULT_HARDWARE_BACK = true;
+ private static final String USER_WIDE_VIEW_PORT = "useWideViewPort";
+ private static final String TOOLBAR_COLOR = "toolbarcolor";
+ private static final String CLOSE_BUTTON_CAPTION = "closebuttoncaption";
+ private static final String CLOSE_BUTTON_COLOR = "closebuttoncolor";
+ private static final String LEFT_TO_RIGHT = "lefttoright";
+ private static final String HIDE_NAVIGATION = "hidenavigationbuttons";
+ private static final String NAVIGATION_COLOR = "navigationbuttoncolor";
+ private static final String HIDE_URL = "hideurlbar";
+ private static final String FOOTER = "footer";
+ private static final String FOOTER_COLOR = "footercolor";
+ private static final String BEFORELOAD = "beforeload";
+ private static final String FULLSCREEN = "fullscreen";
+
+ private static final List customizableOptions = Arrays.asList(CLOSE_BUTTON_CAPTION, TOOLBAR_COLOR, NAVIGATION_COLOR, CLOSE_BUTTON_COLOR, FOOTER_COLOR);
private InAppBrowserDialog dialog;
private WebView inAppWebView;
@@ -100,6 +135,24 @@ public class InAppBrowser extends CordovaPlugin {
private boolean hadwareBackButton = true;
private boolean mediaPlaybackRequiresUserGesture = false;
private boolean shouldPauseInAppBrowser = false;
+ private boolean useWideViewPort = true;
+ private ValueCallback<Uri> mUploadCallback;
+ private ValueCallback<Uri[]> mUploadCallbackLollipop;
+ private final static int FILECHOOSER_REQUESTCODE = 1;
+ private final static int FILECHOOSER_REQUESTCODE_LOLLIPOP = 2;
+ private String closeButtonCaption = "";
+ private String closeButtonColor = "";
+ private boolean leftToRight = false;
+ private int toolbarColor = android.graphics.Color.LTGRAY;
+ private boolean hideNavigationButtons = false;
+ private String navigationButtonColor = "";
+ private boolean hideUrlBar = false;
+ private boolean showFooter = false;
+ private String footerColor = "";
+ private String beforeload = "";
+ private boolean fullscreen = true;
+ private String[] allowedSchemes;
+ private InAppBrowserClient currentClient;
/**
* Executes the request and returns PluginResult.
@@ -118,7 +171,7 @@ public class InAppBrowser extends CordovaPlugin {
t = SELF;
}
final String target = t;
- final HashMap<String, Boolean> features = parseFeature(args.optString(2));
+ final HashMap<String, String> features = parseFeature(args.optString(2));
LOG.d(LOG_TAG, "target = " + target);
@@ -207,6 +260,25 @@ public class InAppBrowser extends CordovaPlugin {
else if (action.equals("close")) {
closeDialog();
}
+ else if (action.equals("loadAfterBeforeload")) {
+ if (beforeload == null) {
+ LOG.e(LOG_TAG, "unexpected loadAfterBeforeload called without feature beforeload=yes");
+ }
+ final String url = args.getString(0);
+ this.cordova.getActivity().runOnUiThread(new Runnable() {
+ @SuppressLint("NewApi")
+ @Override
+ public void run() {
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
+ currentClient.waitForBeforeload = false;
+ inAppWebView.setWebViewClient(currentClient);
+ } else {
+ ((InAppBrowserClient)inAppWebView.getWebViewClient()).waitForBeforeload = false;
+ }
+ inAppWebView.loadUrl(url);
+ }
+ });
+ }
else if (action.equals("injectScriptCode")) {
String jsWrapper = null;
if (args.getBoolean(1)) {
@@ -245,7 +317,22 @@ public class InAppBrowser extends CordovaPlugin {
this.cordova.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
- dialog.show();
+ if (dialog != null && !cordova.getActivity().isFinishing()) {
+ dialog.show();
+ }
+ }
+ });
+ PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
+ pluginResult.setKeepCallback(true);
+ this.callbackContext.sendPluginResult(pluginResult);
+ }
+ else if (action.equals("hide")) {
+ this.cordova.getActivity().runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (dialog != null && !cordova.getActivity().isFinishing()) {
+ dialog.hide();
+ }
}
});
PluginResult pluginResult = new PluginResult(PluginResult.Status.OK);
@@ -311,29 +398,33 @@ public class InAppBrowser extends CordovaPlugin {
* which should be executed directly.
*/
private void injectDeferredObject(String source, String jsWrapper) {
- 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);
+ if (inAppWebView!=null) {
+ 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.cordova.getActivity().runOnUiThread(new Runnable() {
+ @SuppressLint("NewApi")
+ @Override
+ public void run() {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
+ // This action will have the side-effect of blurring the currently focused element
+ inAppWebView.loadUrl("javascript:" + finalScriptToInject);
+ } else {
+ inAppWebView.evaluateJavascript(finalScriptToInject, null);
+ }
+ }
+ });
} else {
- scriptToInject = source;
+ LOG.d(LOG_TAG, "Can't inject code into the system browser");
}
- final String finalScriptToInject = scriptToInject;
- this.cordova.getActivity().runOnUiThread(new Runnable() {
- @SuppressLint("NewApi")
- @Override
- public void run() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
- // This action will have the side-effect of blurring the currently focused element
- inAppWebView.loadUrl("javascript:" + finalScriptToInject);
- } else {
- inAppWebView.evaluateJavascript(finalScriptToInject, null);
- }
- }
- });
}
/**
@@ -342,18 +433,21 @@ public class InAppBrowser extends CordovaPlugin {
* @param optString
* @return
*/
- private HashMap<String, Boolean> parseFeature(String optString) {
+ private HashMap<String, String> parseFeature(String optString) {
if (optString.equals(NULL)) {
return null;
} else {
- HashMap<String, Boolean> map = new HashMap<String, Boolean>();
+ HashMap<String, String> map = new HashMap<String, String>();
StringTokenizer features = new StringTokenizer(optString, ",");
StringTokenizer option;
while(features.hasMoreElements()) {
option = new StringTokenizer(features.nextToken(), "=");
if (option.hasMoreElements()) {
String key = option.nextToken();
- Boolean value = option.nextToken().equals("no") ? Boolean.FALSE : Boolean.TRUE;
+ String value = option.nextToken();
+ if (!customizableOptions.contains(key)) {
+ value = value.equals("yes") || value.equals("no") ? value : "yes";
+ }
map.put(key, value);
}
}
@@ -380,15 +474,57 @@ public class InAppBrowser extends CordovaPlugin {
intent.setData(uri);
}
intent.putExtra(Browser.EXTRA_APPLICATION_ID, cordova.getActivity().getPackageName());
- this.cordova.getActivity().startActivity(intent);
+ // CB-10795: Avoid circular loops by preventing it from opening in the current app
+ this.openExternalExcludeCurrentApp(intent);
return "";
- } catch (android.content.ActivityNotFoundException e) {
+ // not catching FileUriExposedException explicitly because buildtools<24 doesn't know about it
+ } catch (java.lang.RuntimeException e) {
LOG.d(LOG_TAG, "InAppBrowser: Error loading url "+url+":"+ e.toString());
return e.toString();
}
}
/**
+ * Opens the intent, providing a chooser that excludes the current app to avoid
+ * circular loops.
+ */
+ private void openExternalExcludeCurrentApp(Intent intent) {
+ String currentPackage = cordova.getActivity().getPackageName();
+ boolean hasCurrentPackage = false;
+
+ PackageManager pm = cordova.getActivity().getPackageManager();
+ List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
+ ArrayList<Intent> targetIntents = new ArrayList<Intent>();
+
+ for (ResolveInfo ri : activities) {
+ if (!currentPackage.equals(ri.activityInfo.packageName)) {
+ Intent targetIntent = (Intent)intent.clone();
+ targetIntent.setPackage(ri.activityInfo.packageName);
+ targetIntents.add(targetIntent);
+ }
+ else {
+ hasCurrentPackage = true;
+ }
+ }
+
+ // If the current app package isn't a target for this URL, then use
+ // the normal launch behavior
+ if (hasCurrentPackage == false || targetIntents.size() == 0) {
+ this.cordova.getActivity().startActivity(intent);
+ }
+ // If there's only one possible intent, launch it directly
+ else if (targetIntents.size() == 1) {
+ this.cordova.getActivity().startActivity(targetIntents.get(0));
+ }
+ // Otherwise, show a custom chooser without the current app listed
+ else if (targetIntents.size() > 0) {
+ Intent chooser = Intent.createChooser(targetIntents.remove(targetIntents.size()-1), null);
+ chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));
+ this.cordova.getActivity().startActivity(chooser);
+ }
+ }
+
+ /**
* Closes the dialog
*/
public void closeDialog() {
@@ -405,7 +541,7 @@ public class InAppBrowser extends CordovaPlugin {
childView.setWebViewClient(new WebViewClient() {
// NB: wait for about:blank before dismissing
public void onPageFinished(WebView view, String url) {
- if (dialog != null) {
+ if (dialog != null && !cordova.getActivity().isFinishing()) {
dialog.dismiss();
dialog = null;
}
@@ -488,7 +624,7 @@ public class InAppBrowser extends CordovaPlugin {
return this.showLocationBar;
}
- private InAppBrowser getInAppBrowser(){
+ private InAppBrowser getInAppBrowser() {
return this;
}
@@ -498,7 +634,7 @@ public class InAppBrowser extends CordovaPlugin {
* @param url the url to load.
* @param features jsonObject
*/
- public String showWebPage(final String url, HashMap<String, Boolean> features) {
+ public String showWebPage(final String url, HashMap<String, String> features) {
// Determine if we should hide the location bar.
showLocationBar = true;
showZoomControls = true;
@@ -506,38 +642,84 @@ public class InAppBrowser extends CordovaPlugin {
mediaPlaybackRequiresUserGesture = false;
if (features != null) {
- Boolean show = features.get(LOCATION);
+ String show = features.get(LOCATION);
if (show != null) {
- showLocationBar = show.booleanValue();
+ showLocationBar = show.equals("yes") ? true : false;
+ }
+ if(showLocationBar) {
+ String hideNavigation = features.get(HIDE_NAVIGATION);
+ String hideUrl = features.get(HIDE_URL);
+ if(hideNavigation != null) hideNavigationButtons = hideNavigation.equals("yes") ? true : false;
+ if(hideUrl != null) hideUrlBar = hideUrl.equals("yes") ? true : false;
}
- Boolean zoom = features.get(ZOOM);
+ String zoom = features.get(ZOOM);
if (zoom != null) {
- showZoomControls = zoom.booleanValue();
+ showZoomControls = zoom.equals("yes") ? true : false;
}
- Boolean hidden = features.get(HIDDEN);
+ String hidden = features.get(HIDDEN);
if (hidden != null) {
- openWindowHidden = hidden.booleanValue();
+ openWindowHidden = hidden.equals("yes") ? true : false;
}
- Boolean hardwareBack = features.get(HARDWARE_BACK_BUTTON);
+ String hardwareBack = features.get(HARDWARE_BACK_BUTTON);
if (hardwareBack != null) {
- hadwareBackButton = hardwareBack.booleanValue();
+ hadwareBackButton = hardwareBack.equals("yes") ? true : false;
+ } else {
+ hadwareBackButton = DEFAULT_HARDWARE_BACK;
}
- Boolean mediaPlayback = features.get(MEDIA_PLAYBACK_REQUIRES_USER_ACTION);
+ String mediaPlayback = features.get(MEDIA_PLAYBACK_REQUIRES_USER_ACTION);
if (mediaPlayback != null) {
- mediaPlaybackRequiresUserGesture = mediaPlayback.booleanValue();
+ mediaPlaybackRequiresUserGesture = mediaPlayback.equals("yes") ? true : false;
}
- Boolean cache = features.get(CLEAR_ALL_CACHE);
+ String cache = features.get(CLEAR_ALL_CACHE);
if (cache != null) {
- clearAllCache = cache.booleanValue();
+ clearAllCache = cache.equals("yes") ? true : false;
} else {
cache = features.get(CLEAR_SESSION_CACHE);
if (cache != null) {
- clearSessionCache = cache.booleanValue();
+ clearSessionCache = cache.equals("yes") ? true : false;
}
}
- Boolean shouldPause = features.get(SHOULD_PAUSE);
+ String shouldPause = features.get(SHOULD_PAUSE);
if (shouldPause != null) {
- shouldPauseInAppBrowser = shouldPause.booleanValue();
+ shouldPauseInAppBrowser = shouldPause.equals("yes") ? true : false;
+ }
+ String wideViewPort = features.get(USER_WIDE_VIEW_PORT);
+ if (wideViewPort != null ) {
+ useWideViewPort = wideViewPort.equals("yes") ? true : false;
+ }
+ String closeButtonCaptionSet = features.get(CLOSE_BUTTON_CAPTION);
+ if (closeButtonCaptionSet != null) {
+ closeButtonCaption = closeButtonCaptionSet;
+ }
+ String closeButtonColorSet = features.get(CLOSE_BUTTON_COLOR);
+ if (closeButtonColorSet != null) {
+ closeButtonColor = closeButtonColorSet;
+ }
+ String leftToRightSet = features.get(LEFT_TO_RIGHT);
+ leftToRight = leftToRightSet != null && leftToRightSet.equals("yes");
+
+ String toolbarColorSet = features.get(TOOLBAR_COLOR);
+ if (toolbarColorSet != null) {
+ toolbarColor = android.graphics.Color.parseColor(toolbarColorSet);
+ }
+ String navigationButtonColorSet = features.get(NAVIGATION_COLOR);
+ if (navigationButtonColorSet != null) {
+ navigationButtonColor = navigationButtonColorSet;
+ }
+ String showFooterSet = features.get(FOOTER);
+ if (showFooterSet != null) {
+ showFooter = showFooterSet.equals("yes") ? true : false;
+ }
+ String footerColorSet = features.get(FOOTER_COLOR);
+ if (footerColorSet != null) {
+ footerColor = footerColorSet;
+ }
+ if (features.get(BEFORELOAD) != null) {
+ beforeload = features.get(BEFORELOAD);
+ }
+ String fullscreenSet = features.get(FULLSCREEN);
+ if (fullscreenSet != null) {
+ fullscreen = fullscreenSet.equals("yes") ? true : false;
}
}
@@ -552,13 +734,61 @@ public class InAppBrowser extends CordovaPlugin {
*/
private int dpToPixels(int dipValue) {
int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,
- (float) dipValue,
- cordova.getActivity().getResources().getDisplayMetrics()
+ (float) dipValue,
+ cordova.getActivity().getResources().getDisplayMetrics()
);
return value;
}
+ private View createCloseButton(int id) {
+ View _close;
+ Resources activityRes = cordova.getActivity().getResources();
+
+ if (closeButtonCaption != "") {
+ // Use TextView for text
+ TextView close = new TextView(cordova.getActivity());
+ close.setText(closeButtonCaption);
+ close.setTextSize(20);
+ if (closeButtonColor != "") close.setTextColor(android.graphics.Color.parseColor(closeButtonColor));
+ close.setGravity(android.view.Gravity.CENTER_VERTICAL);
+ close.setPadding(this.dpToPixels(10), 0, this.dpToPixels(10), 0);
+ _close = close;
+ }
+ else {
+ ImageButton close = new ImageButton(cordova.getActivity());
+ int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName());
+ Drawable closeIcon = activityRes.getDrawable(closeResId);
+ if (closeButtonColor != "") close.setColorFilter(android.graphics.Color.parseColor(closeButtonColor));
+ close.setImageDrawable(closeIcon);
+ close.setScaleType(ImageView.ScaleType.FIT_CENTER);
+ if (Build.VERSION.SDK_INT >= 16)
+ close.getAdjustViewBounds();
+
+ _close = close;
+ }
+
+ RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
+ if (leftToRight) closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
+ else closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+ _close.setLayoutParams(closeLayoutParams);
+
+ if (Build.VERSION.SDK_INT >= 16)
+ _close.setBackground(null);
+ else
+ _close.setBackgroundDrawable(null);
+
+ _close.setContentDescription("Close Button");
+ _close.setId(Integer.valueOf(id));
+ _close.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ closeDialog();
+ }
+ });
+
+ return _close;
+ }
+
@SuppressLint("NewApi")
public void run() {
@@ -571,6 +801,9 @@ public class InAppBrowser extends CordovaPlugin {
dialog = new InAppBrowserDialog(cordova.getActivity(), android.R.style.Theme_NoTitleBar);
dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ if (fullscreen) {
+ dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ }
dialog.setCancelable(true);
dialog.setInAppBroswer(getInAppBrowser());
@@ -581,18 +814,25 @@ public class InAppBrowser extends CordovaPlugin {
// Toolbar layout
RelativeLayout toolbar = new RelativeLayout(cordova.getActivity());
//Please, no more black!
- toolbar.setBackgroundColor(android.graphics.Color.LTGRAY);
+ toolbar.setBackgroundColor(toolbarColor);
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);
+ if (leftToRight) {
+ toolbar.setHorizontalGravity(Gravity.LEFT);
+ } else {
+ toolbar.setHorizontalGravity(Gravity.RIGHT);
+ }
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));
+ RelativeLayout.LayoutParams actionButtonLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ if (leftToRight) actionButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+ else actionButtonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
+ actionButtonContainer.setLayoutParams(actionButtonLayoutParams);
actionButtonContainer.setHorizontalGravity(Gravity.LEFT);
actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);
- actionButtonContainer.setId(Integer.valueOf(1));
+ actionButtonContainer.setId(leftToRight ? Integer.valueOf(5) : Integer.valueOf(1));
// Back button
ImageButton back = new ImageButton(cordova.getActivity());
@@ -604,6 +844,7 @@ public class InAppBrowser extends CordovaPlugin {
Resources activityRes = cordova.getActivity().getResources();
int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName());
Drawable backIcon = activityRes.getDrawable(backResId);
+ if (navigationButtonColor != "") back.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor));
if (Build.VERSION.SDK_INT >= 16)
back.setBackground(null);
else
@@ -629,6 +870,7 @@ public class InAppBrowser extends CordovaPlugin {
forward.setId(Integer.valueOf(3));
int fwdResId = activityRes.getIdentifier("ic_action_next_item", "drawable", cordova.getActivity().getPackageName());
Drawable fwdIcon = activityRes.getDrawable(fwdResId);
+ if (navigationButtonColor != "") forward.setColorFilter(android.graphics.Color.parseColor(navigationButtonColor));
if (Build.VERSION.SDK_INT >= 16)
forward.setBackground(null);
else
@@ -661,53 +903,112 @@ public class InAppBrowser extends CordovaPlugin {
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;
+ navigate(edittext.getText().toString());
+ return true;
}
return false;
}
});
- // Close/Done button
- ImageButton close = new ImageButton(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(Integer.valueOf(5));
- int closeResId = activityRes.getIdentifier("ic_action_remove", "drawable", cordova.getActivity().getPackageName());
- Drawable closeIcon = activityRes.getDrawable(closeResId);
- if (Build.VERSION.SDK_INT >= 16)
- close.setBackground(null);
- else
- close.setBackgroundDrawable(null);
- close.setImageDrawable(closeIcon);
- close.setScaleType(ImageView.ScaleType.FIT_CENTER);
- back.setPadding(0, this.dpToPixels(10), 0, this.dpToPixels(10));
- if (Build.VERSION.SDK_INT >= 16)
- close.getAdjustViewBounds();
- close.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- closeDialog();
- }
- });
+ // Header Close/Done button
+ int closeButtonId = leftToRight ? 1 : 5;
+ View close = createCloseButton(closeButtonId);
+ toolbar.addView(close);
+
+ // Footer
+ RelativeLayout footer = new RelativeLayout(cordova.getActivity());
+ int _footerColor;
+ if(footerColor != "") {
+ _footerColor = Color.parseColor(footerColor);
+ } else {
+ _footerColor = android.graphics.Color.LTGRAY;
+ }
+ footer.setBackgroundColor(_footerColor);
+ RelativeLayout.LayoutParams footerLayout = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, this.dpToPixels(44));
+ footerLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
+ footer.setLayoutParams(footerLayout);
+ if (closeButtonCaption != "") footer.setPadding(this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8), this.dpToPixels(8));
+ footer.setHorizontalGravity(Gravity.LEFT);
+ footer.setVerticalGravity(Gravity.BOTTOM);
+
+ View footerClose = createCloseButton(7);
+ footer.addView(footerClose);
+
// WebView
inAppWebView = new WebView(cordova.getActivity());
inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
inAppWebView.setId(Integer.valueOf(6));
- inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView));
- WebViewClient client = new InAppBrowserClient(thatWebView, edittext);
- inAppWebView.setWebViewClient(client);
+ // File Chooser Implemented ChromeClient
+ inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView) {
+ // For Android 5.0+
+ public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
+ {
+ LOG.d(LOG_TAG, "File Chooser 5.0+");
+ // If callback exists, finish it.
+ if(mUploadCallbackLollipop != null) {
+ mUploadCallbackLollipop.onReceiveValue(null);
+ }
+ mUploadCallbackLollipop = filePathCallback;
+
+ // Create File Chooser Intent
+ Intent content = new Intent(Intent.ACTION_GET_CONTENT);
+ content.addCategory(Intent.CATEGORY_OPENABLE);
+ content.setType("*/*");
+
+ // Run cordova startActivityForResult
+ cordova.startActivityForResult(InAppBrowser.this, Intent.createChooser(content, "Select File"), FILECHOOSER_REQUESTCODE_LOLLIPOP);
+ return true;
+ }
+
+ // For Android 4.1+
+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
+ {
+ LOG.d(LOG_TAG, "File Chooser 4.1+");
+ // Call file chooser for Android 3.0+
+ openFileChooser(uploadMsg, acceptType);
+ }
+
+ // For Android 3.0+
+ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType)
+ {
+ LOG.d(LOG_TAG, "File Chooser 3.0+");
+ mUploadCallback = uploadMsg;
+ Intent content = new Intent(Intent.ACTION_GET_CONTENT);
+ content.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // run startActivityForResult
+ cordova.startActivityForResult(InAppBrowser.this, Intent.createChooser(content, "Select File"), FILECHOOSER_REQUESTCODE);
+ }
+
+ });
+ currentClient = new InAppBrowserClient(thatWebView, edittext, beforeload);
+ inAppWebView.setWebViewClient(currentClient);
WebSettings settings = inAppWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setBuiltInZoomControls(showZoomControls);
settings.setPluginState(android.webkit.WebSettings.PluginState.ON);
+ // Add postMessage interface
+ class JsObject {
+ @JavascriptInterface
+ public void postMessage(String data) {
+ try {
+ JSONObject obj = new JSONObject();
+ obj.put("type", MESSAGE_EVENT);
+ obj.put("data", new JSONObject(data));
+ sendUpdate(obj, true);
+ } catch (JSONException ex) {
+ LOG.e(LOG_TAG, "data object passed to postMessage has caused a JSON error.");
+ }
+ }
+ }
+
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
settings.setMediaPlaybackRequiresUserGesture(mediaPlaybackRequiresUserGesture);
+ inAppWebView.addJavascriptInterface(new JsObject(), "cordova_iab");
}
String overrideUserAgent = preferences.getString("OverrideUserAgent", null);
@@ -736,10 +1037,15 @@ public class InAppBrowser extends CordovaPlugin {
CookieManager.getInstance().removeSessionCookie();
}
+ // Enable Thirdparty Cookies on >=Android 5.0 device
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
+ CookieManager.getInstance().setAcceptThirdPartyCookies(inAppWebView,true);
+ }
+
inAppWebView.loadUrl(url);
inAppWebView.setId(Integer.valueOf(6));
inAppWebView.getSettings().setLoadWithOverviewMode(true);
- inAppWebView.getSettings().setUseWideViewPort(true);
+ inAppWebView.getSettings().setUseWideViewPort(useWideViewPort);
inAppWebView.requestFocus();
inAppWebView.requestFocusFromTouch();
@@ -747,10 +1053,9 @@ public class InAppBrowser extends CordovaPlugin {
actionButtonContainer.addView(back);
actionButtonContainer.addView(forward);
- // Add the views to our toolbar
- toolbar.addView(actionButtonContainer);
- toolbar.addView(edittext);
- toolbar.addView(close);
+ // Add the views to our toolbar if they haven't been disabled
+ if (!hideNavigationButtons) toolbar.addView(actionButtonContainer);
+ if (!hideUrlBar) toolbar.addView(edittext);
// Don't add the toolbar if its been disabled
if (getShowLocationBar()) {
@@ -759,19 +1064,28 @@ public class InAppBrowser extends CordovaPlugin {
}
// Add our webview to our main view/layout
- main.addView(inAppWebView);
+ RelativeLayout webViewLayout = new RelativeLayout(cordova.getActivity());
+ webViewLayout.addView(inAppWebView);
+ main.addView(webViewLayout);
+
+ // Don't add the footer unless it's been enabled
+ if (showFooter) {
+ webViewLayout.addView(footer);
+ }
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);
+ if (dialog != null) {
+ 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) {
+ if (openWindowHidden && dialog != null) {
dialog.hide();
}
}
@@ -807,11 +1121,49 @@ public class InAppBrowser extends CordovaPlugin {
}
/**
+ * Receive File Data from File Chooser
+ *
+ * @param requestCode the requested code from chromeclient
+ * @param resultCode the result code returned from android system
+ * @param intent the data from android file chooser
+ */
+ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ // For Android >= 5.0
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ LOG.d(LOG_TAG, "onActivityResult (For Android >= 5.0)");
+ // If RequestCode or Callback is Invalid
+ if(requestCode != FILECHOOSER_REQUESTCODE_LOLLIPOP || mUploadCallbackLollipop == null) {
+ super.onActivityResult(requestCode, resultCode, intent);
+ return;
+ }
+ mUploadCallbackLollipop.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
+ mUploadCallbackLollipop = null;
+ }
+ // For Android < 5.0
+ else {
+ LOG.d(LOG_TAG, "onActivityResult (For Android < 5.0)");
+ // If RequestCode or Callback is Invalid
+ if(requestCode != FILECHOOSER_REQUESTCODE || mUploadCallback == null) {
+ super.onActivityResult(requestCode, resultCode, intent);
+ return;
+ }
+
+ if (null == mUploadCallback) return;
+ Uri result = intent == null || resultCode != cordova.getActivity().RESULT_OK ? null : intent.getData();
+
+ mUploadCallback.onReceiveValue(result);
+ mUploadCallback = null;
+ }
+ }
+
+ /**
* The webview client receives notifications about appView
*/
public class InAppBrowserClient extends WebViewClient {
EditText edittext;
CordovaWebView webView;
+ String beforeload;
+ boolean waitForBeforeload;
/**
* Constructor.
@@ -819,27 +1171,97 @@ public class InAppBrowser extends CordovaPlugin {
* @param webView
* @param mEditText
*/
- public InAppBrowserClient(CordovaWebView webView, EditText mEditText) {
+ public InAppBrowserClient(CordovaWebView webView, EditText mEditText, String beforeload) {
this.webView = webView;
this.edittext = mEditText;
+ this.beforeload = beforeload;
+ this.waitForBeforeload = beforeload != null;
}
/**
* Override the URL that should be loaded
*
- * This handles a small subset of all the URIs that would be encountered.
+ * Legacy (deprecated in API 24)
+ * For Android 6 and below.
*
* @param webView
* @param url
*/
+ @SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
+ return shouldOverrideUrlLoading(url, null);
+ }
+
+ /**
+ * Override the URL that should be loaded
+ *
+ * New (added in API 24)
+ * For Android 7 and above.
+ *
+ * @param webView
+ * @param request
+ */
+ @TargetApi(Build.VERSION_CODES.N)
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request) {
+ return shouldOverrideUrlLoading(request.getUrl().toString(), request.getMethod());
+ }
+
+ /**
+ * Override the URL that should be loaded
+ *
+ * This handles a small subset of all the URIs that would be encountered.
+ *
+ * @param url
+ * @param method
+ */
+ public boolean shouldOverrideUrlLoading(String url, String method) {
+ boolean override = false;
+ boolean useBeforeload = false;
+ String errorMessage = null;
+
+ if (beforeload.equals("yes") && method == null) {
+ useBeforeload = true;
+ } else if(beforeload.equals("yes")
+ //TODO handle POST requests then this condition can be removed:
+ && !method.equals("POST"))
+ {
+ useBeforeload = true;
+ } else if(beforeload.equals("get") && (method == null || method.equals("GET"))) {
+ useBeforeload = true;
+ } else if(beforeload.equals("post") && (method == null || method.equals("POST"))) {
+ //TODO handle POST requests
+ errorMessage = "beforeload doesn't yet support POST requests";
+ }
+
+ // On first URL change, initiate JS callback. Only after the beforeload event, continue.
+ if (useBeforeload && this.waitForBeforeload) {
+ if(sendBeforeLoad(url, method)) {
+ return true;
+ }
+ }
+
+ if(errorMessage != null) {
+ try {
+ LOG.e(LOG_TAG, errorMessage);
+ JSONObject obj = new JSONObject();
+ obj.put("type", LOAD_ERROR_EVENT);
+ obj.put("url", url);
+ obj.put("code", -1);
+ obj.put("message", errorMessage);
+ sendUpdate(obj, true, PluginResult.Status.ERROR);
+ } catch(Exception e) {
+ LOG.e(LOG_TAG, "Error sending loaderror for " + url + ": " + e.toString());
+ }
+ }
+
if (url.startsWith(WebView.SCHEME_TEL)) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse(url));
cordova.getActivity().startActivity(intent);
- return true;
+ override = true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error dialing " + url + ": " + e.toString());
}
@@ -848,7 +1270,7 @@ public class InAppBrowser extends CordovaPlugin {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
cordova.getActivity().startActivity(intent);
- return true;
+ override = true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString());
}
@@ -879,15 +1301,89 @@ public class InAppBrowser extends CordovaPlugin {
intent.putExtra("address", address);
intent.setType("vnd.android-dir/mms-sms");
cordova.getActivity().startActivity(intent);
- return true;
+ override = true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
}
}
+ // Test for whitelisted custom scheme names like mycoolapp:// or twitteroauthresponse:// (Twitter Oauth Response)
+ else if (!url.startsWith("http:") && !url.startsWith("https:") && url.matches("^[A-Za-z0-9+.-]*://.*?$")) {
+ if (allowedSchemes == null) {
+ String allowed = preferences.getString("AllowedSchemes", null);
+ if(allowed != null) {
+ allowedSchemes = allowed.split(",");
+ }
+ }
+ if (allowedSchemes != null) {
+ for (String scheme : allowedSchemes) {
+ if (url.startsWith(scheme)) {
+ try {
+ JSONObject obj = new JSONObject();
+ obj.put("type", "customscheme");
+ obj.put("url", url);
+ sendUpdate(obj, true);
+ override = true;
+ } catch (JSONException ex) {
+ LOG.e(LOG_TAG, "Custom Scheme URI passed in has caused a JSON error.");
+ }
+ }
+ }
+ }
+ }
+
+ if (useBeforeload) {
+ this.waitForBeforeload = true;
+ }
+ return override;
+ }
+
+ private boolean sendBeforeLoad(String url, String method) {
+ try {
+ JSONObject obj = new JSONObject();
+ obj.put("type", BEFORELOAD);
+ obj.put("url", url);
+ if(method != null) {
+ obj.put("method", method);
+ }
+ sendUpdate(obj, true);
+ return true;
+ } catch (JSONException ex) {
+ LOG.e(LOG_TAG, "URI passed in has caused a JSON error.");
+ }
return false;
}
+ /**
+ * Legacy (deprecated in API 21)
+ * For Android 4.4 and below.
+ * @param view
+ * @param url
+ * @return
+ */
+ @SuppressWarnings("deprecation")
+ @Override
+ public WebResourceResponse shouldInterceptRequest (final WebView view, String url) {
+ return shouldInterceptRequest(url, super.shouldInterceptRequest(view, url), null);
+ }
+
+ /**
+ * New (added in API 21)
+ * For Android 5.0 and above.
+ *
+ * @param webView
+ * @param request
+ */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ @Override
+ public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
+ return shouldInterceptRequest(request.getUrl().toString(), super.shouldInterceptRequest(view, request), request.getMethod());
+ }
+
+ public WebResourceResponse shouldInterceptRequest(String url, WebResourceResponse response, String method) {
+ return response;
+ }
+
/*
* onPageStarted fires the LOAD_START_EVENT
*
@@ -913,7 +1409,7 @@ public class InAppBrowser extends CordovaPlugin {
// Update the UI if we haven't already
if (!newloc.equals(edittext.getText().toString())) {
edittext.setText(newloc);
- }
+ }
try {
JSONObject obj = new JSONObject();
@@ -925,11 +1421,14 @@ public class InAppBrowser extends CordovaPlugin {
}
}
-
-
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
+ // Set the namespace for postMessage()
+ if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ injectDeferredObject("window.webkit={messageHandlers:{cordova_iab:cordova_iab}}", null);
+ }
+
// CB-10395 InAppBrowser's WebView not storing cookies reliable to local device storage
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().flush();
@@ -937,6 +1436,10 @@ public class InAppBrowser extends CordovaPlugin {
CookieSyncManager.getInstance().sync();
}
+ // https://issues.apache.org/jira/browse/CB-11248
+ view.clearFocus();
+ view.requestFocus();
+
try {
JSONObject obj = new JSONObject();
obj.put("type", LOAD_STOP_EVENT);
@@ -964,6 +1467,46 @@ public class InAppBrowser extends CordovaPlugin {
}
}
+ @Override
+ public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+ super.onReceivedSslError(view, handler, error);
+ try {
+ JSONObject obj = new JSONObject();
+ obj.put("type", LOAD_ERROR_EVENT);
+ obj.put("url", error.getUrl());
+ obj.put("code", 0);
+ obj.put("sslerror", error.getPrimaryError());
+ String message;
+ switch (error.getPrimaryError()) {
+ case SslError.SSL_DATE_INVALID:
+ message = "The date of the certificate is invalid";
+ break;
+ case SslError.SSL_EXPIRED:
+ message = "The certificate has expired";
+ break;
+ case SslError.SSL_IDMISMATCH:
+ message = "Hostname mismatch";
+ break;
+ default:
+ case SslError.SSL_INVALID:
+ message = "A generic error occurred";
+ break;
+ case SslError.SSL_NOTYETVALID:
+ message = "The certificate is not yet valid";
+ break;
+ case SslError.SSL_UNTRUSTED:
+ message = "The certificate authority is not trusted";
+ break;
+ }
+ obj.put("message", message);
+
+ sendUpdate(obj, true, PluginResult.Status.ERROR);
+ } catch (JSONException ex) {
+ LOG.d(LOG_TAG, "Should never happen");
+ }
+ handler.cancel();
+ }
+
/**
* On received http auth request.
*/
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java
index a2145e6a..fe5dd349 100644
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java
@@ -104,7 +104,7 @@ public class InAppChromeClient extends WebChromeClient {
if(defaultValue.startsWith("gap-iab://")) {
PluginResult scriptResult;
String scriptCallbackId = defaultValue.substring(10);
- if (scriptCallbackId.startsWith("InAppBrowser")) {
+ if (scriptCallbackId.matches("^InAppBrowser[0-9]{1,10}$")) {
if(message == null || message.length() == 0) {
scriptResult = new PluginResult(PluginResult.Status.OK, new JSONArray());
} else {
@@ -118,9 +118,14 @@ public class InAppChromeClient extends WebChromeClient {
result.confirm("");
return true;
}
+ else {
+ // Anything else that doesn't look like InAppBrowser0123456789 should end up here
+ LOG.w(LOG_TAG, "InAppBrowser callback called with invalid callbackId : "+ scriptCallbackId);
+ result.cancel();
+ return true;
+ }
}
- else
- {
+ 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();
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md
deleted file mode 100644
index f0fa8607..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md
+++ /dev/null
@@ -1,43 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-# BlackBerry 10 In-App-Browser Plugin
-
-The in app browser functionality is entirely contained within common js. There is no native implementation required.
-To install this plugin, follow the [Command-line Interface Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-If you are not using the Cordova Command-line Interface, follow [Using Plugman to Manage Plugins](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html).
-./cordova-plugin-battery-status/README.md
-./cordova-plugin-camera/README.md
-./cordova-plugin-console/README.md
-./cordova-plugin-contacts/README.md
-./cordova-plugin-device/README.md
-./cordova-plugin-device-motion/README.md
-./cordova-plugin-device-orientation/README.md
-./cordova-plugin-device-orientation/src/blackberry10/README.md
-./cordova-plugin-file/README.md
-./cordova-plugin-file-transfer/README.md
-./cordova-plugin-geolocation/README.md
-./cordova-plugin-globalization/README.md
-./cordova-plugin-inappbrowser/README.md
-./cordova-plugin-inappbrowser/src/blackberry10/README.md
-./cordova-plugin-media/README.md
-./cordova-plugin-media-capture/README.md
-./cordova-plugin-network-information/README.md
-./cordova-plugin-splashscreen/README.md
-./cordova-plugin-vibration/README.md
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/de/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/de/README.md
deleted file mode 100644
index e3944876..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/de/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# BlackBerry 10-In-App-Browser-Plugin
-
-Die Funktionalität ist im app-Browser vollständig in gemeinsamen Js enthalten. Es gibt keine native Implementierung benötigt. Um dieses Plugin zu installieren, folgen Sie dem [Command-Line Interface Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-Wenn Sie nicht die Cordova-Befehlszeilenschnittstelle verwenden, folgen Sie [Verwenden Plugman zu Plugins verwalten](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/es/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/es/README.md
deleted file mode 100644
index 75303369..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/es/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# BlackBerry 10 In-App-Browser Plugin
-
-El en el navegador de aplicación funcionalidad está enteramente dentro de js común. No hay ninguna aplicación nativa necesaria. Para instalar este plugin, siga la [Guía de la interfaz de línea de comandos](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-Si no utiliza la interfaz de línea de comandos de Cordova, siga [Usando Plugman para gestionar Plugins](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/fr/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/fr/README.md
deleted file mode 100644
index 179bd483..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/fr/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# BlackBerry 10 In-App-Browser Plugin
-
-Le dans le navigateur de l'application, la fonctionnalité est entièrement contenue dans js commun. Il n'y a aucune implémentation native requise. Pour installer ce plugin, suivez le [Guide de l'Interface de ligne de commande](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-Si vous n'utilisez pas l'Interface de ligne de commande de Cordova, suivez [Les Plugman à l'aide à gérer les Plugins](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/it/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/it/README.md
deleted file mode 100644
index 8f0623df..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/it/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# BlackBerry 10 In-App-Browser Plugin
-
-Il browser app funzionalità è interamente contenuta nel comune js. Non esiste alcuna implementazione nativa richiesto. Per installare questo plugin, seguire la [Guida per l'interfaccia della riga di comando](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-Se non si utilizza l'interfaccia della riga di comando di Cordova, seguire [Utilizzando Plugman per gestire i plugin](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ja/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ja/README.md
deleted file mode 100644
index b9e4b7b7..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ja/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# BlackBerry 10 In-App-Browser Plugin
-
-アプリケーション ブラウザーの機能は全く一般的な js に含まれています。 ネイティブ実装する必要はありません。 このプラグインをインストールするには[コマンド ライン インターフェイス ガイド](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-コルドバのコマンド ライン インターフェイスを使用していない場合は場合、[管理のプラグインを使用して Plugman](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html)に従ってください。 ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ko/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ko/README.md
deleted file mode 100644
index 67fb8de3..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/ko/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# 블랙베리 10 애플 리 케이 션-브라우저 플러그인
-
-응용 프로그램 브라우저에서 기능은 완전히 포함 된 일반적인 js. 필요 없는 기본 구현이입니다. 이 플러그인을 설치 하려면 [명령줄 인터페이스 가이드](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface) 를 따라합니다.
-
-코르도바 명령줄 인터페이스를 사용 하지 않는 경우 [관리 플러그인을 사용 하 여 Plugman](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html)를 따르십시오. ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/pl/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/pl/README.md
deleted file mode 100644
index ef199ee9..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/pl/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# BlackBerry 10 In-App-Browser Plugin
-
-W aplikacji Przeglądarka funkcjonalność jest całkowicie zawarty w wspólnej js. Tam jest nie native wdrażania wymagane. Aby zainstalować ten plugin, następować po ten [Przewodnik interfejsu wiersza polecenia](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-Jeśli nie używasz interfejsu wiersza polecenia Cordova, następować po [Przy użyciu Plugman do zarządzania wtyczki](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html). ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/zh/README.md b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/zh/README.md
deleted file mode 100644
index 241fb550..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/blackberry10/doc/zh/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-<!---
- license: Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-# 黑莓 10 的應用程式瀏覽器外掛程式
-
-在應用程式瀏覽器功能完全包含在常見的 js。 還有沒有本機的實施所需。 若要安裝此外掛程式,請按照[命令列介面指南](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface).
-
-如果你不使用的科爾多瓦命令列介面,請按照[使用 Plugman 管理外掛程式](http://cordova.apache.org/docs/en/edge/guide_plugin_ref_plugman.md.html)。 ./cordova-plugin-battery-status/README.md ./cordova-plugin-camera/README.md ./cordova-plugin-console/README.md ./cordova-plugin-contacts/README.md ./cordova-plugin-device/README.md ./cordova-plugin-device-motion/README.md ./cordova-plugin-device-orientation/README.md ./cordova-plugin-device-orientation/src/blackberry10/README.md ./cordova-plugin-file/README.md ./cordova-plugin-file-transfer/README.md ./cordova-plugin-geolocation/README.md ./cordova-plugin-globalization/README.md ./cordova-plugin-inappbrowser/README.md ./cordova-plugin-inappbrowser/src/blackberry10/README.md ./cordova-plugin-media/README.md ./cordova-plugin-media-capture/README.md ./cordova-plugin-network-information/README.md ./cordova-plugin-splashscreen/README.md ./cordova-plugin-vibration/README.md \ No newline at end of file
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js
index da7dacd3..1c62574b 100644
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js
@@ -29,27 +29,43 @@ var browserWrap,
forwardButton,
closeButton;
-function attachNavigationEvents(element, callback) {
+function attachNavigationEvents (element, callback) {
var onError = function () {
- callback({ type: "loaderror", url: this.contentWindow.location}, {keepCallback: true});
+ try {
+ callback({ type: 'loaderror', url: this.contentWindow.location.href }, {keepCallback: true}); // eslint-disable-line standard/no-callback-literal
+ } catch (err) {
+ // blocked by CORS :\
+ callback({ type: 'loaderror', url: null }, {keepCallback: true}); // eslint-disable-line standard/no-callback-literal
+ }
};
- element.addEventListener("pageshow", function () {
- callback({ type: "loadstart", url: this.contentWindow.location}, {keepCallback: true});
+ element.addEventListener('pageshow', function () {
+ try {
+ callback({ type: 'loadstart', url: this.contentWindow.location.href }, {keepCallback: true}); // eslint-disable-line standard/no-callback-literal
+ } catch (err) {
+ // blocked by CORS :\
+ callback({ type: 'loadstart', url: null }, {keepCallback: true}); // eslint-disable-line standard/no-callback-literal
+ }
});
- element.addEventListener("load", function () {
- callback({ type: "loadstop", url: this.contentWindow.location}, {keepCallback: true});
+ element.addEventListener('load', function () {
+ try {
+ callback({ type: 'loadstop', url: this.contentWindow.location.href }, {keepCallback: true}); // eslint-disable-line standard/no-callback-literal
+ } catch (err) {
+ // blocked by CORS :\
+ callback({ type: 'loadstop', url: null }, {keepCallback: true}); // eslint-disable-line standard/no-callback-literal
+ }
});
- element.addEventListener("error", onError);
- element.addEventListener("abort", onError);
+ element.addEventListener('error', onError);
+ element.addEventListener('abort', onError);
}
var IAB = {
close: function (win, lose) {
if (browserWrap) {
- if (win) win({ type: "exit" });
+ // use the "open" function callback so that the exit event is fired properly
+ if (IAB._win) IAB._win({ type: 'exit' });
browserWrap.parentNode.removeChild(browserWrap);
browserWrap = null;
@@ -59,109 +75,108 @@ var IAB = {
show: function (win, lose) {
if (browserWrap) {
- browserWrap.style.display = "block";
+ browserWrap.style.display = 'block';
}
},
open: function (win, lose, args) {
- var strUrl = args[0],
- target = args[1],
- features = args[2];
+ var strUrl = args[0];
+ var target = args[1];
+ var features = args[2];
- if (target === "_self" || !target) {
+ IAB._win = win;
+
+ if (target === '_self' || !target) {
window.location = strUrl;
- } else if (target === "_system") {
- modulemapper.getOriginalSymbol(window, 'window.open').call(window, strUrl, "_blank");
+ } else if (target === '_system') {
+ modulemapper.getOriginalSymbol(window, 'window.open').call(window, strUrl, '_blank');
} else {
// "_blank" or anything else
if (!browserWrap) {
- browserWrap = document.createElement("div");
- browserWrap.style.position = "absolute";
- browserWrap.style.top = "0";
- browserWrap.style.left = "0";
- browserWrap.style.boxSizing = "border-box";
- browserWrap.style.borderWidth = "40px";
- browserWrap.style.width = "100vw";
- browserWrap.style.height = "100vh";
- browserWrap.style.borderStyle = "solid";
- browserWrap.style.borderColor = "rgba(0,0,0,0.25)";
+ browserWrap = document.createElement('div');
+ browserWrap.style.position = 'absolute';
+ browserWrap.style.top = '0';
+ browserWrap.style.left = '0';
+ browserWrap.style.boxSizing = 'border-box';
+ browserWrap.style.borderWidth = '40px';
+ browserWrap.style.width = '100vw';
+ browserWrap.style.height = '100vh';
+ browserWrap.style.borderStyle = 'solid';
+ browserWrap.style.borderColor = 'rgba(0,0,0,0.25)';
browserWrap.onclick = function () {
setTimeout(function () {
- IAB.close(win);
+ IAB.close();
}, 0);
};
document.body.appendChild(browserWrap);
}
- if (features.indexOf("hidden=yes") !== -1) {
- browserWrap.style.display = "none";
+ if (features.indexOf('hidden=yes') !== -1) {
+ browserWrap.style.display = 'none';
}
- popup = document.createElement("iframe");
- popup.style.borderWidth = "0px";
- popup.style.width = "100%";
+ popup = document.createElement('iframe');
+ popup.style.borderWidth = '0px';
+ popup.style.width = '100%';
browserWrap.appendChild(popup);
- if (features.indexOf("location=yes") !== -1 || features.indexOf("location") === -1) {
- popup.style.height = "calc(100% - 60px)";
- popup.style.marginBottom = "-4px";
+ if (features.indexOf('location=yes') !== -1 || features.indexOf('location') === -1) {
+ popup.style.height = 'calc(100% - 60px)';
+ popup.style.marginBottom = '-4px';
- navigationButtonsDiv = document.createElement("div");
- navigationButtonsDiv.style.height = "60px";
- navigationButtonsDiv.style.backgroundColor = "#404040";
- navigationButtonsDiv.style.zIndex = "999";
+ navigationButtonsDiv = document.createElement('div');
+ navigationButtonsDiv.style.height = '60px';
+ navigationButtonsDiv.style.backgroundColor = '#404040';
+ navigationButtonsDiv.style.zIndex = '999';
navigationButtonsDiv.onclick = function (e) {
e.cancelBubble = true;
};
- navigationButtonsDivInner = document.createElement("div");
- navigationButtonsDivInner.style.paddingTop = "10px";
- navigationButtonsDivInner.style.height = "50px";
- navigationButtonsDivInner.style.width = "160px";
- navigationButtonsDivInner.style.margin = "0 auto";
- navigationButtonsDivInner.style.backgroundColor = "#404040";
- navigationButtonsDivInner.style.zIndex = "999";
+ navigationButtonsDivInner = document.createElement('div');
+ navigationButtonsDivInner.style.paddingTop = '10px';
+ navigationButtonsDivInner.style.height = '50px';
+ navigationButtonsDivInner.style.width = '160px';
+ navigationButtonsDivInner.style.margin = '0 auto';
+ navigationButtonsDivInner.style.backgroundColor = '#404040';
+ navigationButtonsDivInner.style.zIndex = '999';
navigationButtonsDivInner.onclick = function (e) {
e.cancelBubble = true;
};
+ backButton = document.createElement('button');
+ backButton.style.width = '40px';
+ backButton.style.height = '40px';
+ backButton.style.borderRadius = '40px';
- backButton = document.createElement("button");
- backButton.style.width = "40px";
- backButton.style.height = "40px";
- backButton.style.borderRadius = "40px";
-
- backButton.innerHTML = "←";
- backButton.addEventListener("click", function (e) {
- if (popup.canGoBack)
- popup.goBack();
+ backButton.innerHTML = '←';
+ backButton.addEventListener('click', function (e) {
+ if (popup.canGoBack) { popup.goBack(); }
});
- forwardButton = document.createElement("button");
- forwardButton.style.marginLeft = "20px";
- forwardButton.style.width = "40px";
- forwardButton.style.height = "40px";
- forwardButton.style.borderRadius = "40px";
+ forwardButton = document.createElement('button');
+ forwardButton.style.marginLeft = '20px';
+ forwardButton.style.width = '40px';
+ forwardButton.style.height = '40px';
+ forwardButton.style.borderRadius = '40px';
- forwardButton.innerHTML = "→";
- forwardButton.addEventListener("click", function (e) {
- if (popup.canGoForward)
- popup.goForward();
+ forwardButton.innerHTML = '→';
+ forwardButton.addEventListener('click', function (e) {
+ if (popup.canGoForward) { popup.goForward(); }
});
- closeButton = document.createElement("button");
- closeButton.style.marginLeft = "20px";
- closeButton.style.width = "40px";
- closeButton.style.height = "40px";
- closeButton.style.borderRadius = "40px";
+ closeButton = document.createElement('button');
+ closeButton.style.marginLeft = '20px';
+ closeButton.style.width = '40px';
+ closeButton.style.height = '40px';
+ closeButton.style.borderRadius = '40px';
- closeButton.innerHTML = "✖";
- closeButton.addEventListener("click", function (e) {
+ closeButton.innerHTML = '✖';
+ closeButton.addEventListener('click', function (e) {
setTimeout(function () {
- IAB.close(win);
+ IAB.close();
}, 0);
});
@@ -176,7 +191,7 @@ var IAB = {
browserWrap.appendChild(navigationButtonsDiv);
} else {
- popup.style.height = "100%";
+ popup.style.height = '100%';
}
// start listening for navigation events
@@ -187,8 +202,8 @@ var IAB = {
},
injectScriptCode: function (win, fail, args) {
- var code = args[0],
- hasCallback = args[1];
+ var code = args[0];
+ var hasCallback = args[1];
if (browserWrap && popup) {
try {
@@ -196,7 +211,7 @@ var IAB = {
if (hasCallback) {
win([]);
}
- } catch(e) {
+ } catch (e) {
console.error('Error occured while trying to injectScriptCode: ' + JSON.stringify(e));
}
}
@@ -208,7 +223,7 @@ var IAB = {
if (fail) {
fail(msg);
}
- },
+ },
injectStyleCode: function (win, fail, args) {
var msg = 'Browser cordova-plugin-inappbrowser injectStyleCode is not yet implemented';
@@ -229,4 +244,4 @@ var IAB = {
module.exports = IAB;
-require("cordova/exec/proxy").add("InAppBrowser", module.exports);
+require('cordova/exec/proxy').add('InAppBrowser', module.exports);
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js
deleted file mode 100644
index c09e3583..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-// https://developer.mozilla.org/en-US/docs/WebAPI/Browser
-
-var modulemapper = require('cordova/modulemapper');
-
-var origOpenFunc = modulemapper.getOriginalSymbol(window, 'window.open');
-var browserWrap;
-
-var IABExecs = {
-
- close: function (win, lose) {
- if (browserWrap) {
- browserWrap.parentNode.removeChild(browserWrap);
- browserWrap = null;
- if (typeof(win) == "function") win({type:'exit'});
- }
- },
-
- /*
- * Reveal browser if opened hidden
- */
- show: function (win, lose) {
- console.error('[FirefoxOS] show not implemented');
- },
-
- open: function (win, lose, args) {
- var strUrl = args[0],
- target = args[1],
- features_string = args[2] || "location=yes", //location=yes is default
- features = {};
-
- var features_list = features_string.split(',');
- features_list.forEach(function(feature) {
- var tup = feature.split('=');
- if (tup[1] == 'yes') {
- tup[1] = true;
- } else if (tup[1] == 'no') {
- tup[1] = false;
- } else {
- var number = parseInt(tup[1]);
- if (!isNaN(number)) {
- tup[1] = number;
- }
- }
- features[tup[0]] = tup[1];
- });
-
- function updateIframeSizeNoLocation() {
- browserWrap.style.width = window.innerWidth + 'px';
- browserWrap.style.height = window.innerHeight + 'px';
- browserWrap.style.zIndex = '999999999';
- browserWrap.browser.style.height = (window.innerHeight - 60) + 'px';
- browserWrap.browser.style.width = browserWrap.style.width;
- }
-
- if (target === '_system') {
- origOpenFunc.apply(window, [strUrl, '_blank']);
- } else if (target === '_blank') {
- var browserElem = document.createElement('iframe');
- browserElem.setAttribute('mozbrowser', true);
- // make this loaded in its own child process
- browserElem.setAttribute('remote', true);
- browserElem.setAttribute('src', strUrl);
- if (browserWrap) {
- document.body.removeChild(browserWrap);
- }
- browserWrap = document.createElement('div');
- // assign browser element to browserWrap for future reference
- browserWrap.browser = browserElem;
-
- browserWrap.classList.add('inAppBrowserWrap');
- // position fixed so that it works even when page is scrolled
- browserWrap.style.position = 'fixed';
- browserElem.style.position = 'absolute';
- browserElem.style.border = 0;
- browserElem.style.top = '60px';
- browserElem.style.left = '0px';
- updateIframeSizeNoLocation();
-
- var menu = document.createElement('menu');
- menu.setAttribute('type', 'toolbar');
- var close = document.createElement('li');
- var back = document.createElement('li');
- var forward = document.createElement('li');
-
- close.appendChild(document.createTextNode('×'));
- back.appendChild(document.createTextNode('<'));
- forward.appendChild(document.createTextNode('>'));
-
- close.classList.add('inAppBrowserClose');
- back.classList.add('inAppBrowserBack');
- forward.classList.add('inAppBrowserForward');
-
- var checkForwardBackward = function () {
- var backReq = browserElem.getCanGoBack();
- backReq.onsuccess = function() {
- if (this.result) {
- back.classList.remove('disabled');
- } else {
- back.classList.add('disabled');
- }
- };
- var forwardReq = browserElem.getCanGoForward();
- forwardReq.onsuccess = function() {
- if (this.result) {
- forward.classList.remove('disabled');
- } else {
- forward.classList.add('disabled');
- }
- };
- };
-
- browserElem.addEventListener('mozbrowserloadend', checkForwardBackward);
-
- close.addEventListener('click', function () {
- setTimeout(function () {
- IABExecs.close(win, lose);
- }, 0);
- }, false);
-
- back.addEventListener('click', function () {
- browserElem.goBack();
- }, false);
-
- forward.addEventListener('click', function () {
- browserElem.goForward();
- }, false);
-
- menu.appendChild(back);
- menu.appendChild(forward);
- menu.appendChild(close);
-
- browserWrap.appendChild(menu);
- browserWrap.appendChild(browserElem);
- document.body.appendChild(browserWrap);
-
- //we use mozbrowserlocationchange instead of mozbrowserloadstart to get the url
- browserElem.addEventListener('mozbrowserlocationchange', function(e){
- win({
- type:'loadstart',
- url : e.detail
- });
- }, false);
- browserElem.addEventListener('mozbrowserloadend', function(e){
- win({type:'loadstop'});
- }, false);
- browserElem.addEventListener('mozbrowsererror', function(e){
- win({type:'loaderror'});
- }, false);
- browserElem.addEventListener('mozbrowserclose', function(e){
- win({type:'exit'});
- }, false);
- } else {
- window.location = strUrl;
- }
- },
- injectScriptCode: function (code, bCB) {
- console.error('[FirefoxOS] injectScriptCode not implemented');
- },
- injectScriptFile: function (file, bCB) {
- console.error('[FirefoxOS] injectScriptFile not implemented');
- }
-};
-
-module.exports = IABExecs;
-
-require('cordova/exec/proxy').add('InAppBrowser', module.exports);
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h
deleted file mode 100644
index 6bb0ec16..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
- */
-
-#import <Cordova/CDVPlugin.h>
-#import <Cordova/CDVInvokedUrlCommand.h>
-#import <Cordova/CDVScreenOrientationDelegate.h>
-
-#ifdef __CORDOVA_4_0_0
- #import <Cordova/CDVUIWebViewDelegate.h>
-#else
- #import <Cordova/CDVWebViewDelegate.h>
-#endif
-
-@class CDVInAppBrowserViewController;
-
-@interface CDVInAppBrowser : CDVPlugin {
-}
-
-@property (nonatomic, retain) CDVInAppBrowserViewController* inAppBrowserViewController;
-@property (nonatomic, copy) NSString* callbackId;
-@property (nonatomic, copy) NSRegularExpression *callbackIdPattern;
-
-- (void)open:(CDVInvokedUrlCommand*)command;
-- (void)close:(CDVInvokedUrlCommand*)command;
-- (void)injectScriptCode:(CDVInvokedUrlCommand*)command;
-- (void)show:(CDVInvokedUrlCommand*)command;
-
-@end
-
-@interface CDVInAppBrowserOptions : NSObject {}
-
-@property (nonatomic, assign) BOOL location;
-@property (nonatomic, assign) BOOL toolbar;
-@property (nonatomic, copy) NSString* closebuttoncaption;
-@property (nonatomic, copy) NSString* toolbarposition;
-@property (nonatomic, assign) BOOL clearcache;
-@property (nonatomic, assign) BOOL clearsessioncache;
-
-@property (nonatomic, copy) NSString* presentationstyle;
-@property (nonatomic, copy) NSString* transitionstyle;
-
-@property (nonatomic, assign) BOOL enableviewportscale;
-@property (nonatomic, assign) BOOL mediaplaybackrequiresuseraction;
-@property (nonatomic, assign) BOOL allowinlinemediaplayback;
-@property (nonatomic, assign) BOOL keyboarddisplayrequiresuseraction;
-@property (nonatomic, assign) BOOL suppressesincrementalrendering;
-@property (nonatomic, assign) BOOL hidden;
-@property (nonatomic, assign) BOOL disallowoverscroll;
-
-+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options;
-
-@end
-
-@interface CDVInAppBrowserViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate>{
- @private
- NSString* _userAgent;
- NSString* _prevUserAgent;
- NSInteger _userAgentLockToken;
- CDVInAppBrowserOptions *_browserOptions;
-
-#ifdef __CORDOVA_4_0_0
- CDVUIWebViewDelegate* _webViewDelegate;
-#else
- CDVWebViewDelegate* _webViewDelegate;
-#endif
-
-}
-
-@property (nonatomic, strong) IBOutlet UIWebView* webView;
-@property (nonatomic, strong) IBOutlet UIBarButtonItem* closeButton;
-@property (nonatomic, strong) IBOutlet UILabel* addressLabel;
-@property (nonatomic, strong) IBOutlet UIBarButtonItem* backButton;
-@property (nonatomic, strong) IBOutlet UIBarButtonItem* forwardButton;
-@property (nonatomic, strong) IBOutlet UIActivityIndicatorView* spinner;
-@property (nonatomic, strong) IBOutlet UIToolbar* toolbar;
-
-@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate;
-@property (nonatomic, weak) CDVInAppBrowser* navigationDelegate;
-@property (nonatomic) NSURL* currentURL;
-
-- (void)close;
-- (void)navigateTo:(NSURL*)url;
-- (void)showLocationBar:(BOOL)show;
-- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition;
-- (void)setCloseButtonTitle:(NSString*)title;
-
-- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions;
-
-@end
-
-@interface CDVInAppBrowserNavigationController : UINavigationController
-
-@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate;
-
-@end
-
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.h b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.h
new file mode 100644
index 00000000..bd186a2f
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.h
@@ -0,0 +1,27 @@
+/*
+ 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 <Cordova/CDVScreenOrientationDelegate.h>
+
+
+@interface CDVInAppBrowserNavigationController : UINavigationController
+
+@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate;
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.m b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.m
new file mode 100644
index 00000000..3cc9043f
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserNavigationController.m
@@ -0,0 +1,63 @@
+/*
+ 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 "CDVInAppBrowserNavigationController.h"
+
+@implementation CDVInAppBrowserNavigationController : UINavigationController
+
+- (void) dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
+ if ( self.presentedViewController) {
+ [super dismissViewControllerAnimated:flag completion:completion];
+ }
+}
+
+- (void) viewDidLoad {
+ [super viewDidLoad];
+}
+
+- (CGRect) invertFrameIfNeeded:(CGRect)rect {
+ if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
+ CGFloat temp = rect.size.width;
+ rect.size.width = rect.size.height;
+ rect.size.height = temp;
+ }
+ rect.origin = CGPointZero;
+ return rect;
+}
+
+#pragma mark CDVScreenOrientationDelegate
+
+- (BOOL)shouldAutorotate
+{
+ if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) {
+ return [self.orientationDelegate shouldAutorotate];
+ }
+ return YES;
+}
+
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations
+{
+ if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) {
+ return [self.orientationDelegate supportedInterfaceOrientations];
+ }
+
+ return 1 << UIInterfaceOrientationPortrait;
+}
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.h b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.h
new file mode 100644
index 00000000..c1c9fa53
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.h
@@ -0,0 +1,50 @@
+/*
+ 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.
+ */
+
+
+@interface CDVInAppBrowserOptions : NSObject {}
+
+@property (nonatomic, assign) BOOL location;
+@property (nonatomic, assign) BOOL toolbar;
+@property (nonatomic, copy) NSString* closebuttoncaption;
+@property (nonatomic, copy) NSString* closebuttoncolor;
+@property (nonatomic, assign) BOOL lefttoright;
+@property (nonatomic, copy) NSString* toolbarposition;
+@property (nonatomic, copy) NSString* toolbarcolor;
+@property (nonatomic, assign) BOOL toolbartranslucent;
+@property (nonatomic, assign) BOOL hidenavigationbuttons;
+@property (nonatomic, copy) NSString* navigationbuttoncolor;
+@property (nonatomic, assign) BOOL cleardata;
+@property (nonatomic, assign) BOOL clearcache;
+@property (nonatomic, assign) BOOL clearsessioncache;
+@property (nonatomic, assign) BOOL hidespinner;
+
+@property (nonatomic, copy) NSString* presentationstyle;
+@property (nonatomic, copy) NSString* transitionstyle;
+
+@property (nonatomic, assign) BOOL enableviewportscale;
+@property (nonatomic, assign) BOOL mediaplaybackrequiresuseraction;
+@property (nonatomic, assign) BOOL allowinlinemediaplayback;
+@property (nonatomic, assign) BOOL hidden;
+@property (nonatomic, assign) BOOL disallowoverscroll;
+@property (nonatomic, copy) NSString* beforeload;
+
++ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options;
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.m b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.m
new file mode 100644
index 00000000..e20d1a8c
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowserOptions.m
@@ -0,0 +1,90 @@
+/*
+ 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 "CDVInAppBrowserOptions.h"
+
+@implementation CDVInAppBrowserOptions
+
+- (id)init
+{
+ if (self = [super init]) {
+ // default values
+ self.location = YES;
+ self.toolbar = YES;
+ self.closebuttoncaption = nil;
+ self.toolbarposition = @"bottom";
+ self.cleardata = NO;
+ self.clearcache = NO;
+ self.clearsessioncache = NO;
+ self.hidespinner = NO;
+
+ self.enableviewportscale = NO;
+ self.mediaplaybackrequiresuseraction = NO;
+ self.allowinlinemediaplayback = NO;
+ self.hidden = NO;
+ self.disallowoverscroll = NO;
+ self.hidenavigationbuttons = NO;
+ self.closebuttoncolor = nil;
+ self.lefttoright = false;
+ self.toolbarcolor = nil;
+ self.toolbartranslucent = YES;
+ self.beforeload = @"";
+ }
+
+ return self;
+}
+
++ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options
+{
+ CDVInAppBrowserOptions* obj = [[CDVInAppBrowserOptions alloc] init];
+
+ // NOTE: this parsing does not handle quotes within values
+ NSArray* pairs = [options componentsSeparatedByString:@","];
+
+ // parse keys and values, set the properties
+ for (NSString* pair in pairs) {
+ NSArray* keyvalue = [pair componentsSeparatedByString:@"="];
+
+ if ([keyvalue count] == 2) {
+ NSString* key = [[keyvalue objectAtIndex:0] lowercaseString];
+ NSString* value = [keyvalue objectAtIndex:1];
+ NSString* value_lc = [value lowercaseString];
+
+ BOOL isBoolean = [value_lc isEqualToString:@"yes"] || [value_lc isEqualToString:@"no"];
+ NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
+ [numberFormatter setAllowsFloats:YES];
+ BOOL isNumber = [numberFormatter numberFromString:value_lc] != nil;
+
+ // set the property according to the key name
+ if ([obj respondsToSelector:NSSelectorFromString(key)]) {
+ if (isNumber) {
+ [obj setValue:[numberFormatter numberFromString:value_lc] forKey:key];
+ } else if (isBoolean) {
+ [obj setValue:[NSNumber numberWithBool:[value_lc isEqualToString:@"yes"]] forKey:key];
+ } else {
+ [obj setValue:value forKey:key];
+ }
+ }
+ }
+ }
+
+ return obj;
+}
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowser.h b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowser.h
new file mode 100644
index 00000000..e339be15
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowser.h
@@ -0,0 +1,80 @@
+/*
+ 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 <Cordova/CDVPlugin.h>
+#import <Cordova/CDVInvokedUrlCommand.h>
+#import <Cordova/CDVScreenOrientationDelegate.h>
+#import "CDVWKInAppBrowserUIDelegate.h"
+#import "CDVInAppBrowserOptions.h"
+#import "CDVInAppBrowserNavigationController.h"
+
+@class CDVWKInAppBrowserViewController;
+
+@interface CDVWKInAppBrowser : CDVPlugin {
+ UIWindow * tmpWindow;
+
+ @private
+ NSString* _beforeload;
+ BOOL _waitForBeforeload;
+}
+
+@property (nonatomic, retain) CDVWKInAppBrowser* instance;
+@property (nonatomic, retain) CDVWKInAppBrowserViewController* inAppBrowserViewController;
+@property (nonatomic, copy) NSString* callbackId;
+@property (nonatomic, copy) NSRegularExpression *callbackIdPattern;
+
++ (id) getInstance;
+- (void)open:(CDVInvokedUrlCommand*)command;
+- (void)close:(CDVInvokedUrlCommand*)command;
+- (void)injectScriptCode:(CDVInvokedUrlCommand*)command;
+- (void)show:(CDVInvokedUrlCommand*)command;
+- (void)hide:(CDVInvokedUrlCommand*)command;
+- (void)loadAfterBeforeload:(CDVInvokedUrlCommand*)command;
+
+@end
+
+@interface CDVWKInAppBrowserViewController : UIViewController <CDVScreenOrientationDelegate,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>{
+ @private
+ CDVInAppBrowserOptions *_browserOptions;
+ NSDictionary *_settings;
+}
+
+@property (nonatomic, strong) IBOutlet WKWebView* webView;
+@property (nonatomic, strong) IBOutlet WKWebViewConfiguration* configuration;
+@property (nonatomic, strong) IBOutlet UIBarButtonItem* closeButton;
+@property (nonatomic, strong) IBOutlet UILabel* addressLabel;
+@property (nonatomic, strong) IBOutlet UIBarButtonItem* backButton;
+@property (nonatomic, strong) IBOutlet UIBarButtonItem* forwardButton;
+@property (nonatomic, strong) IBOutlet UIActivityIndicatorView* spinner;
+@property (nonatomic, strong) IBOutlet UIToolbar* toolbar;
+@property (nonatomic, strong) IBOutlet CDVWKInAppBrowserUIDelegate* webViewUIDelegate;
+
+@property (nonatomic, weak) id <CDVScreenOrientationDelegate> orientationDelegate;
+@property (nonatomic, weak) CDVWKInAppBrowser* navigationDelegate;
+@property (nonatomic) NSURL* currentURL;
+
+- (void)close;
+- (void)navigateTo:(NSURL*)url;
+- (void)showLocationBar:(BOOL)show;
+- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition;
+- (void)setCloseButtonTitle:(NSString*)title : (NSString*) colorString : (int) buttonIndex;
+
+- (id)initWithBrowserOptions: (CDVInAppBrowserOptions*) browserOptions andSettings:(NSDictionary*) settings;
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowser.m
index b342ca73..1ec20653 100644
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowser.m
@@ -6,9 +6,9 @@
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
@@ -17,9 +17,13 @@
under the License.
*/
-#import "CDVInAppBrowser.h"
+#import "CDVWKInAppBrowser.h"
+
+#if __has_include("CDVWKProcessPoolFactory.h")
+#import "CDVWKProcessPoolFactory.h"
+#endif
+
#import <Cordova/CDVPluginResult.h>
-#import <Cordova/CDVUserAgentUtil.h>
#define kInAppBrowserTargetSelf @"_self"
#define kInAppBrowserTargetSystem @"_system"
@@ -28,28 +32,34 @@
#define kInAppBrowserToolbarBarPositionBottom @"bottom"
#define kInAppBrowserToolbarBarPositionTop @"top"
+#define IAB_BRIDGE_NAME @"cordova_iab"
+
#define TOOLBAR_HEIGHT 44.0
#define LOCATIONBAR_HEIGHT 21.0
#define FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT))
-#pragma mark CDVInAppBrowser
+#pragma mark CDVWKInAppBrowser
-@interface CDVInAppBrowser () {
+@interface CDVWKInAppBrowser () {
NSInteger _previousStatusBarStyle;
}
@end
-@implementation CDVInAppBrowser
+@implementation CDVWKInAppBrowser
+
+static CDVWKInAppBrowser* instance = nil;
+
++ (id) getInstance{
+ return instance;
+}
- (void)pluginInitialize
{
+ instance = self;
_previousStatusBarStyle = -1;
_callbackIdPattern = nil;
-}
-
-- (id)settingForKey:(NSString*)key
-{
- return [self.commandDelegate.settings objectForKey:[key lowercaseString]];
+ _beforeload = @"";
+ _waitForBeforeload = NO;
}
- (void)onReset
@@ -63,41 +73,38 @@
NSLog(@"IAB.close() called but it was already closed.");
return;
}
+
// Things are cleaned up in browserExit.
[self.inAppBrowserViewController close];
}
- (BOOL) isSystemUrl:(NSURL*)url
{
- if ([[url host] isEqualToString:@"itunes.apple.com"]) {
- return YES;
- }
-
- return NO;
+ if ([[url host] isEqualToString:@"itunes.apple.com"]) {
+ return YES;
+ }
+
+ return NO;
}
- (void)open:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult;
-
+
NSString* url = [command argumentAtIndex:0];
NSString* target = [command argumentAtIndex:1 withDefault:kInAppBrowserTargetSelf];
NSString* options = [command argumentAtIndex:2 withDefault:@"" andClass:[NSString class]];
-
+
self.callbackId = command.callbackId;
-
+
if (url != nil) {
-#ifdef __CORDOVA_4_0_0
NSURL* baseUrl = [self.webViewEngine URL];
-#else
- NSURL* baseUrl = [self.webView.request URL];
-#endif
NSURL* absoluteUrl = [[NSURL URLWithString:url relativeToURL:baseUrl] absoluteURL];
-
+
if ([self isSystemUrl:absoluteUrl]) {
target = kInAppBrowserTargetSystem;
}
-
+
if ([target isEqualToString:kInAppBrowserTargetSelf]) {
[self openInCordovaWebView:absoluteUrl withOptions:options];
} else if ([target isEqualToString:kInAppBrowserTargetSystem]) {
@@ -105,12 +112,12 @@
} else { // _blank or anything else
[self openInInAppBrowser:absoluteUrl withOptions:options];
}
-
+
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"incorrect number of arguments"];
}
-
+
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@@ -118,51 +125,92 @@
- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options
{
CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options];
-
+
+ WKWebsiteDataStore* dataStore = [WKWebsiteDataStore defaultDataStore];
+ if (browserOptions.cleardata) {
+
+ NSDate* dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
+ [dataStore removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:dateFrom completionHandler:^{
+ NSLog(@"Removed all WKWebView data");
+ self.inAppBrowserViewController.webView.configuration.processPool = [[WKProcessPool alloc] init]; // create new process pool to flush all data
+ }];
+ }
+
if (browserOptions.clearcache) {
- NSHTTPCookie *cookie;
- NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- for (cookie in [storage cookies])
- {
- if (![cookie.domain isEqual: @".^filecookies^"]) {
- [storage deleteCookie:cookie];
- }
+ bool isAtLeastiOS11 = false;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+ if (@available(iOS 11.0, *)) {
+ isAtLeastiOS11 = true;
+ }
+#endif
+
+ if(isAtLeastiOS11){
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+ // Deletes all cookies
+ WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
+ [cookieStore getAllCookies:^(NSArray* cookies) {
+ NSHTTPCookie* cookie;
+ for(cookie in cookies){
+ [cookieStore deleteCookie:cookie completionHandler:nil];
+ }
+ }];
+#endif
+ }else{
+ // https://stackoverflow.com/a/31803708/777265
+ // Only deletes domain cookies (not session cookies)
+ [dataStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes]
+ completionHandler:^(NSArray<WKWebsiteDataRecord *> * __nonnull records) {
+ for (WKWebsiteDataRecord *record in records){
+ NSSet<NSString*>* dataTypes = record.dataTypes;
+ if([dataTypes containsObject:WKWebsiteDataTypeCookies]){
+ [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:record.dataTypes
+ forDataRecords:@[record]
+ completionHandler:^{}];
+ }
+ }
+ }];
}
}
-
+
if (browserOptions.clearsessioncache) {
- NSHTTPCookie *cookie;
- NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
- for (cookie in [storage cookies])
- {
- if (![cookie.domain isEqual: @".^filecookies^"] && cookie.isSessionOnly) {
- [storage deleteCookie:cookie];
- }
+ bool isAtLeastiOS11 = false;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+ if (@available(iOS 11.0, *)) {
+ isAtLeastiOS11 = true;
+ }
+#endif
+ if (isAtLeastiOS11) {
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+ // Deletes session cookies
+ WKHTTPCookieStore* cookieStore = dataStore.httpCookieStore;
+ [cookieStore getAllCookies:^(NSArray* cookies) {
+ NSHTTPCookie* cookie;
+ for(cookie in cookies){
+ if(cookie.sessionOnly){
+ [cookieStore deleteCookie:cookie completionHandler:nil];
+ }
+ }
+ }];
+#endif
+ }else{
+ NSLog(@"clearsessioncache not available below iOS 11.0");
}
}
if (self.inAppBrowserViewController == nil) {
- NSString* userAgent = [CDVUserAgentUtil originalUserAgent];
- NSString* overrideUserAgent = [self settingForKey:@"OverrideUserAgent"];
- NSString* appendUserAgent = [self settingForKey:@"AppendUserAgent"];
- if(overrideUserAgent){
- userAgent = overrideUserAgent;
- }
- if(appendUserAgent){
- userAgent = [userAgent stringByAppendingString: appendUserAgent];
- }
- self.inAppBrowserViewController = [[CDVInAppBrowserViewController alloc] initWithUserAgent:userAgent prevUserAgent:[self.commandDelegate userAgent] browserOptions: browserOptions];
+ self.inAppBrowserViewController = [[CDVWKInAppBrowserViewController alloc] initWithBrowserOptions: browserOptions andSettings:self.commandDelegate.settings];
self.inAppBrowserViewController.navigationDelegate = self;
-
+
if ([self.viewController conformsToProtocol:@protocol(CDVScreenOrientationDelegate)]) {
self.inAppBrowserViewController.orientationDelegate = (UIViewController <CDVScreenOrientationDelegate>*)self.viewController;
}
}
-
+
[self.inAppBrowserViewController showLocationBar:browserOptions.location];
[self.inAppBrowserViewController showToolBar:browserOptions.toolbar :browserOptions.toolbarposition];
- if (browserOptions.closebuttoncaption != nil) {
- [self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption];
+ if (browserOptions.closebuttoncaption != nil || browserOptions.closebuttoncolor != nil) {
+ int closeButtonIndex = browserOptions.lefttoright ? (browserOptions.hidenavigationbuttons ? 1 : 4) : 0;
+ [self.inAppBrowserViewController setCloseButtonTitle:browserOptions.closebuttoncaption :browserOptions.closebuttoncolor :closeButtonIndex];
}
// Set Presentation Style
UIModalPresentationStyle presentationStyle = UIModalPresentationFullScreen; // default
@@ -174,7 +222,7 @@
}
}
self.inAppBrowserViewController.modalPresentationStyle = presentationStyle;
-
+
// Set Transition Style
UIModalTransitionStyle transitionStyle = UIModalTransitionStyleCoverVertical; // default
if (browserOptions.transitionstyle != nil) {
@@ -185,8 +233,8 @@
}
}
self.inAppBrowserViewController.modalTransitionStyle = transitionStyle;
-
- // prevent webView from bouncing
+
+ //prevent webView from bouncing
if (browserOptions.disallowoverscroll) {
if ([self.inAppBrowserViewController.webView respondsToSelector:@selector(scrollView)]) {
((UIScrollView*)[self.inAppBrowserViewController.webView scrollView]).bounces = NO;
@@ -198,24 +246,32 @@
}
}
}
-
- // UIWebView options
- self.inAppBrowserViewController.webView.scalesPageToFit = browserOptions.enableviewportscale;
- self.inAppBrowserViewController.webView.mediaPlaybackRequiresUserAction = browserOptions.mediaplaybackrequiresuseraction;
- self.inAppBrowserViewController.webView.allowsInlineMediaPlayback = browserOptions.allowinlinemediaplayback;
- if (IsAtLeastiOSVersion(@"6.0")) {
- self.inAppBrowserViewController.webView.keyboardDisplayRequiresUserAction = browserOptions.keyboarddisplayrequiresuseraction;
- self.inAppBrowserViewController.webView.suppressesIncrementalRendering = browserOptions.suppressesincrementalrendering;
+
+ // use of beforeload event
+ if([browserOptions.beforeload isKindOfClass:[NSString class]]){
+ _beforeload = browserOptions.beforeload;
+ }else{
+ _beforeload = @"yes";
}
-
+ _waitForBeforeload = ![_beforeload isEqualToString:@""];
+
[self.inAppBrowserViewController navigateTo:url];
if (!browserOptions.hidden) {
- [self show:nil];
+ [self show:nil withNoAnimate:browserOptions.hidden];
}
}
-- (void)show:(CDVInvokedUrlCommand*)command
+- (void)show:(CDVInvokedUrlCommand*)command{
+ [self show:command withNoAnimate:NO];
+}
+
+- (void)show:(CDVInvokedUrlCommand*)command withNoAnimate:(BOOL)noAnimate
{
+ BOOL initHidden = NO;
+ if(command == nil && noAnimate == YES){
+ initHidden = YES;
+ }
+
if (self.inAppBrowserViewController == nil) {
NSLog(@"Tried to show IAB after it was closed.");
return;
@@ -224,21 +280,69 @@
NSLog(@"Tried to show IAB while already shown");
return;
}
-
- _previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
-
+
+ if(!initHidden){
+ _previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
+ }
+
__block CDVInAppBrowserNavigationController* nav = [[CDVInAppBrowserNavigationController alloc]
- initWithRootViewController:self.inAppBrowserViewController];
+ initWithRootViewController:self.inAppBrowserViewController];
nav.orientationDelegate = self.inAppBrowserViewController;
nav.navigationBarHidden = YES;
nav.modalPresentationStyle = self.inAppBrowserViewController.modalPresentationStyle;
+
+ __weak CDVWKInAppBrowser* weakSelf = self;
+
+ // Run later to avoid the "took a long time" log message.
+ dispatch_async(dispatch_get_main_queue(), ^{
+ if (weakSelf.inAppBrowserViewController != nil) {
+ float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
+ __strong __typeof(weakSelf) strongSelf = weakSelf;
+ if (!strongSelf->tmpWindow) {
+ CGRect frame = [[UIScreen mainScreen] bounds];
+ if(initHidden && osVersion < 11){
+ frame.origin.x = -10000;
+ }
+ strongSelf->tmpWindow = [[UIWindow alloc] initWithFrame:frame];
+ }
+ UIViewController *tmpController = [[UIViewController alloc] init];
+
+ [strongSelf->tmpWindow setRootViewController:tmpController];
+ [strongSelf->tmpWindow setWindowLevel:UIWindowLevelNormal];
- __weak CDVInAppBrowser* weakSelf = self;
+ if(!initHidden || osVersion < 11){
+ [self->tmpWindow makeKeyAndVisible];
+ }
+ [tmpController presentViewController:nav animated:!noAnimate completion:nil];
+ }
+ });
+}
+- (void)hide:(CDVInvokedUrlCommand*)command
+{
+ // Set tmpWindow to hidden to make main webview responsive to touch again
+ // https://stackoverflow.com/questions/4544489/how-to-remove-a-uiwindow
+ self->tmpWindow.hidden = YES;
+ self->tmpWindow = nil;
+
+ if (self.inAppBrowserViewController == nil) {
+ NSLog(@"Tried to hide IAB after it was closed.");
+ return;
+
+
+ }
+ if (_previousStatusBarStyle == -1) {
+ NSLog(@"Tried to hide IAB while already hidden");
+ return;
+ }
+
+ _previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
+
// Run later to avoid the "took a long time" log message.
dispatch_async(dispatch_get_main_queue(), ^{
- if (weakSelf.inAppBrowserViewController != nil) {
- [weakSelf.viewController presentViewController:nav animated:YES completion:nil];
+ if (self.inAppBrowserViewController != nil) {
+ _previousStatusBarStyle = -1;
+ [self.inAppBrowserViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
});
}
@@ -246,24 +350,39 @@
- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options
{
NSURLRequest* request = [NSURLRequest requestWithURL:url];
-
-#ifdef __CORDOVA_4_0_0
// the webview engine itself will filter for this according to <allow-navigation> policy
// in config.xml for cordova-ios-4.0
[self.webViewEngine loadRequest:request];
-#else
- if ([self.commandDelegate URLIsWhitelisted:url]) {
- [self.webView loadRequest:request];
- } else { // this assumes the InAppBrowser can be excepted from the white-list
- [self openInInAppBrowser:url withOptions:options];
- }
-#endif
}
- (void)openInSystem:(NSURL*)url
{
- [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];
- [[UIApplication sharedApplication] openURL:url];
+ if ([[UIApplication sharedApplication] openURL:url] == NO) {
+ [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]];
+ [[UIApplication sharedApplication] openURL:url];
+ }
+}
+
+- (void)loadAfterBeforeload:(CDVInvokedUrlCommand*)command
+{
+ NSString* urlStr = [command argumentAtIndex:0];
+
+ if ([_beforeload isEqualToString:@""]) {
+ NSLog(@"unexpected loadAfterBeforeload called without feature beforeload=get|post");
+ }
+ if (self.inAppBrowserViewController == nil) {
+ NSLog(@"Tried to invoke loadAfterBeforeload on IAB after it was closed.");
+ return;
+ }
+ if (urlStr == nil) {
+ NSLog(@"loadAfterBeforeload called with nil argument, ignoring.");
+ return;
+ }
+
+ NSURL* url = [NSURL URLWithString:urlStr];
+ //_beforeload = @"";
+ _waitForBeforeload = NO;
+ [self.inAppBrowserViewController navigateTo:url];
}
// This is a helper method for the inject{Script|Style}{Code|File} API calls, which
@@ -277,28 +396,43 @@
- (void)injectDeferredObject:(NSString*)source withWrapper:(NSString*)jsWrapper
{
- // Ensure an iframe bridge is created to communicate with the CDVInAppBrowserViewController
- [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:@"(function(d){_cdvIframeBridge=d.getElementById('_cdvIframeBridge');if(!_cdvIframeBridge) {var e = _cdvIframeBridge = d.createElement('iframe');e.id='_cdvIframeBridge'; e.style.display='none';d.body.appendChild(e);}})(document)"];
-
+ // Ensure a message handler bridge is created to communicate with the CDVWKInAppBrowserViewController
+ [self evaluateJavaScript: [NSString stringWithFormat:@"(function(w){if(!w._cdvMessageHandler) {w._cdvMessageHandler = function(id,d){w.webkit.messageHandlers.%@.postMessage({d:d, id:id});}}})(window)", IAB_BRIDGE_NAME]];
+
if (jsWrapper != nil) {
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:@[source] options:0 error:nil];
NSString* sourceArrayString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
if (sourceArrayString) {
NSString* sourceString = [sourceArrayString substringWithRange:NSMakeRange(1, [sourceArrayString length] - 2)];
NSString* jsToInject = [NSString stringWithFormat:jsWrapper, sourceString];
- [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:jsToInject];
+ [self evaluateJavaScript:jsToInject];
}
} else {
- [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:source];
+ [self evaluateJavaScript:source];
}
}
+
+//Synchronus helper for javascript evaluation
+- (void)evaluateJavaScript:(NSString *)script {
+ __block NSString* _script = script;
+ [self.inAppBrowserViewController.webView evaluateJavaScript:script completionHandler:^(id result, NSError *error) {
+ if (error == nil) {
+ if (result != nil) {
+ NSLog(@"%@", result);
+ }
+ } else {
+ NSLog(@"evaluateJavaScript error : %@ : %@", error.localizedDescription, _script);
+ }
+ }];
+}
+
- (void)injectScriptCode:(CDVInvokedUrlCommand*)command
{
NSString* jsWrapper = nil;
-
+
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
- jsWrapper = [NSString stringWithFormat:@"_cdvIframeBridge.src='gap-iab://%@/'+encodeURIComponent(JSON.stringify([eval(%%@)]));", command.callbackId];
+ jsWrapper = [NSString stringWithFormat:@"_cdvMessageHandler('%@',JSON.stringify([eval(%%@)]));", command.callbackId];
}
[self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper];
}
@@ -306,9 +440,9 @@
- (void)injectScriptFile:(CDVInvokedUrlCommand*)command
{
NSString* jsWrapper;
-
+
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
- jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('script'); c.src = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)", command.callbackId];
+ jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('script'); c.src = %%@; c.onload = function() { _cdvMessageHandler('%@'); }; d.body.appendChild(c); })(document)", command.callbackId];
} else {
jsWrapper = @"(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)";
}
@@ -318,9 +452,9 @@
- (void)injectStyleCode:(CDVInvokedUrlCommand*)command
{
NSString* jsWrapper;
-
+
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
- jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('style'); c.innerHTML = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)", command.callbackId];
+ jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('style'); c.innerHTML = %%@; c.onload = function() { _cdvMessageHandler('%@'); }; d.body.appendChild(c); })(document)", command.callbackId];
} else {
jsWrapper = @"(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document)";
}
@@ -330,9 +464,9 @@
- (void)injectStyleFile:(CDVInvokedUrlCommand*)command
{
NSString* jsWrapper;
-
+
if ((command.callbackId != nil) && ![command.callbackId isEqualToString:@"INVALID"]) {
- jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%@; c.onload = function() { _cdvIframeBridge.src='gap-iab://%@'; }; d.body.appendChild(c); })(document)", command.callbackId];
+ jsWrapper = [NSString stringWithFormat:@"(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %%@; c.onload = function() { _cdvMessageHandler('%@'); }; d.body.appendChild(c); })(document)", command.callbackId];
} else {
jsWrapper = @"(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document)";
}
@@ -357,94 +491,163 @@
}
/**
- * The iframe bridge provided for the InAppBrowser is capable of executing any oustanding callback belonging
+ * The message handler 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 iframe (or any other resource) should attempt to load a url of the form:
- *
- * gap-iab://<callbackId>/<arguments>
- *
- * where <callbackId> is the string id of the callback to trigger (something like "InAppBrowser0123456789")
- *
- * If present, the path component of the special gap-iab:// url is expected to be a URL-escaped JSON-encoded
- * value to pass to the callback. [NSURL path] should take care of the URL-unescaping, and a JSON_EXCEPTION
- * is returned if the JSON is invalid.
*/
-- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
-{
- NSURL* url = request.URL;
- BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]];
-
- // See if the url uses the 'gap-iab' protocol. If so, the host should be the id of a callback to execute,
- // and the path, if present, should be a JSON-encoded value to pass to the callback.
- if ([[url scheme] isEqualToString:@"gap-iab"]) {
- NSString* scriptCallbackId = [url host];
- CDVPluginResult* pluginResult = nil;
-
- if ([self isValidCallbackId:scriptCallbackId]) {
- NSString* scriptResult = [url path];
- NSError* __autoreleasing error = nil;
+- (void)webView:(WKWebView *)theWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
+
+ NSURL* url = navigationAction.request.URL;
+ NSURL* mainDocumentURL = navigationAction.request.mainDocumentURL;
+ BOOL isTopLevelNavigation = [url isEqual:mainDocumentURL];
+ BOOL shouldStart = YES;
+ BOOL useBeforeLoad = NO;
+ NSString* httpMethod = navigationAction.request.HTTPMethod;
+ NSString* errorMessage = nil;
+
+ if([_beforeload isEqualToString:@"post"]){
+ //TODO handle POST requests by preserving POST data then remove this condition
+ errorMessage = @"beforeload doesn't yet support POST requests";
+ }
+ else if(isTopLevelNavigation && (
+ [_beforeload isEqualToString:@"yes"]
+ || ([_beforeload isEqualToString:@"get"] && [httpMethod isEqualToString:@"GET"])
+ // TODO comment in when POST requests are handled
+ // || ([_beforeload isEqualToString:@"post"] && [httpMethod isEqualToString:@"POST"])
+ )){
+ useBeforeLoad = YES;
+ }
- // The message should be a JSON-encoded array of the result of the script which executed.
- if ((scriptResult != nil) && ([scriptResult length] > 1)) {
- scriptResult = [scriptResult substringFromIndex:1];
- NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[scriptResult dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
- if ((error == nil) && [decodedResult isKindOfClass:[NSArray class]]) {
- pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:(NSArray*)decodedResult];
- } else {
- pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION];
- }
- } else {
- pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:@[]];
- }
- [self.commandDelegate sendPluginResult:pluginResult callbackId:scriptCallbackId];
- return NO;
- }
- }
+ // When beforeload, on first URL change, initiate JS callback. Only after the beforeload event, continue.
+ if (_waitForBeforeload && useBeforeLoad) {
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
+ messageAsDictionary:@{@"type":@"beforeload", @"url":[url absoluteString]}];
+ [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
+
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
+ decisionHandler(WKNavigationActionPolicyCancel);
+ return;
+ }
+
+ if(errorMessage != nil){
+ NSLog(errorMessage);
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
+ messageAsDictionary:@{@"type":@"loaderror", @"url":[url absoluteString], @"code": @"-1", @"message": errorMessage}];
+ [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
+ }
+
//if is an app store link, let the system handle it, otherwise it fails to load it
- else if ([[ url scheme] isEqualToString:@"itms-appss"] || [[ url scheme] isEqualToString:@"itms-apps"]) {
+ if ([[ url scheme] isEqualToString:@"itms-appss"] || [[ url scheme] isEqualToString:@"itms-apps"]) {
[theWebView stopLoading];
[self openInSystem:url];
- return NO;
+ shouldStart = NO;
}
else if ((self.callbackId != nil) && isTopLevelNavigation) {
// Send a loadstart event for each top-level navigation (includes redirects).
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsDictionary:@{@"type":@"loadstart", @"url":[url absoluteString]}];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
-
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
- return YES;
+ if (useBeforeLoad) {
+ _waitForBeforeload = YES;
+ }
+
+ if(shouldStart){
+ // Fix GH-417 & GH-424: Handle non-default target attribute
+ // Based on https://stackoverflow.com/a/25713070/777265
+ if (!navigationAction.targetFrame){
+ [theWebView loadRequest:navigationAction.request];
+ decisionHandler(WKNavigationActionPolicyCancel);
+ }else{
+ decisionHandler(WKNavigationActionPolicyAllow);
+ }
+ }else{
+ decisionHandler(WKNavigationActionPolicyCancel);
+ }
}
-- (void)webViewDidStartLoad:(UIWebView*)theWebView
+#pragma mark WKScriptMessageHandler delegate
+- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
+
+ CDVPluginResult* pluginResult = nil;
+
+ if([message.body isKindOfClass:[NSDictionary class]]){
+ NSDictionary* messageContent = (NSDictionary*) message.body;
+ NSString* scriptCallbackId = messageContent[@"id"];
+
+ if([messageContent objectForKey:@"d"]){
+ NSString* scriptResult = messageContent[@"d"];
+ NSError* __autoreleasing error = nil;
+ NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[scriptResult dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
+ if ((error == nil) && [decodedResult isKindOfClass:[NSArray class]]) {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:(NSArray*)decodedResult];
+ } else {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_JSON_EXCEPTION];
+ }
+ } else {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsArray:@[]];
+ }
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:scriptCallbackId];
+ }else if(self.callbackId != nil){
+ // Send a message event
+ NSString* messageContent = (NSString*) message.body;
+ NSError* __autoreleasing error = nil;
+ NSData* decodedResult = [NSJSONSerialization JSONObjectWithData:[messageContent dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&error];
+ if (error == nil) {
+ NSMutableDictionary* dResult = [NSMutableDictionary new];
+ [dResult setValue:@"message" forKey:@"type"];
+ [dResult setObject:decodedResult forKey:@"data"];
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dResult];
+ [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
+ }
+ }
+}
+
+- (void)didStartProvisionalNavigation:(WKWebView*)theWebView
{
+ NSLog(@"didStartProvisionalNavigation");
+// self.inAppBrowserViewController.currentURL = theWebView.URL;
}
-- (void)webViewDidFinishLoad:(UIWebView*)theWebView
+- (void)didFinishNavigation:(WKWebView*)theWebView
{
if (self.callbackId != nil) {
- // TODO: It would be more useful to return the URL the page is actually on (e.g. if it's been redirected).
- NSString* url = [self.inAppBrowserViewController.currentURL absoluteString];
+ NSString* url = [theWebView.URL absoluteString];
+ if(url == nil){
+ if(self.inAppBrowserViewController.currentURL != nil){
+ url = [self.inAppBrowserViewController.currentURL absoluteString];
+ }else{
+ url = @"";
+ }
+ }
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsDictionary:@{@"type":@"loadstop", @"url":url}];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
-
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
}
-- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
+- (void)webView:(WKWebView*)theWebView didFailNavigation:(NSError*)error
{
if (self.callbackId != nil) {
- NSString* url = [self.inAppBrowserViewController.currentURL absoluteString];
+ NSString* url = [theWebView.URL absoluteString];
+ if(url == nil){
+ if(self.inAppBrowserViewController.currentURL != nil){
+ url = [self.inAppBrowserViewController.currentURL absoluteString];
+ }else{
+ url = @"";
+ }
+ }
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR
messageAsDictionary:@{@"type":@"loaderror", @"url":url, @"code": [NSNumber numberWithInteger:error.code], @"message": error.localizedDescription}];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
-
+
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
}
}
@@ -457,78 +660,135 @@
[self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
self.callbackId = nil;
}
+
+ [self.inAppBrowserViewController.configuration.userContentController removeScriptMessageHandlerForName:IAB_BRIDGE_NAME];
+ self.inAppBrowserViewController.configuration = nil;
+
+ [self.inAppBrowserViewController.webView stopLoading];
+ [self.inAppBrowserViewController.webView removeFromSuperview];
+ [self.inAppBrowserViewController.webView setUIDelegate:nil];
+ [self.inAppBrowserViewController.webView setNavigationDelegate:nil];
+ self.inAppBrowserViewController.webView = 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.
- // Also - this is required for the PDF/User-Agent bug work-around.
self.inAppBrowserViewController = nil;
+ // Set tmpWindow to hidden to make main webview responsive to touch again
+ // Based on https://stackoverflow.com/questions/4544489/how-to-remove-a-uiwindow
+ self->tmpWindow.hidden = YES;
+ self->tmpWindow = nil;
+
if (IsAtLeastiOSVersion(@"7.0")) {
if (_previousStatusBarStyle != -1) {
[[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle];
+
}
}
-
+
_previousStatusBarStyle = -1; // this value was reset before reapplying it. caused statusbar to stay black on ios7
}
-@end
+@end //CDVWKInAppBrowser
-#pragma mark CDVInAppBrowserViewController
+#pragma mark CDVWKInAppBrowserViewController
-@implementation CDVInAppBrowserViewController
+@implementation CDVWKInAppBrowserViewController
@synthesize currentURL;
-- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions
+CGFloat lastReducedStatusBarHeight = 0.0;
+BOOL isExiting = FALSE;
+
+- (id)initWithBrowserOptions: (CDVInAppBrowserOptions*) browserOptions andSettings:(NSDictionary *)settings
{
self = [super init];
if (self != nil) {
- _userAgent = userAgent;
- _prevUserAgent = prevUserAgent;
_browserOptions = browserOptions;
-#ifdef __CORDOVA_4_0_0
- _webViewDelegate = [[CDVUIWebViewDelegate alloc] initWithDelegate:self];
-#else
- _webViewDelegate = [[CDVWebViewDelegate alloc] initWithDelegate:self];
-#endif
+ _settings = settings;
+ self.webViewUIDelegate = [[CDVWKInAppBrowserUIDelegate alloc] initWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]];
+ [self.webViewUIDelegate setViewController:self];
[self createViews];
}
-
+
return self;
}
-// Prevent crashes on closing windows
-(void)dealloc {
- self.webView.delegate = nil;
+ //NSLog(@"dealloc");
}
- (void)createViews
{
// We create the views in code for primarily for ease of upgrades and not requiring an external .xib to be included
-
+
CGRect webViewBounds = self.view.bounds;
BOOL toolbarIsAtBottom = ![_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop];
webViewBounds.size.height -= _browserOptions.location ? FOOTER_HEIGHT : TOOLBAR_HEIGHT;
- self.webView = [[UIWebView alloc] initWithFrame:webViewBounds];
-
- self.webView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
+ WKUserContentController* userContentController = [[WKUserContentController alloc] init];
+
+ WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
+
+ NSString *userAgent = configuration.applicationNameForUserAgent;
+ if (
+ [self settingForKey:@"OverrideUserAgent"] == nil &&
+ [self settingForKey:@"AppendUserAgent"] != nil
+ ) {
+ userAgent = [NSString stringWithFormat:@"%@ %@", userAgent, [self settingForKey:@"AppendUserAgent"]];
+ }
+ configuration.applicationNameForUserAgent = userAgent;
+ configuration.userContentController = userContentController;
+#if __has_include("CDVWKProcessPoolFactory.h")
+ configuration.processPool = [[CDVWKProcessPoolFactory sharedFactory] sharedProcessPool];
+#endif
+ [configuration.userContentController addScriptMessageHandler:self name:IAB_BRIDGE_NAME];
+
+ //WKWebView options
+ configuration.allowsInlineMediaPlayback = _browserOptions.allowinlinemediaplayback;
+ if (IsAtLeastiOSVersion(@"10.0")) {
+ configuration.ignoresViewportScaleLimits = _browserOptions.enableviewportscale;
+ if(_browserOptions.mediaplaybackrequiresuseraction == YES){
+ configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
+ }else{
+ configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
+ }
+ }else{ // iOS 9
+ configuration.mediaPlaybackRequiresUserAction = _browserOptions.mediaplaybackrequiresuseraction;
+ }
+
+
+ self.webView = [[WKWebView alloc] initWithFrame:webViewBounds configuration:configuration];
+
[self.view addSubview:self.webView];
[self.view sendSubviewToBack:self.webView];
-
- self.webView.delegate = _webViewDelegate;
+
+
+ self.webView.navigationDelegate = self;
+ self.webView.UIDelegate = self.webViewUIDelegate;
self.webView.backgroundColor = [UIColor whiteColor];
-
+ if ([self settingForKey:@"OverrideUserAgent"] != nil) {
+ self.webView.customUserAgent = [self settingForKey:@"OverrideUserAgent"];
+ }
+
self.webView.clearsContextBeforeDrawing = YES;
self.webView.clipsToBounds = YES;
self.webView.contentMode = UIViewContentModeScaleToFill;
self.webView.multipleTouchEnabled = YES;
self.webView.opaque = YES;
- self.webView.scalesPageToFit = NO;
self.webView.userInteractionEnabled = YES;
-
+ self.automaticallyAdjustsScrollViewInsets = YES ;
+ [self.webView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
+ self.webView.allowsLinkPreview = NO;
+ self.webView.allowsBackForwardNavigationGestures = NO;
+
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
+ if (@available(iOS 11.0, *)) {
+ [self.webView.scrollView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
+ }
+#endif
+
self.spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.spinner.alpha = 1.000;
self.spinner.autoresizesSubviews = YES;
@@ -543,18 +803,18 @@
self.spinner.opaque = NO;
self.spinner.userInteractionEnabled = NO;
[self.spinner stopAnimating];
-
+
self.closeButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(close)];
self.closeButton.enabled = YES;
-
+
UIBarButtonItem* flexibleSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
-
+
UIBarButtonItem* fixedSpaceButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
fixedSpaceButton.width = 20;
-
+
float toolbarY = toolbarIsAtBottom ? self.view.bounds.size.height - TOOLBAR_HEIGHT : 0.0;
CGRect toolbarFrame = CGRectMake(0.0, toolbarY, self.view.bounds.size.width, TOOLBAR_HEIGHT);
-
+
self.toolbar = [[UIToolbar alloc] initWithFrame:toolbarFrame];
self.toolbar.alpha = 1.000;
self.toolbar.autoresizesSubviews = YES;
@@ -567,10 +827,16 @@
self.toolbar.multipleTouchEnabled = NO;
self.toolbar.opaque = NO;
self.toolbar.userInteractionEnabled = YES;
-
+ if (_browserOptions.toolbarcolor != nil) { // Set toolbar color if user sets it in options
+ self.toolbar.barTintColor = [self colorFromHexString:_browserOptions.toolbarcolor];
+ }
+ if (!_browserOptions.toolbartranslucent) { // Set toolbar translucent to no if user sets it in options
+ self.toolbar.translucent = NO;
+ }
+
CGFloat labelInset = 5.0;
float locationBarY = toolbarIsAtBottom ? self.view.bounds.size.height - FOOTER_HEIGHT : self.view.bounds.size.height - LOCATIONBAR_HEIGHT;
-
+
self.addressLabel = [[UILabel alloc] initWithFrame:CGRectMake(labelInset, locationBarY, self.view.bounds.size.width - labelInset, LOCATIONBAR_HEIGHT)];
self.addressLabel.adjustsFontSizeToFitWidth = NO;
self.addressLabel.alpha = 1.000;
@@ -584,13 +850,13 @@
self.addressLabel.enabled = YES;
self.addressLabel.hidden = NO;
self.addressLabel.lineBreakMode = NSLineBreakByTruncatingTail;
-
+
if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumScaleFactor:")]) {
[self.addressLabel setValue:@(10.0/[UIFont labelFontSize]) forKey:@"minimumScaleFactor"];
} else if ([self.addressLabel respondsToSelector:NSSelectorFromString(@"setMinimumFontSize:")]) {
[self.addressLabel setValue:@(10.0) forKey:@"minimumFontSize"];
}
-
+
self.addressLabel.multipleTouchEnabled = NO;
self.addressLabel.numberOfLines = 1;
self.addressLabel.opaque = NO;
@@ -599,84 +865,108 @@
self.addressLabel.textAlignment = NSTextAlignmentLeft;
self.addressLabel.textColor = [UIColor colorWithWhite:1.000 alpha:1.000];
self.addressLabel.userInteractionEnabled = NO;
-
+
NSString* frontArrowString = NSLocalizedString(@"►", nil); // create arrow from Unicode char
self.forwardButton = [[UIBarButtonItem alloc] initWithTitle:frontArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goForward:)];
self.forwardButton.enabled = YES;
self.forwardButton.imageInsets = UIEdgeInsetsZero;
+ if (_browserOptions.navigationbuttoncolor != nil) { // Set button color if user sets it in options
+ self.forwardButton.tintColor = [self colorFromHexString:_browserOptions.navigationbuttoncolor];
+ }
NSString* backArrowString = NSLocalizedString(@"◄", nil); // create arrow from Unicode char
self.backButton = [[UIBarButtonItem alloc] initWithTitle:backArrowString style:UIBarButtonItemStylePlain target:self action:@selector(goBack:)];
self.backButton.enabled = YES;
self.backButton.imageInsets = UIEdgeInsetsZero;
+ if (_browserOptions.navigationbuttoncolor != nil) { // Set button color if user sets it in options
+ self.backButton.tintColor = [self colorFromHexString:_browserOptions.navigationbuttoncolor];
+ }
- [self.toolbar setItems:@[self.closeButton, flexibleSpaceButton, self.backButton, fixedSpaceButton, self.forwardButton]];
-
- self.view.backgroundColor = [UIColor grayColor];
+ // Filter out Navigation Buttons if user requests so
+ if (_browserOptions.hidenavigationbuttons) {
+ if (_browserOptions.lefttoright) {
+ [self.toolbar setItems:@[flexibleSpaceButton, self.closeButton]];
+ } else {
+ [self.toolbar setItems:@[self.closeButton, flexibleSpaceButton]];
+ }
+ } else if (_browserOptions.lefttoright) {
+ [self.toolbar setItems:@[self.backButton, fixedSpaceButton, self.forwardButton, flexibleSpaceButton, self.closeButton]];
+ } else {
+ [self.toolbar setItems:@[self.closeButton, flexibleSpaceButton, self.backButton, fixedSpaceButton, self.forwardButton]];
+ }
+
+ self.view.backgroundColor = [UIColor clearColor];
[self.view addSubview:self.toolbar];
[self.view addSubview:self.addressLabel];
[self.view addSubview:self.spinner];
}
+- (id)settingForKey:(NSString*)key
+{
+ return [_settings objectForKey:[key lowercaseString]];
+}
+
- (void) setWebViewFrame : (CGRect) frame {
NSLog(@"Setting the WebView's frame to %@", NSStringFromCGRect(frame));
[self.webView setFrame:frame];
}
-- (void)setCloseButtonTitle:(NSString*)title
+- (void)setCloseButtonTitle:(NSString*)title : (NSString*) colorString : (int) buttonIndex
{
// the advantage of using UIBarButtonSystemItemDone is the system will localize it for you automatically
// but, if you want to set this yourself, knock yourself out (we can't set the title for a system Done button, so we have to create a new one)
self.closeButton = nil;
- self.closeButton = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStyleBordered target:self action:@selector(close)];
+ // Initialize with title if title is set, otherwise the title will be 'Done' localized
+ self.closeButton = title != nil ? [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStyleBordered target:self action:@selector(close)] : [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(close)];
self.closeButton.enabled = YES;
- self.closeButton.tintColor = [UIColor colorWithRed:60.0 / 255.0 green:136.0 / 255.0 blue:230.0 / 255.0 alpha:1];
-
+ // If color on closebutton is requested then initialize with that that color, otherwise use initialize with default
+ self.closeButton.tintColor = colorString != nil ? [self colorFromHexString:colorString] : [UIColor colorWithRed:60.0 / 255.0 green:136.0 / 255.0 blue:230.0 / 255.0 alpha:1];
+
NSMutableArray* items = [self.toolbar.items mutableCopy];
- [items replaceObjectAtIndex:0 withObject:self.closeButton];
+ [items replaceObjectAtIndex:buttonIndex withObject:self.closeButton];
[self.toolbar setItems:items];
}
- (void)showLocationBar:(BOOL)show
{
CGRect locationbarFrame = self.addressLabel.frame;
-
+
BOOL toolbarVisible = !self.toolbar.hidden;
-
+
// prevent double show/hide
if (show == !(self.addressLabel.hidden)) {
return;
}
-
+
if (show) {
self.addressLabel.hidden = NO;
-
+
if (toolbarVisible) {
// toolBar at the bottom, leave as is
// put locationBar on top of the toolBar
-
+
CGRect webViewBounds = self.view.bounds;
webViewBounds.size.height -= FOOTER_HEIGHT;
[self setWebViewFrame:webViewBounds];
-
+
locationbarFrame.origin.y = webViewBounds.size.height;
self.addressLabel.frame = locationbarFrame;
} else {
// no toolBar, so put locationBar at the bottom
-
+
CGRect webViewBounds = self.view.bounds;
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
[self setWebViewFrame:webViewBounds];
-
+
locationbarFrame.origin.y = webViewBounds.size.height;
self.addressLabel.frame = locationbarFrame;
}
} else {
self.addressLabel.hidden = YES;
-
+
if (toolbarVisible) {
// locationBar is on top of toolBar, hide locationBar
-
+
// webView take up whole height less toolBar height
CGRect webViewBounds = self.view.bounds;
webViewBounds.size.height -= TOOLBAR_HEIGHT;
@@ -692,18 +982,18 @@
{
CGRect toolbarFrame = self.toolbar.frame;
CGRect locationbarFrame = self.addressLabel.frame;
-
+
BOOL locationbarVisible = !self.addressLabel.hidden;
-
+
// prevent double show/hide
if (show == !(self.toolbar.hidden)) {
return;
}
-
+
if (show) {
self.toolbar.hidden = NO;
CGRect webViewBounds = self.view.bounds;
-
+
if (locationbarVisible) {
// locationBar at the bottom, move locationBar up
// put toolBar at the bottom
@@ -717,7 +1007,7 @@
webViewBounds.size.height -= TOOLBAR_HEIGHT;
self.toolbar.frame = toolbarFrame;
}
-
+
if ([toolbarPosition isEqualToString:kInAppBrowserToolbarBarPositionTop]) {
toolbarFrame.origin.y = 0;
webViewBounds.origin.y += toolbarFrame.size.height;
@@ -726,19 +1016,19 @@
toolbarFrame.origin.y = (webViewBounds.size.height + LOCATIONBAR_HEIGHT);
}
[self setWebViewFrame:webViewBounds];
-
+
} else {
self.toolbar.hidden = YES;
-
+
if (locationbarVisible) {
// locationBar is on top of toolBar, hide toolBar
// put locationBar at the bottom
-
+
// webView take up whole height less locationBar height
CGRect webViewBounds = self.view.bounds;
webViewBounds.size.height -= LOCATIONBAR_HEIGHT;
[self setWebViewFrame:webViewBounds];
-
+
// move locationBar down
locationbarFrame.origin.y = webViewBounds.size.height;
self.addressLabel.frame = locationbarFrame;
@@ -754,11 +1044,13 @@
[super viewDidLoad];
}
-- (void)viewDidUnload
+- (void)viewDidDisappear:(BOOL)animated
{
- [self.webView loadHTMLString:nil baseURL:nil];
- [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
- [super viewDidUnload];
+ [super viewDidDisappear:animated];
+ if (isExiting && (self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) {
+ [self.navigationDelegate browserExit];
+ isExiting = FALSE;
+ }
}
- (UIStatusBarStyle)preferredStatusBarStyle
@@ -772,17 +1064,13 @@
- (void)close
{
- [CDVUserAgentUtil releaseLock:&_userAgentLockToken];
self.currentURL = nil;
-
- if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) {
- [self.navigationDelegate browserExit];
- }
-
+
__weak UIViewController* weakSelf = self;
-
+
// Run later to avoid the "took a long time" log message.
dispatch_async(dispatch_get_main_queue(), ^{
+ isExiting = TRUE;
if ([weakSelf respondsToSelector:@selector(presentingViewController)]) {
[[weakSelf presentingViewController] dismissViewControllerAnimated:YES completion:nil];
} else {
@@ -793,17 +1081,11 @@
- (void)navigateTo:(NSURL*)url
{
- NSURLRequest* request = [NSURLRequest requestWithURL:url];
-
- if (_userAgentLockToken != 0) {
- [self.webView loadRequest:request];
+ if ([url.scheme isEqualToString:@"file"]) {
+ [self.webView loadFileURL:url allowingReadAccessToURL:url];
} else {
- __weak CDVInAppBrowserViewController* weakSelf = self;
- [CDVUserAgentUtil acquireLock:^(NSInteger lockToken) {
- _userAgentLockToken = lockToken;
- [CDVUserAgentUtil setUserAgent:_userAgent lockToken:lockToken];
- [weakSelf.webView loadRequest:request];
- }];
+ NSURLRequest* request = [NSURLRequest requestWithURL:url];
+ [self.webView loadRequest:request];
}
}
@@ -819,11 +1101,8 @@
- (void)viewWillAppear:(BOOL)animated
{
- if (IsAtLeastiOSVersion(@"7.0")) {
- [[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]];
- }
[self rePositionViews];
-
+
[super viewWillAppear:animated];
}
@@ -833,213 +1112,117 @@
// change that value.
//
- (float) getStatusBarOffset {
- CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
- float statusBarOffset = IsAtLeastiOSVersion(@"7.0") ? MIN(statusBarFrame.size.width, statusBarFrame.size.height) : 0.0;
- return statusBarOffset;
+ return (float) IsAtLeastiOSVersion(@"7.0") ? [[UIApplication sharedApplication] statusBarFrame].size.height : 0.0;
}
- (void) rePositionViews {
- if ([_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop]) {
- [self.webView setFrame:CGRectMake(self.webView.frame.origin.x, TOOLBAR_HEIGHT, self.webView.frame.size.width, self.webView.frame.size.height)];
- [self.toolbar setFrame:CGRectMake(self.toolbar.frame.origin.x, [self getStatusBarOffset], self.toolbar.frame.size.width, self.toolbar.frame.size.height)];
+ CGRect viewBounds = [self.webView bounds];
+ CGFloat statusBarHeight = [self getStatusBarOffset];
+
+ // orientation portrait or portraitUpsideDown: status bar is on the top and web view is to be aligned to the bottom of the status bar
+ // orientation landscapeLeft or landscapeRight: status bar height is 0 in but lets account for it in case things ever change in the future
+ viewBounds.origin.y = statusBarHeight;
+
+ // account for web view height portion that may have been reduced by a previous call to this method
+ viewBounds.size.height = viewBounds.size.height - statusBarHeight + lastReducedStatusBarHeight;
+ lastReducedStatusBarHeight = statusBarHeight;
+
+ if ((_browserOptions.toolbar) && ([_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop])) {
+ // if we have to display the toolbar on top of the web view, we need to account for its height
+ viewBounds.origin.y += TOOLBAR_HEIGHT;
+ self.toolbar.frame = CGRectMake(self.toolbar.frame.origin.x, statusBarHeight, self.toolbar.frame.size.width, self.toolbar.frame.size.height);
}
+
+ self.webView.frame = viewBounds;
}
-#pragma mark UIWebViewDelegate
+// Helper function to convert hex color string to UIColor
+// Assumes input like "#00FF00" (#RRGGBB).
+// Taken from https://stackoverflow.com/questions/1560081/how-can-i-create-a-uicolor-from-a-hex-string
+- (UIColor *)colorFromHexString:(NSString *)hexString {
+ unsigned rgbValue = 0;
+ NSScanner *scanner = [NSScanner scannerWithString:hexString];
+ [scanner setScanLocation:1]; // bypass '#' character
+ [scanner scanHexInt:&rgbValue];
+ return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0];
+}
-- (void)webViewDidStartLoad:(UIWebView*)theWebView
-{
- // loading url, start spinner, update back/forward
+#pragma mark WKNavigationDelegate
+- (void)webView:(WKWebView *)theWebView didStartProvisionalNavigation:(WKNavigation *)navigation{
+
+ // loading url, start spinner, update back/forward
+
self.addressLabel.text = NSLocalizedString(@"Loading...", nil);
self.backButton.enabled = theWebView.canGoBack;
self.forwardButton.enabled = theWebView.canGoForward;
-
- [self.spinner startAnimating];
-
- return [self.navigationDelegate webViewDidStartLoad:theWebView];
+
+ NSLog(_browserOptions.hidespinner ? @"Yes" : @"No");
+ if(!_browserOptions.hidespinner) {
+ [self.spinner startAnimating];
+ }
+
+ return [self.navigationDelegate didStartProvisionalNavigation:theWebView];
}
-- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
+- (void)webView:(WKWebView *)theWebView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
- BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]];
-
+ NSURL *url = navigationAction.request.URL;
+ NSURL *mainDocumentURL = navigationAction.request.mainDocumentURL;
+
+ BOOL isTopLevelNavigation = [url isEqual:mainDocumentURL];
+
if (isTopLevelNavigation) {
- self.currentURL = request.URL;
+ self.currentURL = url;
}
- return [self.navigationDelegate webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
+
+ [self.navigationDelegate webView:theWebView decidePolicyForNavigationAction:navigationAction decisionHandler:decisionHandler];
}
-- (void)webViewDidFinishLoad:(UIWebView*)theWebView
+- (void)webView:(WKWebView *)theWebView didFinishNavigation:(WKNavigation *)navigation
{
// update url, stop spinner, update back/forward
-
+
self.addressLabel.text = [self.currentURL absoluteString];
self.backButton.enabled = theWebView.canGoBack;
self.forwardButton.enabled = theWebView.canGoForward;
-
+ theWebView.scrollView.contentInset = UIEdgeInsetsZero;
+
[self.spinner stopAnimating];
-
- // Work around a bug where the first time a PDF is opened, all UIWebViews
- // reload their User-Agent from NSUserDefaults.
- // This work-around makes the following assumptions:
- // 1. The app has only a single Cordova Webview. If not, then the app should
- // take it upon themselves to load a PDF in the background as a part of
- // their start-up flow.
- // 2. That the PDF does not require any additional network requests. We change
- // the user-agent here back to that of the CDVViewController, so requests
- // from it must pass through its white-list. This *does* break PDFs that
- // contain links to other remote PDF/websites.
- // More info at https://issues.apache.org/jira/browse/CB-2225
- BOOL isPDF = [@"true" isEqualToString :[theWebView stringByEvaluatingJavaScriptFromString:@"document.body==null"]];
- if (isPDF) {
- [CDVUserAgentUtil setUserAgent:_prevUserAgent lockToken:_userAgentLockToken];
- }
-
- [self.navigationDelegate webViewDidFinishLoad:theWebView];
+
+ [self.navigationDelegate didFinishNavigation:theWebView];
}
-
-- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
-{
+
+- (void)webView:(WKWebView*)theWebView failedNavigation:(NSString*) delegateName withError:(nonnull NSError *)error{
// log fail message, stop spinner, update back/forward
- NSLog(@"webView:didFailLoadWithError - %ld: %@", (long)error.code, [error localizedDescription]);
-
+ NSLog(@"webView:%@ - %ld: %@", delegateName, (long)error.code, [error localizedDescription]);
+
self.backButton.enabled = theWebView.canGoBack;
self.forwardButton.enabled = theWebView.canGoForward;
[self.spinner stopAnimating];
-
+
self.addressLabel.text = NSLocalizedString(@"Load Error", nil);
-
- [self.navigationDelegate webView:theWebView didFailLoadWithError:error];
-}
-
-#pragma mark CDVScreenOrientationDelegate
-
-- (BOOL)shouldAutorotate
-{
- if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotate)]) {
- return [self.orientationDelegate shouldAutorotate];
- }
- return YES;
-}
-
-- (NSUInteger)supportedInterfaceOrientations
-{
- if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) {
- return [self.orientationDelegate supportedInterfaceOrientations];
- }
-
- return 1 << UIInterfaceOrientationPortrait;
-}
-
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-{
- if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
- return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation];
- }
-
- return YES;
+
+ [self.navigationDelegate webView:theWebView didFailNavigation:error];
}
-@end
-
-@implementation CDVInAppBrowserOptions
-
-- (id)init
+- (void)webView:(WKWebView*)theWebView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error
{
- if (self = [super init]) {
- // default values
- self.location = YES;
- self.toolbar = YES;
- self.closebuttoncaption = nil;
- self.toolbarposition = kInAppBrowserToolbarBarPositionBottom;
- self.clearcache = NO;
- self.clearsessioncache = NO;
-
- self.enableviewportscale = NO;
- self.mediaplaybackrequiresuseraction = NO;
- self.allowinlinemediaplayback = NO;
- self.keyboarddisplayrequiresuseraction = YES;
- self.suppressesincrementalrendering = NO;
- self.hidden = NO;
- self.disallowoverscroll = NO;
- }
-
- return self;
+ [self webView:theWebView failedNavigation:@"didFailNavigation" withError:error];
}
-
-+ (CDVInAppBrowserOptions*)parseOptions:(NSString*)options
+
+- (void)webView:(WKWebView*)theWebView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error
{
- CDVInAppBrowserOptions* obj = [[CDVInAppBrowserOptions alloc] init];
-
- // NOTE: this parsing does not handle quotes within values
- NSArray* pairs = [options componentsSeparatedByString:@","];
-
- // parse keys and values, set the properties
- for (NSString* pair in pairs) {
- NSArray* keyvalue = [pair componentsSeparatedByString:@"="];
-
- if ([keyvalue count] == 2) {
- NSString* key = [[keyvalue objectAtIndex:0] lowercaseString];
- NSString* value = [keyvalue objectAtIndex:1];
- NSString* value_lc = [value lowercaseString];
-
- BOOL isBoolean = [value_lc isEqualToString:@"yes"] || [value_lc isEqualToString:@"no"];
- NSNumberFormatter* numberFormatter = [[NSNumberFormatter alloc] init];
- [numberFormatter setAllowsFloats:YES];
- BOOL isNumber = [numberFormatter numberFromString:value_lc] != nil;
-
- // set the property according to the key name
- if ([obj respondsToSelector:NSSelectorFromString(key)]) {
- if (isNumber) {
- [obj setValue:[numberFormatter numberFromString:value_lc] forKey:key];
- } else if (isBoolean) {
- [obj setValue:[NSNumber numberWithBool:[value_lc isEqualToString:@"yes"]] forKey:key];
- } else {
- [obj setValue:value forKey:key];
- }
- }
- }
- }
-
- return obj;
+ [self webView:theWebView failedNavigation:@"didFailProvisionalNavigation" withError:error];
}
-@end
-
-@implementation CDVInAppBrowserNavigationController : UINavigationController
-
-- (void) dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
- if ( self.presentedViewController) {
- [super dismissViewControllerAnimated:flag completion:completion];
- }
-}
-
-- (void) viewDidLoad {
-
- CGRect frame = [UIApplication sharedApplication].statusBarFrame;
-
- // simplified from: http://stackoverflow.com/a/25669695/219684
-
- UIToolbar* bgToolbar = [[UIToolbar alloc] initWithFrame:[self invertFrameIfNeeded:frame]];
- bgToolbar.barStyle = UIBarStyleDefault;
- [bgToolbar setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
- [self.view addSubview:bgToolbar];
-
- [super viewDidLoad];
-}
-
-- (CGRect) invertFrameIfNeeded:(CGRect)rect {
- // We need to invert since on iOS 7 frames are always in Portrait context
- if (!IsAtLeastiOSVersion(@"8.0")) {
- if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
- CGFloat temp = rect.size.width;
- rect.size.width = rect.size.height;
- rect.size.height = temp;
- }
- rect.origin = CGPointZero;
+#pragma mark WKScriptMessageHandler delegate
+- (void)userContentController:(nonnull WKUserContentController *)userContentController didReceiveScriptMessage:(nonnull WKScriptMessage *)message {
+ if (![message.name isEqualToString:IAB_BRIDGE_NAME]) {
+ return;
}
- return rect;
+ //NSLog(@"Received script message %@", message.body);
+ [self.navigationDelegate userContentController:userContentController didReceiveScriptMessage:message];
}
#pragma mark CDVScreenOrientationDelegate
@@ -1052,24 +1235,27 @@
return YES;
}
-- (NSUInteger)supportedInterfaceOrientations
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(supportedInterfaceOrientations)]) {
return [self.orientationDelegate supportedInterfaceOrientations];
}
-
+
return 1 << UIInterfaceOrientationPortrait;
}
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
- if ((self.orientationDelegate != nil) && [self.orientationDelegate respondsToSelector:@selector(shouldAutorotateToInterfaceOrientation:)]) {
- return [self.orientationDelegate shouldAutorotateToInterfaceOrientation:interfaceOrientation];
- }
+ [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
+ {
+ [self rePositionViews];
+ } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
+ {
- return YES;
-}
+ }];
+ [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+}
-@end
+@end //CDVWKInAppBrowserViewController
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.h b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.h
new file mode 100644
index 00000000..1a6ea220
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.h
@@ -0,0 +1,32 @@
+/*
+ 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 <WebKit/WebKit.h>
+
+@interface CDVWKInAppBrowserUIDelegate : NSObject <WKUIDelegate>{
+ @private
+ UIViewController* _viewController;
+}
+
+@property (nonatomic, copy) NSString* title;
+
+- (instancetype)initWithTitle:(NSString*)title;
+-(void) setViewController:(UIViewController*) viewController;
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.m b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.m
new file mode 100644
index 00000000..4bc7a76b
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ios/CDVWKInAppBrowserUIDelegate.m
@@ -0,0 +1,127 @@
+/*
+ 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 "CDVWKInAppBrowserUIDelegate.h"
+
+@implementation CDVWKInAppBrowserUIDelegate
+
+- (instancetype)initWithTitle:(NSString*)title
+{
+ self = [super init];
+ if (self) {
+ self.title = title;
+ }
+
+ return self;
+}
+
+- (void) webView:(WKWebView*)webView runJavaScriptAlertPanelWithMessage:(NSString*)message
+ initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(void))completionHandler
+{
+ UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
+ message:message
+ preferredStyle:UIAlertControllerStyleAlert];
+
+ UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK")
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction* action)
+ {
+ completionHandler();
+ [alert dismissViewControllerAnimated:YES completion:nil];
+ }];
+
+ [alert addAction:ok];
+
+ [[self getViewController] presentViewController:alert animated:YES completion:nil];
+}
+
+- (void) webView:(WKWebView*)webView runJavaScriptConfirmPanelWithMessage:(NSString*)message
+ initiatedByFrame:(WKFrameInfo*)frame completionHandler:(void (^)(BOOL result))completionHandler
+{
+ UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
+ message:message
+ preferredStyle:UIAlertControllerStyleAlert];
+
+ UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK")
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction* action)
+ {
+ completionHandler(YES);
+ [alert dismissViewControllerAnimated:YES completion:nil];
+ }];
+
+ [alert addAction:ok];
+
+ UIAlertAction* cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel")
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction* action)
+ {
+ completionHandler(NO);
+ [alert dismissViewControllerAnimated:YES completion:nil];
+ }];
+ [alert addAction:cancel];
+
+ [[self getViewController] presentViewController:alert animated:YES completion:nil];
+}
+
+- (void) webView:(WKWebView*)webView runJavaScriptTextInputPanelWithPrompt:(NSString*)prompt
+ defaultText:(NSString*)defaultText initiatedByFrame:(WKFrameInfo*)frame
+ completionHandler:(void (^)(NSString* result))completionHandler
+{
+ UIAlertController* alert = [UIAlertController alertControllerWithTitle:self.title
+ message:prompt
+ preferredStyle:UIAlertControllerStyleAlert];
+
+ UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"OK", @"OK")
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction* action)
+ {
+ completionHandler(((UITextField*)alert.textFields[0]).text);
+ [alert dismissViewControllerAnimated:YES completion:nil];
+ }];
+
+ [alert addAction:ok];
+
+ UIAlertAction* cancel = [UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel")
+ style:UIAlertActionStyleDefault
+ handler:^(UIAlertAction* action)
+ {
+ completionHandler(nil);
+ [alert dismissViewControllerAnimated:YES completion:nil];
+ }];
+ [alert addAction:cancel];
+
+ [alert addTextFieldWithConfigurationHandler:^(UITextField* textField) {
+ textField.text = defaultText;
+ }];
+
+ [[self getViewController] presentViewController:alert animated:YES completion:nil];
+}
+
+-(UIViewController*) getViewController
+{
+ return _viewController;
+}
+
+-(void) setViewController:(UIViewController*) viewController
+{
+ _viewController = viewController;
+}
+
+@end
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.h b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.h
new file mode 100644
index 00000000..742af70a
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.h
@@ -0,0 +1,30 @@
+/*
+ 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 <Cordova/CDVPlugin.h>
+
+@interface CDVInAppBrowser : CDVPlugin {
+}
+
+@property (nonatomic, copy) NSString* callbackId;
+
+- (void)open:(CDVInvokedUrlCommand*)command;
+
+@end
+
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.m b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.m
new file mode 100644
index 00000000..9d579e15
--- /dev/null
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/osx/CDVInAppBrowser.m
@@ -0,0 +1,89 @@
+/*
+ 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 "CDVInAppBrowser.h"
+#import <Cordova/CDVPluginResult.h>
+
+#define kInAppBrowserTargetSelf @"_self"
+#define kInAppBrowserTargetSystem @"_system"
+#define kInAppBrowserTargetBlank @"_blank"
+
+@interface CDVInAppBrowser () {
+}
+@end
+
+@implementation CDVInAppBrowser
+
+- (void)pluginInitialize
+{
+}
+
+- (BOOL) isSystemUrl:(NSURL*)url
+{
+ if ([[url host] isEqualToString:@"itunes.apple.com"]) {
+ return YES;
+ }
+
+ return NO;
+}
+
+- (void)open:(CDVInvokedUrlCommand*)command
+{
+ CDVPluginResult* pluginResult;
+
+ NSString* url = [command argumentAtIndex:0];
+ NSString* target = [command argumentAtIndex:1 withDefault:kInAppBrowserTargetSelf];
+
+ self.callbackId = command.callbackId;
+
+ if (url != nil) {
+
+ NSURL* baseUrl = [NSURL URLWithString:url];
+
+ NSURL* absoluteUrl = [[NSURL URLWithString:url relativeToURL:baseUrl] absoluteURL];
+
+ if ([self isSystemUrl:absoluteUrl]) {
+ target = kInAppBrowserTargetSystem;
+ }
+
+ if ([target isEqualToString:kInAppBrowserTargetSelf]) {
+ //[self openInCordovaWebView:absoluteUrl withOptions:options];
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not Yet Implemented for OSX: [self openInCordovaWebView:absoluteUrl withOptions:options]"];
+ } else if ([target isEqualToString:kInAppBrowserTargetSystem]) {
+ [self openInSystem:absoluteUrl];
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ } else { // _blank or anything else
+ //[self openInInAppBrowser:absoluteUrl withOptions:options];
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Not Yet Implemented for OSX: [self openInInAppBrowser:absoluteUrl withOptions:options]"];
+ }
+
+ } else {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"incorrect number of arguments"];
+ }
+ [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+}
+
+- (void)openInSystem:(NSURL*)url
+{
+ [[NSWorkspace sharedWorkspace] openURL:url];
+}
+
+@end
+
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml
deleted file mode 100644
index 781e8a6e..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *
- * 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 Ubuntu.Components.Popups 0.1
-import Ubuntu.Components 0.1
-import com.canonical.Oxide 1.0
-
-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])
- }
- }
- }
- }
-
- property string usContext: "oxide://main-world/2"
-
- function executeJS(scId, code) {
- var req = _view.rootFrame.sendMessage(usContext, "EXECUTE", {code: code});
-
- req.onreply = function(response) {
- var code = 'cordova.callback(' + scId + ', JSON.parse(\'' + JSON.stringify(response.result) + '\'))';
- console.warn(code);
- cordova.javaScriptExecNeeded(code);
- console.warn("RESP:" + JSON.stringify(response));
- };
- }
-
- WebView {
- width: parent.width
- y: urlEntry.height
- height: parent.height - y
- url: url1
- id: _view
- onLoadingStateChanged: {
- root.exec("InAppBrowser", "loadFinished", [_view.loading])
- }
- context: WebContext {
- id: webcontext
-
- userScripts: [
- UserScript {
- context: usContext
- emulateGreasemonkey: true
- url: "InAppBrowser_escapeScript.js"
- }
- ]
- }
- }
-}
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js
deleted file mode 100644
index b01daeb5..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
-*/
-
-/* jshint -W061 */
-/* global oxide */
-
-oxide.addMessageHandler("EXECUTE", function(msg) {
- var code = msg.args.code;
- try {
- msg.reply({result: eval(code)});
- } catch(e) {
- msg.error("Code threw exception: \"" + e + "\"");
- }
-});
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png
deleted file mode 100644
index 56373d1f..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png
+++ /dev/null
Binary files differ
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp
deleted file mode 100644
index c5a9e64a..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *
- * 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; \
-function createObject() { \
- component = Qt.createComponent(%1); \
- if (component.status == Component.Ready) \
- finishCreation(); \
- else \
- component.statusChanged.connect(finishCreation); \
-} \
-function finishCreation() { \
- CordovaWrapper.global.inappbrowser = component.createObject(root, \
- {root: root, cordova: cordova, url1: %2}); \
-} \
-createObject()";
-
-const char EXIT_EVENT[] = "{type: 'exit'}";
-const char LOADSTART_EVENT[] = "{type: 'loadstart'}";
-const char LOADSTOP_EVENT[] = "{type: 'loadstop'}";
-const char LOADERROR_EVENT[] = "{type: 'loaderror'}";
-
-void Inappbrowser::open(int cb, int, const QString &url, const QString &, const QString &) {
- assert(_eventCb == 0);
-
- _eventCb = cb;
-
- QString path = m_cordova->get_app_dir() + "/../qml/InAppBrowser.qml";
- 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.global.inappbrowser.visible = true");
-}
-
-void Inappbrowser::close(int, int) {
- m_cordova->execQML("CordovaWrapper.global.inappbrowser.destroy()");
- this->callbackWithoutRemove(_eventCb, EXIT_EVENT);
- _eventCb = 0;
-}
-
-void Inappbrowser::injectStyleFile(int scId, int ecId, const QString& src, bool b) {
- QString code("(function(d) { var c = d.createElement('link'); c.rel='stylesheet'; c.type='text/css'; c.href = %1; d.head.appendChild(c);})(document)");
- code = code.arg(CordovaInternal::format(src));
-
- injectScriptCode(scId, ecId, code, b);
-}
-
-void Inappbrowser::injectStyleCode(int scId, int ecId, const QString& src, bool b) {
- QString code("(function(d) { var c = d.createElement('style'); c.innerHTML = %1; d.body.appendChild(c); })(document)");
- code = code.arg(CordovaInternal::format(src));
-
- injectScriptCode(scId, ecId, code, b);
-}
-
-void Inappbrowser::injectScriptFile(int scId, int ecId, const QString& src, bool b) {
- QString code("(function(d) { var c = d.createElement('script'); c.src = %1; d.body.appendChild(c);})(document)");
- code = code.arg(CordovaInternal::format(src));
-
- injectScriptCode(scId, ecId, code, b);
-}
-
-void Inappbrowser::injectScriptCode(int scId, int, const QString& code, bool) {
- m_cordova->execQML(QString("CordovaWrapper.global.inappbrowser.executeJS(%2, %1)").arg(CordovaInternal::format(code)).arg(scId));
-}
-
-void Inappbrowser::loadFinished(bool status) {
- if (!status) {
- this->callbackWithoutRemove(_eventCb, LOADSTOP_EVENT);
- } else {
- this->callbackWithoutRemove(_eventCb, LOADSTART_EVENT);
- }
-}
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h
deleted file mode 100644
index 1da4e033..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *
- * 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(bool status);
-
-private:
- int _eventCb;
-};
-
-#endif
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js
index 23f6e547..9e544c5d 100644
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js
+++ b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js
@@ -1,4 +1,4 @@
-/*
+/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -21,9 +21,10 @@
/* jslint sloppy:true */
/* global Windows:true, setImmediate */
+/* eslint standard/no-callback-literal : 0 */
-var cordova = require('cordova'),
- urlutil = require('cordova/urlutil');
+var cordova = require('cordova');
+var urlutil = require('cordova/urlutil');
var browserWrap,
popup,
@@ -40,56 +41,56 @@ var browserWrap,
// http://msdn.microsoft.com/en-us/library/windows/apps/dn301831.aspx
var isWebViewAvailable = cordova.platformId === 'windows';
-function attachNavigationEvents(element, callback) {
+function attachNavigationEvents (element, callback) {
if (isWebViewAvailable) {
- element.addEventListener("MSWebViewNavigationStarting", function (e) {
- callback({ type: "loadstart", url: e.uri}, {keepCallback: true} );
+ element.addEventListener('MSWebViewNavigationStarting', function (e) {
+ callback({ type: 'loadstart', url: e.uri }, {keepCallback: true});
});
- element.addEventListener("MSWebViewNavigationCompleted", function (e) {
+ element.addEventListener('MSWebViewNavigationCompleted', function (e) {
if (e.isSuccess) {
- callback({ type: "loadstop", url: e.uri }, { keepCallback: true });
+ callback({ type: 'loadstop', url: e.uri }, { keepCallback: true });
} else {
- callback({ type: "loaderror", url: e.uri, code: e.webErrorStatus, message: "Navigation failed with error code " + e.webErrorStatus}, { keepCallback: true });
+ callback({ type: 'loaderror', url: e.uri, code: e.webErrorStatus, message: 'Navigation failed with error code ' + e.webErrorStatus }, { keepCallback: true });
}
});
- element.addEventListener("MSWebViewUnviewableContentIdentified", function (e) {
+ element.addEventListener('MSWebViewUnviewableContentIdentified', function (e) {
// WebView found the content to be not HTML.
// http://msdn.microsoft.com/en-us/library/windows/apps/dn609716.aspx
- callback({ type: "loaderror", url: e.uri, code: e.webErrorStatus, message: "Navigation failed with error code " + e.webErrorStatus}, { keepCallback: true });
+ callback({ type: 'loaderror', url: e.uri, code: e.webErrorStatus, message: 'Navigation failed with error code ' + e.webErrorStatus }, { keepCallback: true });
});
- element.addEventListener("MSWebViewContentLoading", function (e) {
+ element.addEventListener('MSWebViewContentLoading', function (e) {
if (navigationButtonsDiv && popup) {
if (popup.canGoBack) {
- backButton.removeAttribute("disabled");
+ backButton.removeAttribute('disabled');
} else {
- backButton.setAttribute("disabled", "true");
+ backButton.setAttribute('disabled', 'true');
}
if (popup.canGoForward) {
- forwardButton.removeAttribute("disabled");
+ forwardButton.removeAttribute('disabled');
} else {
- forwardButton.setAttribute("disabled", "true");
+ forwardButton.setAttribute('disabled', 'true');
}
}
});
} else {
var onError = function () {
- callback({ type: "loaderror", url: this.contentWindow.location}, {keepCallback: true});
+ callback({ type: 'loaderror', url: this.contentWindow.location }, {keepCallback: true});
};
- element.addEventListener("unload", function () {
- callback({ type: "loadstart", url: this.contentWindow.location}, {keepCallback: true});
+ element.addEventListener('unload', function () {
+ callback({ type: 'loadstart', url: this.contentWindow.location }, {keepCallback: true});
});
- element.addEventListener("load", function () {
- callback({ type: "loadstop", url: this.contentWindow.location}, {keepCallback: true});
+ element.addEventListener('load', function () {
+ callback({ type: 'loadstop', url: this.contentWindow.location }, {keepCallback: true});
});
- element.addEventListener("error", onError);
- element.addEventListener("abort", onError);
+ element.addEventListener('error', onError);
+ element.addEventListener('abort', onError);
}
}
@@ -98,7 +99,7 @@ var IAB = {
setImmediate(function () {
if (browserWrap) {
if (navigationEventsCallback) {
- navigationEventsCallback({ type: "exit" });
+ navigationEventsCallback({ type: 'exit' });
}
browserWrap.parentNode.removeChild(browserWrap);
@@ -107,47 +108,52 @@ var IAB = {
browserWrap = null;
popup = null;
- document.removeEventListener("backbutton", hardwareBackCallback, false);
+ document.removeEventListener('backbutton', hardwareBackCallback, false);
}
});
},
show: function (win, lose) {
setImmediate(function () {
if (browserWrap) {
- browserWrap.style.display = "block";
+ browserWrap.style.display = 'block';
}
});
},
+ hide: function (win, lose) {
+ if (browserWrap) {
+ browserWrap.style.display = 'none';
+ }
+ },
open: function (win, lose, args) {
// make function async so that we can add navigation events handlers before view is loaded and navigation occured
setImmediate(function () {
- var strUrl = args[0],
- target = args[1],
- features = args[2],
- url;
+ var strUrl = args[0];
+ var target = args[1];
+ var features = args[2];
+ var url;
navigationEventsCallback = win;
- if (target === "_system") {
+ if (target === '_system') {
url = new Windows.Foundation.Uri(strUrl);
Windows.System.Launcher.launchUriAsync(url);
- } else if (target === "_self" || !target) {
+ } else if (target === '_self' || !target) {
window.location = strUrl;
} else {
// "_blank" or anything else
if (!browserWrap) {
var browserWrapStyle = document.createElement('link');
- browserWrapStyle.rel = "stylesheet";
- browserWrapStyle.type = "text/css";
- browserWrapStyle.href = urlutil.makeAbsolute("/www/css/inappbrowser.css");
+ browserWrapStyle.rel = 'stylesheet';
+ browserWrapStyle.type = 'text/css';
+ browserWrapStyle.href = urlutil.makeAbsolute('/www/css/inappbrowser.css');
document.head.appendChild(browserWrapStyle);
- browserWrap = document.createElement("div");
- browserWrap.className = "inAppBrowserWrap";
+ browserWrap = document.createElement('div');
+ browserWrap.className = 'inAppBrowserWrap';
- if (features.indexOf("fullscreen=yes") > -1) {
- browserWrap.classList.add("inAppBrowserWrapFullscreen");
+ if (features.indexOf('fullscreen=yes') > -1) {
+ browserWrap.classList.add('inAppBrowserWrapFullscreen');
}
// Save body overflow style to be able to reset it back later
@@ -161,22 +167,22 @@ var IAB = {
document.body.appendChild(browserWrap);
// Hide scrollbars for the whole body while inappbrowser's window is open
- document.body.style.msOverflowStyle = "none";
+ document.body.style.msOverflowStyle = 'none';
}
- if (features.indexOf("hidden=yes") !== -1) {
- browserWrap.style.display = "none";
+ if (features.indexOf('hidden=yes') !== -1) {
+ browserWrap.style.display = 'none';
}
- popup = document.createElement(isWebViewAvailable ? "x-ms-webview" : "iframe");
- if (popup instanceof HTMLIFrameElement) {
+ popup = document.createElement(isWebViewAvailable ? 'x-ms-webview' : 'iframe');
+ if (popup instanceof HTMLIFrameElement) { // eslint-disable-line no-undef
// For iframe we need to override bacground color of parent element here
// otherwise pages without background color set will have transparent background
- popup.style.backgroundColor = "white";
+ popup.style.backgroundColor = 'white';
}
- popup.style.borderWidth = "0px";
- popup.style.width = "100%";
- popup.style.marginBottom = "-3px";
+ popup.style.borderWidth = '0px';
+ popup.style.width = '100%';
+ popup.style.marginBottom = '-5px';
browserWrap.appendChild(popup);
@@ -186,14 +192,14 @@ var IAB = {
}, 0);
};
- if (features.indexOf("hardwareback=yes") > -1 || features.indexOf("hardwareback") === -1) {
+ if (features.indexOf('hardwareback=yes') > -1 || features.indexOf('hardwareback') === -1) {
hardwareBackCallback = function () {
if (browserWrap.style.display === 'none') {
// NOTE: backbutton handlers have to throw an exception in order to prevent
// returning 'true' inside cordova-js, which would mean that the event is handled by user.
// Throwing an exception means that the default/system navigation behavior will take place,
// which is to exit the app if the navigation stack is empty.
- throw 'Exit the app';
+ throw 'Exit the app'; // eslint-disable-line no-throw-literal
}
if (popup.canGoBack) {
@@ -202,59 +208,57 @@ var IAB = {
closeHandler();
}
};
- } else if (features.indexOf("hardwareback=no") > -1) {
+ } else if (features.indexOf('hardwareback=no') > -1) {
hardwareBackCallback = function () {
if (browserWrap.style.display === 'none') {
// See comment above
- throw 'Exit the app';
+ throw 'Exit the app'; // eslint-disable-line no-throw-literal
}
closeHandler();
};
}
- document.addEventListener("backbutton", hardwareBackCallback, false);
+ document.addEventListener('backbutton', hardwareBackCallback, false);
- if (features.indexOf("location=yes") !== -1 || features.indexOf("location") === -1) {
- popup.style.height = "calc(100% - 70px)";
+ if (features.indexOf('location=yes') !== -1 || features.indexOf('location') === -1) {
+ popup.style.height = 'calc(100% - 70px)';
- navigationButtonsDiv = document.createElement("div");
- navigationButtonsDiv.className = "inappbrowser-app-bar";
+ navigationButtonsDiv = document.createElement('div');
+ navigationButtonsDiv.className = 'inappbrowser-app-bar';
navigationButtonsDiv.onclick = function (e) {
e.cancelBubble = true;
};
- navigationButtonsDivInner = document.createElement("div");
- navigationButtonsDivInner.className = "inappbrowser-app-bar-inner";
+ navigationButtonsDivInner = document.createElement('div');
+ navigationButtonsDivInner.className = 'inappbrowser-app-bar-inner';
navigationButtonsDivInner.onclick = function (e) {
e.cancelBubble = true;
};
- backButton = document.createElement("div");
- backButton.innerText = "back";
- backButton.className = "app-bar-action action-back";
- backButton.addEventListener("click", function (e) {
- if (popup.canGoBack)
- popup.goBack();
+ backButton = document.createElement('div');
+ backButton.innerText = 'back';
+ backButton.className = 'app-bar-action action-back';
+ backButton.addEventListener('click', function (e) {
+ if (popup.canGoBack) { popup.goBack(); }
});
- forwardButton = document.createElement("div");
- forwardButton.innerText = "forward";
- forwardButton.className = "app-bar-action action-forward";
- forwardButton.addEventListener("click", function (e) {
- if (popup.canGoForward)
- popup.goForward();
+ forwardButton = document.createElement('div');
+ forwardButton.innerText = 'forward';
+ forwardButton.className = 'app-bar-action action-forward';
+ forwardButton.addEventListener('click', function (e) {
+ if (popup.canGoForward) { popup.goForward(); }
});
- closeButton = document.createElement("div");
- closeButton.innerText = "close";
- closeButton.className = "app-bar-action action-close";
- closeButton.addEventListener("click", closeHandler);
+ closeButton = document.createElement('div');
+ closeButton.innerText = 'close';
+ closeButton.className = 'app-bar-action action-close';
+ closeButton.addEventListener('click', closeHandler);
if (!isWebViewAvailable) {
// iframe navigation is not yet supported
- backButton.setAttribute("disabled", "true");
- forwardButton.setAttribute("disabled", "true");
+ backButton.setAttribute('disabled', 'true');
+ forwardButton.setAttribute('disabled', 'true');
}
navigationButtonsDivInner.appendChild(backButton);
@@ -264,14 +268,14 @@ var IAB = {
browserWrap.appendChild(navigationButtonsDiv);
} else {
- popup.style.height = "100%";
+ popup.style.height = '100%';
}
// start listening for navigation events
attachNavigationEvents(popup, navigationEventsCallback);
if (isWebViewAvailable) {
- strUrl = strUrl.replace("ms-appx://", "ms-appx-web://");
+ strUrl = strUrl.replace('ms-appx://', 'ms-appx-web://');
}
popup.src = strUrl;
}
@@ -280,11 +284,11 @@ var IAB = {
injectScriptCode: function (win, fail, args) {
setImmediate(function () {
- var code = args[0],
- hasCallback = args[1];
+ var code = args[0];
+ var hasCallback = args[1];
if (isWebViewAvailable && browserWrap && popup) {
- var op = popup.invokeScriptAsync("eval", code);
+ var op = popup.invokeScriptAsync('eval', code);
op.oncomplete = function (e) {
if (hasCallback) {
// return null if event target is unavailable by some reason
@@ -300,19 +304,20 @@ var IAB = {
injectScriptFile: function (win, fail, args) {
setImmediate(function () {
- var filePath = args[0],
- hasCallback = args[1];
+ var filePath = args[0];
+ var hasCallback = args[1];
- if (!!filePath) {
+ if (filePath) {
filePath = urlutil.makeAbsolute(filePath);
}
if (isWebViewAvailable && browserWrap && popup) {
- var uri = new Windows.Foundation.Uri(filePath);
+ // CB-12364 getFileFromApplicationUriAsync does not support ms-appx-web
+ var uri = new Windows.Foundation.Uri(filePath.replace('ms-appx-web:', 'ms-appx:'));
Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).done(function (file) {
Windows.Storage.FileIO.readTextAsync(file).done(function (code) {
- var op = popup.invokeScriptAsync("eval", code);
- op.oncomplete = function(e) {
+ var op = popup.invokeScriptAsync('eval', code);
+ op.oncomplete = function (e) {
if (hasCallback) {
var result = [e.target.result];
win(result);
@@ -328,8 +333,8 @@ var IAB = {
injectStyleCode: function (win, fail, args) {
setImmediate(function () {
- var code = args[0],
- hasCallback = args[1];
+ var code = args[0];
+ var hasCallback = args[1];
if (isWebViewAvailable && browserWrap && popup) {
injectCSS(popup, code, hasCallback && win);
@@ -339,13 +344,14 @@ var IAB = {
injectStyleFile: function (win, fail, args) {
setImmediate(function () {
- var filePath = args[0],
- hasCallback = args[1];
+ var filePath = args[0];
+ var hasCallback = args[1];
filePath = filePath && urlutil.makeAbsolute(filePath);
if (isWebViewAvailable && browserWrap && popup) {
- var uri = new Windows.Foundation.Uri(filePath);
+ // CB-12364 getFileFromApplicationUriAsync does not support ms-appx-web
+ var uri = new Windows.Foundation.Uri(filePath.replace('ms-appx-web:', 'ms-appx:'));
Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) {
return Windows.Storage.FileIO.readTextAsync(file);
}).done(function (code) {
@@ -361,11 +367,11 @@ var IAB = {
function injectCSS (webView, cssCode, callback) {
// This will automatically escape all thing that we need (quotes, slashes, etc.)
var escapedCode = JSON.stringify(cssCode);
- var evalWrapper = "(function(d){var c=d.createElement('style');c.innerHTML=%s;d.head.appendChild(c);})(document)"
+ var evalWrapper = '(function(d){var c=d.createElement(\'style\');c.innerHTML=%s;d.head.appendChild(c);})(document)'
.replace('%s', escapedCode);
- var op = webView.invokeScriptAsync("eval", evalWrapper);
- op.oncomplete = function() {
+ var op = webView.invokeScriptAsync('eval', evalWrapper);
+ op.oncomplete = function () {
if (callback) {
callback([]);
}
@@ -376,4 +382,4 @@ function injectCSS (webView, cssCode, callback) {
module.exports = IAB;
-require("cordova/exec/proxy").add("InAppBrowser", module.exports);
+require('cordova/exec/proxy').add('InAppBrowser', module.exports);
diff --git a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs b/StoneIsland/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs
deleted file mode 100644
index ddb51227..00000000
--- a/StoneIsland/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Runtime.Serialization;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-
-#if WP8
-using System.Threading.Tasks;
-using Windows.ApplicationModel;
-using Windows.Storage;
-using Windows.System;
-
-//Use alias in case Cordova File Plugin is enabled. Then the File class will be declared in both and error will occur.
-using IOFile = System.IO.File;
-#else
-using Microsoft.Phone.Tasks;
-#endif
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
- [DataContract]
- public class BrowserOptions
- {
- [DataMember]
- public string url;
-
- [DataMember]
- public bool isGeolocationEnabled;
- }
-
- public class InAppBrowser : BaseCommand
- {
-
- private static WebBrowser browser;
- private static ApplicationBarIconButton backButton;
- private static ApplicationBarIconButton fwdButton;
-
- protected ApplicationBar AppBar;
-
- protected bool ShowLocation {get;set;}
- protected bool StartHidden {get;set;}
-
- protected string NavigationCallbackId { get; set; }
-
- public void open(string options)
- {
- // reset defaults on ShowLocation + StartHidden features
- ShowLocation = true;
- StartHidden = false;
-
- string[] args = JSON.JsonHelper.Deserialize<string[]>(options);
- //BrowserOptions opts = JSON.JsonHelper.Deserialize<BrowserOptions>(options);
- string urlLoc = args[0];
- string target = args[1];
- string featString = args[2];
- this.NavigationCallbackId = args[3];
-
- if (!string.IsNullOrEmpty(featString))
- {
- string[] features = featString.Split(',');
- foreach (string str in features)
- {
- try
- {
- string[] split = str.Split('=');
- switch (split[0])
- {
- case "location":
- ShowLocation = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase);
- break;
- case "hidden":
- StartHidden = split[1].StartsWith("yes", StringComparison.OrdinalIgnoreCase);
- break;
- }
- }
- catch (Exception)
- {
- // some sort of invalid param was passed, moving on ...
- }
- }
- }
- /*
- _self - opens in the Cordova WebView if url is in the white-list, else it opens in the InAppBrowser
- _blank - always open in the InAppBrowser
- _system - always open in the system web browser
- */
- switch (target)
- {
- case "_blank":
- ShowInAppBrowser(urlLoc);
- break;
- case "_self":
- ShowCordovaBrowser(urlLoc);
- break;
- case "_system":
- ShowSystemBrowser(urlLoc);
- 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 cordova-plugin-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 cordova-plugin-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 cordova-plugin-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)
- {
- Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- CordovaView cView = page.FindName("CordovaView") as CordovaView;
- if (cView != null)
- {
- WebBrowser br = cView.Browser;
- br.Navigate2(loc);
- }
- }
-
- }
- });
- }
-
-#if WP8
- private async void ShowSystemBrowser(string url)
- {
- var pathUri = new Uri(url, UriKind.Absolute);
- if (pathUri.Scheme == Uri.UriSchemeHttp || pathUri.Scheme == Uri.UriSchemeHttps)
- {
- await Launcher.LaunchUriAsync(pathUri);
- return;
- }
-
- var file = await GetFile(pathUri.AbsolutePath.Replace('/', Path.DirectorySeparatorChar));
- if (file != null)
- {
- await Launcher.LaunchFileAsync(file);
- }
- else
- {
- Debug.WriteLine("File not found.");
- }
- }
-
- private async Task<StorageFile> GetFile(string fileName)
- {
- //first try to get the file from the isolated storage
- var localFolder = ApplicationData.Current.LocalFolder;
- if (IOFile.Exists(Path.Combine(localFolder.Path, fileName)))
- {
- return await localFolder.GetFileAsync(fileName);
- }
-
- //if file is not found try to get it from the xap
- var filePath = Path.Combine(Package.Current.InstalledLocation.Path, fileName);
- if (IOFile.Exists(filePath))
- {
- return await StorageFile.GetFileFromPathAsync(filePath);
- }
-
- return null;
- }
-#else
- private void ShowSystemBrowser(string url)
- {
- WebBrowserTask webBrowserTask = new WebBrowserTask();
- webBrowserTask.Uri = new Uri(url, UriKind.Absolute);
- webBrowserTask.Show();
- }
-#endif
-
- private void ShowInAppBrowser(string url)
- {
- Uri loc = new Uri(url, UriKind.RelativeOrAbsolute);
-
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- if (browser != null)
- {
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- browser.Navigate2(loc);
- }
- else
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
- string baseImageUrl = "Images/";
-
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- browser = new WebBrowser();
- browser.IsScriptEnabled = true;
- browser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(browser_LoadCompleted);
-
- browser.Navigating += new EventHandler<NavigatingEventArgs>(browser_Navigating);
- browser.NavigationFailed += new System.Windows.Navigation.NavigationFailedEventHandler(browser_NavigationFailed);
- browser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(browser_Navigated);
- browser.Navigate2(loc);
-
- if (StartHidden)
- {
- browser.Visibility = Visibility.Collapsed;
- }
-
- //browser.IsGeolocationEnabled = opts.isGeolocationEnabled;
- grid.Children.Add(browser);
- }
-
- ApplicationBar bar = new ApplicationBar();
- bar.BackgroundColor = Colors.Gray;
- bar.IsMenuEnabled = false;
-
- backButton = new ApplicationBarIconButton();
- backButton.Text = "Back";
-
- backButton.IconUri = new Uri(baseImageUrl + "appbar.back.rest.png", UriKind.Relative);
- backButton.Click += new EventHandler(backButton_Click);
- bar.Buttons.Add(backButton);
-
-
- fwdButton = new ApplicationBarIconButton();
- fwdButton.Text = "Forward";
- fwdButton.IconUri = new Uri(baseImageUrl + "appbar.next.rest.png", UriKind.Relative);
- fwdButton.Click += new EventHandler(fwdButton_Click);
- bar.Buttons.Add(fwdButton);
-
- ApplicationBarIconButton closeBtn = new ApplicationBarIconButton();
- closeBtn.Text = "Close";
- closeBtn.IconUri = new Uri(baseImageUrl + "appbar.close.rest.png", UriKind.Relative);
- closeBtn.Click += new EventHandler(closeBtn_Click);
- bar.Buttons.Add(closeBtn);
-
- page.ApplicationBar = bar;
- bar.IsVisible = !StartHidden;
- AppBar = bar;
-
- page.BackKeyPress += page_BackKeyPress;
-
- }
-
- }
- }
- });
- }
-
- void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
- {
-#if WP8
- if (browser.CanGoBack)
- {
- browser.GoBack();
- }
- else
- {
- close();
- }
- e.Cancel = true;
-#else
- browser.InvokeScript("execScript", "history.back();");
-#endif
- }
-
- void browser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
-
- }
-
- void fwdButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
-#if WP8
- browser.GoForward();
-#else
- browser.InvokeScript("execScript", "history.forward();");
-#endif
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void backButton_Click(object sender, EventArgs e)
- {
- if (browser != null)
- {
- try
- {
-#if WP8
- browser.GoBack();
-#else
- browser.InvokeScript("execScript", "history.back();");
-#endif
- }
- catch (Exception)
- {
-
- }
- }
- }
-
- void closeBtn_Click(object sender, EventArgs e)
- {
- this.close();
- }
-
-
- public void close(string options = "")
- {
- if (browser != null)
- {
- Deployment.Current.Dispatcher.BeginInvoke(() =>
- {
- PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
- if (frame != null)
- {
- PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
- if (page != null)
- {
- Grid grid = page.FindName("LayoutRoot") as Grid;
- if (grid != null)
- {
- grid.Children.Remove(browser);
- }
- page.ApplicationBar = null;
- page.BackKeyPress -= page_BackKeyPress;
- }
- }
-
- browser = null;
- string message = "{\"type\":\"exit\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = false;
- this.DispatchCommandResult(result, NavigationCallbackId);
- });
- }
- }
-
- void browser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
- {
-#if WP8
- if (browser != null)
- {
- backButton.IsEnabled = browser.CanGoBack;
- fwdButton.IsEnabled = browser.CanGoForward;
-
- }
-#endif
- string message = "{\"type\":\"loadstop\", \"url\":\"" + e.Uri.OriginalString + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result, NavigationCallbackId);
- }
-
- void browser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
- {
- string message = "{\"type\":\"error\",\"url\":\"" + e.Uri.OriginalString + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.ERROR, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result, NavigationCallbackId);
- }
-
- void browser_Navigating(object sender, NavigatingEventArgs e)
- {
- string message = "{\"type\":\"loadstart\",\"url\":\"" + e.Uri.OriginalString + "\"}";
- PluginResult result = new PluginResult(PluginResult.Status.OK, message);
- result.KeepCallback = true;
- this.DispatchCommandResult(result, NavigationCallbackId);
- }
-
- }
-
- internal static class WebBrowserExtensions
- {
- /// <summary>
- /// Improved method to initiate request to the provided URI. Supports 'data:text/html' urls.
- /// </summary>
- /// <param name="browser">The browser instance</param>
- /// <param name="uri">The requested uri</param>
- internal static void Navigate2(this WebBrowser browser, Uri uri)
- {
- // IE10 does not support data uri so we use NavigateToString method instead
- if (uri.Scheme == "data")
- {
- // we should remove the scheme identifier and unescape the uri
- string uriString = Uri.UnescapeDataString(uri.AbsoluteUri);
- // format is 'data:text/html, ...'
- string html = new System.Text.RegularExpressions.Regex("^data:text/html,").Replace(uriString, "");
- browser.NavigateToString(html);
- }
- else
- {
- browser.Navigate(uri);
- }
- }
- }
-}