diff options
Diffstat (limited to 'plugins/cordova-plugin-inappbrowser/src')
29 files changed, 0 insertions, 4780 deletions
diff --git a/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java b/plugins/cordova-plugin-inappbrowser/src/amazon/InAppBrowser.java deleted file mode 100644 index 0263ea2c..00000000 --- a/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/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java b/plugins/cordova-plugin-inappbrowser/src/amazon/InAppChromeClient.java deleted file mode 100644 index 37cf101f..00000000 --- a/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/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java b/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java deleted file mode 100644 index 217e48e1..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowser.java +++ /dev/null @@ -1,879 +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.Intent; -import android.provider.Browser; -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 android.webkit.CookieManager; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebViewClient; -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.PluginManager; -import org.apache.cordova.PluginResult; -import org.json.JSONException; -import org.json.JSONObject; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -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 ZOOM = "zoom"; - private static final String HIDDEN = "hidden"; - private static final String LOAD_START_EVENT = "loadstart"; - private static final String LOAD_STOP_EVENT = "loadstop"; - private static final String LOAD_ERROR_EVENT = "loaderror"; - private static final String CLEAR_ALL_CACHE = "clearcache"; - private static final String CLEAR_SESSION_CACHE = "clearsessioncache"; - private static final String HARDWARE_BACK_BUTTON = "hardwareback"; - - private InAppBrowserDialog dialog; - private WebView 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; - private boolean hadwareBackButton=true; - - /** - * 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"); - /* This code exists for compatibility between 3.x and 4.x versions of Cordova. - * Previously the Config class had a static method, isUrlWhitelisted(). That - * responsibility has been moved to the plugins, with an aggregating method in - * PluginManager. - */ - Boolean shouldAllowNavigation = null; - if (url.startsWith("javascript:")) { - shouldAllowNavigation = true; - } - if (shouldAllowNavigation == null) { - try { - Method iuw = Config.class.getMethod("isUrlWhiteListed", String.class); - shouldAllowNavigation = (Boolean)iuw.invoke(null, url); - } catch (NoSuchMethodException e) { - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { - } - } - if (shouldAllowNavigation == null) { - try { - Method gpm = webView.getClass().getMethod("getPluginManager"); - PluginManager pm = (PluginManager)gpm.invoke(webView); - Method san = pm.getClass().getMethod("shouldAllowNavigation", String.class); - shouldAllowNavigation = (Boolean)san.invoke(pm, url); - } catch (NoSuchMethodException e) { - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { - } - } - // load in webview - if (Boolean.TRUE.equals(shouldAllowNavigation)) { - Log.d(LOG_TAG, "loading in webview"); - webView.loadUrl(url); - } - //Load the dialer - else if (url.startsWith(WebView.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 WebView. - * - * 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) { - 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); - } - intent.putExtra(Browser.EXTRA_APPLICATION_ID, cordova.getActivity().getPackageName()); - 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 WebView 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 WebViewClient() { - // NB: wait for about:blank before dismissing - public void onPageFinished(WebView view, String url) { - if (dialog != null) { - dialog.dismiss(); - } - } - }); - // NB: From SDK 19: "If you call methods on WebView from any thread - // 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. - */ - public void goBack() { - if (this.inAppWebView.canGoBack()) { - this.inAppWebView.goBack(); - } - } - - /** - * Can the web browser go back? - * @return boolean - */ - public boolean canGoBack() { - return this.inAppWebView.canGoBack(); - } - - /** - * Has the user set the hardware back button to go back - * @return boolean - */ - public boolean hardwareBack() { - return hadwareBackButton; - } - - /** - * Checks to see if it is possible to go forward one page in history, then does so. - */ - private void goForward() { - if (this.inAppWebView.canGoForward()) { - this.inAppWebView.goForward(); - } - } - - /** - * Navigate to the new page - * - * @param url to load - */ - private void navigate(String url) { - InputMethodManager imm = (InputMethodManager)this.cordova.getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0); - - if (!url.startsWith("http") && !url.startsWith("file:")) { - this.inAppWebView.loadUrl("http://" + url); - } else { - this.inAppWebView.loadUrl(url); - } - 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 hardwareBack = features.get(HARDWARE_BACK_BUTTON); - if (hardwareBack != null) { - hadwareBackButton = hardwareBack.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 WebView(cordova.getActivity()); - inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView)); - WebViewClient client = new InAppBrowserClient(thatWebView, edittext); - inAppWebView.setWebViewClient(client); - WebSettings settings = inAppWebView.getSettings(); - settings.setJavaScriptEnabled(true); - settings.setJavaScriptCanOpenWindowsAutomatically(true); - settings.setBuiltInZoomControls(getShowZoomControls()); - settings.setPluginState(android.webkit.WebSettings.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) { - CookieManager.getInstance().removeAllCookie(); - } else if (clearSessionCache) { - CookieManager.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 WebViewClient { - 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(WebView 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(WebView.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(WebView.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(WebView 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(WebView 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/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowserDialog.java b/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowserDialog.java deleted file mode 100644 index d7017202..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/InAppBrowserDialog.java +++ /dev/null @@ -1,58 +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.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; - -/** - * Created by Oliver on 22/11/2013. - */ -public class InAppBrowserDialog extends Dialog { - Context context; - InAppBrowser inAppBrowser = null; - - public InAppBrowserDialog(Context context, int theme) { - super(context, theme); - this.context = context; - } - - public void setInAppBroswer(InAppBrowser browser) { - this.inAppBrowser = browser; - } - - public void onBackPressed () { - if (this.inAppBrowser == null) { - this.dismiss(); - } else { - // better to go through the in inAppBrowser - // because it does a clean up - if (this.inAppBrowser.hardwareBack() && this.inAppBrowser.canGoBack()) { - this.inAppBrowser.goBack(); - } else { - this.inAppBrowser.closeDialog(); - } - } - } -} diff --git a/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java b/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java deleted file mode 100644 index a2145e6a..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/InAppChromeClient.java +++ /dev/null @@ -1,133 +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 android.webkit.JsPromptResult; -import android.webkit.WebChromeClient; -import android.webkit.WebStorage; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.webkit.GeolocationPermissions.Callback; - -public class InAppChromeClient extends WebChromeClient { - - 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, WebStorage.QuotaUpdater quotaUpdater) - { - LOG.d(LOG_TAG, "onExceededDatabaseQuota estimatedSize: %d currentQuota: %d totalUsedQuota: %d", estimatedSize, currentQuota, totalUsedQuota); - quotaUpdater.updateQuota(MAX_QUOTA); - } - - /** - * 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(WebView view, String url, String message, String defaultValue, JsPromptResult 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/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index fa469d88..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index e861ecce..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index f889617e..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-hdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index 47365a30..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index 4ad2df42..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index e84853e4..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-mdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index 5f304742..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index ed8ac91d..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index 4cd0458b..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xhdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png Binary files differdeleted file mode 100644 index 51479d8d..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_next_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png Binary files differdeleted file mode 100644 index bc8ff124..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_previous_item.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png b/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png Binary files differdeleted file mode 100644 index 331c545b..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/android/res/drawable-xxhdpi/ic_action_remove.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md b/plugins/cordova-plugin-inappbrowser/src/blackberry10/README.md deleted file mode 100644 index f0fa8607..00000000 --- a/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/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js b/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js deleted file mode 100644 index 33fbe476..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/browser/InAppBrowserProxy.js +++ /dev/null @@ -1,221 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * -*/ - -var cordova = require('cordova'), - channel = require('cordova/channel'), - urlutil = require('cordova/urlutil'); - -var browserWrap, - popup, - navigationButtonsDiv, - navigationButtonsDivInner, - backButton, - forwardButton, - closeButton; - -function attachNavigationEvents(element, callback) { - var onError = function () { - callback({ type: "loaderror", url: this.contentWindow.location}, {keepCallback: true}); - }; - - element.addEventListener("pageshow", 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("error", onError); - element.addEventListener("abort", onError); -} - -var IAB = { - close: function (win, lose) { - if (browserWrap) { - if (win) win({ type: "exit" }); - - browserWrap.parentNode.removeChild(browserWrap); - browserWrap = null; - popup = null; - } - }, - - show: function (win, lose) { - if (browserWrap) { - browserWrap.style.display = "block"; - } - }, - - open: function (win, lose, args) { - var strUrl = args[0], - target = args[1], - features = args[2], - url; - - if (target === "_system" || target === "_self" || !target) { - window.location = strUrl; - } else { - // "_blank" or anything else - if (!browserWrap) { - browserWrap = document.createElement("div"); - browserWrap.style.position = "absolute"; - browserWrap.style.borderWidth = "40px"; - browserWrap.style.width = "calc(100% - 80px)"; - browserWrap.style.height = "calc(100% - 80px)"; - browserWrap.style.borderStyle = "solid"; - browserWrap.style.borderColor = "rgba(0,0,0,0.25)"; - - browserWrap.onclick = function () { - setTimeout(function () { - IAB.close(win); - }, 0); - }; - - document.body.appendChild(browserWrap); - } - - if (features.indexOf("hidden=yes") !== -1) { - browserWrap.style.display = "none"; - } - - 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)"; - - 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.onclick = function (e) { - e.cancelBubble = true; - }; - - - 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(); - }); - - 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(); - }); - - 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) { - setTimeout(function () { - IAB.close(win); - }, 0); - }); - - // iframe navigation is not yet supported - backButton.disabled = true; - forwardButton.disabled = true; - - navigationButtonsDivInner.appendChild(backButton); - navigationButtonsDivInner.appendChild(forwardButton); - navigationButtonsDivInner.appendChild(closeButton); - navigationButtonsDiv.appendChild(navigationButtonsDivInner); - - browserWrap.appendChild(navigationButtonsDiv); - } else { - popup.style.height = "100%"; - } - - // start listening for navigation events - attachNavigationEvents(popup, win); - - popup.src = strUrl; - } - }, - - injectScriptCode: function (win, fail, args) { - var code = args[0], - hasCallback = args[1]; - - if (browserWrap && popup) { - try { - popup.contentWindow.eval(code); - hasCallback && win([]); - } catch(e) { - console.error('Error occured while trying to injectScriptCode: ' + JSON.stringify(e)); - } - } - }, - - injectScriptFile: function (win, fail, args) { - var msg = 'Browser cordova-plugin-inappbrowser injectScriptFile is not yet implemented'; - console.warn(msg); - fail && fail(msg); - }, - - injectStyleCode: function (win, fail, args) { - var msg = 'Browser cordova-plugin-inappbrowser injectStyleCode is not yet implemented'; - console.warn(msg); - fail && fail(msg); - }, - - injectStyleFile: function (win, fail, args) { - var msg = 'Browser cordova-plugin-inappbrowser injectStyleFile is not yet implemented'; - console.warn(msg); - fail && fail(msg); - } -}; - -module.exports = IAB; - -require("cordova/exec/proxy").add("InAppBrowser", module.exports); diff --git a/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js b/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js deleted file mode 100644 index f0d44c12..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/firefoxos/InAppBrowserProxy.js +++ /dev/null @@ -1,191 +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 cordova = require('cordova'), - channel = require('cordova/channel'), - 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 = {}, - url, - elem; - - 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'); - - function checkForwardBackward() { - 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/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h b/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h deleted file mode 100644 index 1ccc7b14..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.h +++ /dev/null @@ -1,113 +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 { - BOOL _injectedIframeBridge; -} - -@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/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m b/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m deleted file mode 100644 index 24f56c49..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ios/CDVInAppBrowser.m +++ /dev/null @@ -1,1022 +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 "CDVInAppBrowser.h" -#import <Cordova/CDVPluginResult.h> -#import <Cordova/CDVUserAgentUtil.h> - -#define kInAppBrowserTargetSelf @"_self" -#define kInAppBrowserTargetSystem @"_system" -#define kInAppBrowserTargetBlank @"_blank" - -#define kInAppBrowserToolbarBarPositionBottom @"bottom" -#define kInAppBrowserToolbarBarPositionTop @"top" - -#define TOOLBAR_HEIGHT 44.0 -#define LOCATIONBAR_HEIGHT 21.0 -#define FOOTER_HEIGHT ((TOOLBAR_HEIGHT) + (LOCATIONBAR_HEIGHT)) - -#pragma mark CDVInAppBrowser - -@interface CDVInAppBrowser () { - NSInteger _previousStatusBarStyle; -} -@end - -@implementation CDVInAppBrowser - -- (void)pluginInitialize -{ - _previousStatusBarStyle = -1; - _callbackIdPattern = nil; -} - -- (void)onReset -{ - [self close:nil]; -} - -- (void)close:(CDVInvokedUrlCommand*)command -{ - if (self.inAppBrowserViewController == nil) { - 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; -} - -- (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]) { - [self openInSystem:absoluteUrl]; - } 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]; -} - -- (void)openInInAppBrowser:(NSURL*)url withOptions:(NSString*)options -{ - CDVInAppBrowserOptions* browserOptions = [CDVInAppBrowserOptions parseOptions:options]; - - if (browserOptions.clearcache) { - NSHTTPCookie *cookie; - NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - for (cookie in [storage cookies]) - { - if (![cookie.domain isEqual: @".^filecookies^"]) { - [storage deleteCookie:cookie]; - } - } - } - - if (browserOptions.clearsessioncache) { - NSHTTPCookie *cookie; - NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - for (cookie in [storage cookies]) - { - if (![cookie.domain isEqual: @".^filecookies^"] && cookie.isSessionOnly) { - [storage deleteCookie:cookie]; - } - } - } - - if (self.inAppBrowserViewController == nil) { - NSString* originalUA = [CDVUserAgentUtil originalUserAgent]; - self.inAppBrowserViewController = [[CDVInAppBrowserViewController alloc] initWithUserAgent:originalUA prevUserAgent:[self.commandDelegate userAgent] browserOptions: browserOptions]; - 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]; - } - // Set Presentation Style - UIModalPresentationStyle presentationStyle = UIModalPresentationFullScreen; // default - if (browserOptions.presentationstyle != nil) { - if ([[browserOptions.presentationstyle lowercaseString] isEqualToString:@"pagesheet"]) { - presentationStyle = UIModalPresentationPageSheet; - } else if ([[browserOptions.presentationstyle lowercaseString] isEqualToString:@"formsheet"]) { - presentationStyle = UIModalPresentationFormSheet; - } - } - self.inAppBrowserViewController.modalPresentationStyle = presentationStyle; - - // Set Transition Style - UIModalTransitionStyle transitionStyle = UIModalTransitionStyleCoverVertical; // default - if (browserOptions.transitionstyle != nil) { - if ([[browserOptions.transitionstyle lowercaseString] isEqualToString:@"fliphorizontal"]) { - transitionStyle = UIModalTransitionStyleFlipHorizontal; - } else if ([[browserOptions.transitionstyle lowercaseString] isEqualToString:@"crossdissolve"]) { - transitionStyle = UIModalTransitionStyleCrossDissolve; - } - } - self.inAppBrowserViewController.modalTransitionStyle = transitionStyle; - - // prevent webView from bouncing - if (browserOptions.disallowoverscroll) { - if ([self.inAppBrowserViewController.webView respondsToSelector:@selector(scrollView)]) { - ((UIScrollView*)[self.inAppBrowserViewController.webView scrollView]).bounces = NO; - } else { - for (id subview in self.inAppBrowserViewController.webView.subviews) { - if ([[subview class] isSubclassOfClass:[UIScrollView class]]) { - ((UIScrollView*)subview).bounces = NO; - } - } - } - } - - // UIWebView options - 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; - } - - [self.inAppBrowserViewController navigateTo:url]; - if (!browserOptions.hidden) { - [self show:nil]; - } -} - -- (void)show:(CDVInvokedUrlCommand*)command -{ - if (self.inAppBrowserViewController == nil) { - NSLog(@"Tried to show IAB after it was closed."); - return; - } - if (_previousStatusBarStyle != -1) { - NSLog(@"Tried to show IAB while already shown"); - return; - } - - _previousStatusBarStyle = [UIApplication sharedApplication].statusBarStyle; - - CDVInAppBrowserNavigationController* nav = [[CDVInAppBrowserNavigationController alloc] - initWithRootViewController:self.inAppBrowserViewController]; - nav.orientationDelegate = self.inAppBrowserViewController; - nav.navigationBarHidden = YES; - // Run later to avoid the "took a long time" log message. - dispatch_async(dispatch_get_main_queue(), ^{ - if (self.inAppBrowserViewController != nil) { - [self.viewController presentViewController:nav animated:YES completion:nil]; - } - }); -} - -- (void)openInCordovaWebView:(NSURL*)url withOptions:(NSString*)options -{ - if ([self.commandDelegate URLIsWhitelisted:url]) { - NSURLRequest* request = [NSURLRequest requestWithURL:url]; -#ifdef __CORDOVA_4_0_0 - [self.webViewEngine loadRequest:request]; -#else - [self.webView loadRequest:request]; -#endif - } else { // this assumes the InAppBrowser can be excepted from the white-list - [self openInInAppBrowser:url withOptions:options]; - } -} - -- (void)openInSystem:(NSURL*)url -{ - if ([[UIApplication sharedApplication] canOpenURL:url]) { - [[UIApplication sharedApplication] openURL:url]; - } else { // handle any custom schemes to plugins - [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPluginHandleOpenURLNotification object:url]]; - } -} - -// 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 -// '%@' marker). -// -// If no wrapper is supplied, then the source string is executed directly. - -- (void)injectDeferredObject:(NSString*)source withWrapper:(NSString*)jsWrapper -{ - if (!_injectedIframeBridge) { - _injectedIframeBridge = YES; - // Create an iframe bridge in the new document to communicate with the CDVInAppBrowserViewController - [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:@"(function(d){var e = _cdvIframeBridge = d.createElement('iframe');e.style.display='none';d.body.appendChild(e);})(document)"]; - } - - 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]; - } - } else { - [self.inAppBrowserViewController.webView stringByEvaluatingJavaScriptFromString:source]; - } -} - -- (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]; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (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]; - } else { - jsWrapper = @"(function(d) { var c = d.createElement('script'); c.src = %@; d.body.appendChild(c); })(document)"; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (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]; - } else { - jsWrapper = @"(function(d) { var c = d.createElement('style'); c.innerHTML = %@; d.body.appendChild(c); })(document)"; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (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]; - } else { - jsWrapper = @"(function(d) { var c = d.createElement('link'); c.rel='stylesheet', c.type='text/css'; c.href = %@; d.body.appendChild(c); })(document)"; - } - [self injectDeferredObject:[command argumentAtIndex:0] withWrapper:jsWrapper]; -} - -- (BOOL)isValidCallbackId:(NSString *)callbackId -{ - NSError *err = nil; - // Initialize on first use - if (self.callbackIdPattern == nil) { - self.callbackIdPattern = [NSRegularExpression regularExpressionWithPattern:@"^InAppBrowser[0-9]{1,10}$" options:0 error:&err]; - if (err != nil) { - // Couldn't initialize Regex; No is safer than Yes. - return NO; - } - } - if ([self.callbackIdPattern firstMatchInString:callbackId options:0 range:NSMakeRange(0, [callbackId length])]) { - return YES; - } - return NO; -} - -/** - * The iframe bridge provided for the InAppBrowser is capable of executing any oustanding callback belonging - * 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; - - // 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; - } - } 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; -} - -- (void)webViewDidStartLoad:(UIWebView*)theWebView -{ - _injectedIframeBridge = NO; -} - -- (void)webViewDidFinishLoad:(UIWebView*)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]; - 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 -{ - if (self.callbackId != nil) { - NSString* url = [self.inAppBrowserViewController.currentURL absoluteString]; - 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]; - } -} - -- (void)browserExit -{ - if (self.callbackId != nil) { - CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK - messageAsDictionary:@{@"type":@"exit"}]; - [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId]; - self.callbackId = nil; - } - // Set navigationDelegate to nil to ensure no callbacks are received from it. - self.inAppBrowserViewController.navigationDelegate = nil; - // Don't recycle the ViewController since it may be consuming a lot of memory. - // Also - this is required for the PDF/User-Agent bug work-around. - self.inAppBrowserViewController = nil; - - if (IsAtLeastiOSVersion(@"7.0")) { - [[UIApplication sharedApplication] setStatusBarStyle:_previousStatusBarStyle]; - } - - _previousStatusBarStyle = -1; // this value was reset before reapplying it. caused statusbar to stay black on ios7 -} - -@end - -#pragma mark CDVInAppBrowserViewController - -@implementation CDVInAppBrowserViewController - -@synthesize currentURL; - -- (id)initWithUserAgent:(NSString*)userAgent prevUserAgent:(NSString*)prevUserAgent browserOptions: (CDVInAppBrowserOptions*) browserOptions -{ - 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 - - [self createViews]; - } - - return self; -} - -- (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); - - [self.view addSubview:self.webView]; - [self.view sendSubviewToBack:self.webView]; - - self.webView.delegate = _webViewDelegate; - self.webView.backgroundColor = [UIColor whiteColor]; - - 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.spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; - self.spinner.alpha = 1.000; - self.spinner.autoresizesSubviews = YES; - self.spinner.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin; - self.spinner.clearsContextBeforeDrawing = NO; - self.spinner.clipsToBounds = NO; - self.spinner.contentMode = UIViewContentModeScaleToFill; - self.spinner.frame = CGRectMake(454.0, 231.0, 20.0, 20.0); - self.spinner.hidden = YES; - self.spinner.hidesWhenStopped = YES; - self.spinner.multipleTouchEnabled = NO; - 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; - self.toolbar.autoresizingMask = toolbarIsAtBottom ? (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin) : UIViewAutoresizingFlexibleWidth; - self.toolbar.barStyle = UIBarStyleBlackOpaque; - self.toolbar.clearsContextBeforeDrawing = NO; - self.toolbar.clipsToBounds = NO; - self.toolbar.contentMode = UIViewContentModeScaleToFill; - self.toolbar.hidden = NO; - self.toolbar.multipleTouchEnabled = NO; - self.toolbar.opaque = NO; - self.toolbar.userInteractionEnabled = YES; - - 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; - self.addressLabel.autoresizesSubviews = YES; - self.addressLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin; - self.addressLabel.backgroundColor = [UIColor clearColor]; - self.addressLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; - self.addressLabel.clearsContextBeforeDrawing = YES; - self.addressLabel.clipsToBounds = YES; - self.addressLabel.contentMode = UIViewContentModeScaleToFill; - 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; - self.addressLabel.shadowOffset = CGSizeMake(0.0, -1.0); - self.addressLabel.text = NSLocalizedString(@"Loading...", nil); - 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; - - 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; - - [self.toolbar setItems:@[self.closeButton, flexibleSpaceButton, self.backButton, fixedSpaceButton, self.forwardButton]]; - - self.view.backgroundColor = [UIColor grayColor]; - [self.view addSubview:self.toolbar]; - [self.view addSubview:self.addressLabel]; - [self.view addSubview:self.spinner]; -} - -- (void) setWebViewFrame : (CGRect) frame { - NSLog(@"Setting the WebView's frame to %@", NSStringFromCGRect(frame)); - [self.webView setFrame:frame]; -} - -- (void)setCloseButtonTitle:(NSString*)title -{ - // 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)]; - 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]; - - NSMutableArray* items = [self.toolbar.items mutableCopy]; - [items replaceObjectAtIndex:0 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; - [self setWebViewFrame:webViewBounds]; - } else { - // no toolBar, expand webView to screen dimensions - [self setWebViewFrame:self.view.bounds]; - } - } -} - -- (void)showToolBar:(BOOL)show : (NSString *) toolbarPosition -{ - 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 - webViewBounds.size.height -= FOOTER_HEIGHT; - locationbarFrame.origin.y = webViewBounds.size.height; - self.addressLabel.frame = locationbarFrame; - self.toolbar.frame = toolbarFrame; - } else { - // no locationBar, so put toolBar at the bottom - CGRect webViewBounds = self.view.bounds; - webViewBounds.size.height -= TOOLBAR_HEIGHT; - self.toolbar.frame = toolbarFrame; - } - - if ([toolbarPosition isEqualToString:kInAppBrowserToolbarBarPositionTop]) { - toolbarFrame.origin.y = 0; - webViewBounds.origin.y += toolbarFrame.size.height; - [self setWebViewFrame:webViewBounds]; - } else { - toolbarFrame.origin.y = (webViewBounds.size.height + LOCATIONBAR_HEIGHT); - } - [self setWebViewFrame:webViewBounds]; - - } else { - 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; - } else { - // no locationBar, expand webView to screen dimensions - [self setWebViewFrame:self.view.bounds]; - } - } -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; -} - -- (void)viewDidUnload -{ - [self.webView loadHTMLString:nil baseURL:nil]; - [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; - [super viewDidUnload]; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return UIStatusBarStyleDefault; -} - -- (void)close -{ - [CDVUserAgentUtil releaseLock:&_userAgentLockToken]; - self.currentURL = nil; - - if ((self.navigationDelegate != nil) && [self.navigationDelegate respondsToSelector:@selector(browserExit)]) { - [self.navigationDelegate browserExit]; - } - - // Run later to avoid the "took a long time" log message. - dispatch_async(dispatch_get_main_queue(), ^{ - if ([self respondsToSelector:@selector(presentingViewController)]) { - [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil]; - } else { - [[self parentViewController] dismissViewControllerAnimated:YES completion:nil]; - } - }); -} - -- (void)navigateTo:(NSURL*)url -{ - NSURLRequest* request = [NSURLRequest requestWithURL:url]; - - if (_userAgentLockToken != 0) { - [self.webView loadRequest:request]; - } else { - [CDVUserAgentUtil acquireLock:^(NSInteger lockToken) { - _userAgentLockToken = lockToken; - [CDVUserAgentUtil setUserAgent:_userAgent lockToken:lockToken]; - [self.webView loadRequest:request]; - }]; - } -} - -- (void)goBack:(id)sender -{ - [self.webView goBack]; -} - -- (void)goForward:(id)sender -{ - [self.webView goForward]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - if (IsAtLeastiOSVersion(@"7.0")) { - [[UIApplication sharedApplication] setStatusBarStyle:[self preferredStatusBarStyle]]; - } - [self rePositionViews]; - - [super viewWillAppear:animated]; -} - -// -// On iOS 7 the status bar is part of the view's dimensions, therefore it's height has to be taken into account. -// The height of it could be hardcoded as 20 pixels, but that would assume that the upcoming releases of iOS won't -// change that value. -// -- (float) getStatusBarOffset { - CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame]; - float statusBarOffset = IsAtLeastiOSVersion(@"7.0") ? MIN(statusBarFrame.size.width, statusBarFrame.size.height) : 0.0; - return statusBarOffset; -} - -- (void) rePositionViews { - if ([_browserOptions.toolbarposition isEqualToString:kInAppBrowserToolbarBarPositionTop]) { - [self.webView setFrame:CGRectMake(self.webView.frame.origin.x, TOOLBAR_HEIGHT, self.webView.frame.size.width, self.webView.frame.size.height)]; - [self.toolbar setFrame:CGRectMake(self.toolbar.frame.origin.x, [self getStatusBarOffset], self.toolbar.frame.size.width, self.toolbar.frame.size.height)]; - } -} - -#pragma mark UIWebViewDelegate - -- (void)webViewDidStartLoad:(UIWebView*)theWebView -{ - // 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]; -} - -- (BOOL)webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType -{ - BOOL isTopLevelNavigation = [request.URL isEqual:[request mainDocumentURL]]; - - if (isTopLevelNavigation) { - self.currentURL = request.URL; - } - return [self.navigationDelegate webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType]; -} - -- (void)webViewDidFinishLoad:(UIWebView*)theWebView -{ - // update url, stop spinner, update back/forward - - self.addressLabel.text = [self.currentURL absoluteString]; - self.backButton.enabled = theWebView.canGoBack; - self.forwardButton.enabled = theWebView.canGoForward; - - [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]; -} - -- (void)webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error -{ - // log fail message, stop spinner, update back/forward - NSLog(@"webView:didFailLoadWithError - %ld: %@", (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; -} - -@end - -@implementation CDVInAppBrowserOptions - -- (id)init -{ - 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; -} - -+ (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 - -@implementation CDVInAppBrowserNavigationController : UINavigationController - -- (void) viewDidLoad { - - CGRect frame = [UIApplication sharedApplication].statusBarFrame; - - // simplified from: http://stackoverflow.com/a/25669695/219684 - - UIToolbar* bgToolbar = [[UIToolbar alloc] initWithFrame:frame]; - bgToolbar.barStyle = UIBarStyleDefault; - [self.view addSubview:bgToolbar]; - - [super viewDidLoad]; -} - - -#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; -} - - -@end - diff --git a/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml b/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser.qml deleted file mode 100644 index 781e8a6e..00000000 --- a/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/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js b/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js deleted file mode 100644 index 07661bb6..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ubuntu/InAppBrowser_escapeScript.js +++ /dev/null @@ -1,29 +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. - * -*/ - -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/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png b/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png Binary files differdeleted file mode 100644 index 56373d1f..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/ubuntu/close.png +++ /dev/null diff --git a/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp b/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.cpp deleted file mode 100644 index c5a9e64a..00000000 --- a/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/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h b/plugins/cordova-plugin-inappbrowser/src/ubuntu/inappbrowser.h deleted file mode 100644 index 1da4e033..00000000 --- a/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/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js b/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js deleted file mode 100644 index 817516e5..00000000 --- a/plugins/cordova-plugin-inappbrowser/src/windows/InAppBrowserProxy.js +++ /dev/null @@ -1,326 +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. - * -*/ - -/*jslint sloppy:true */ -/*global Windows:true, require, document, setTimeout, window, module */ - - - -var cordova = require('cordova'), - channel = require('cordova/channel'), - urlutil = require('cordova/urlutil'); - -var browserWrap, - popup, - navigationButtonsDiv, - navigationButtonsDivInner, - backButton, - forwardButton, - closeButton, - bodyOverflowStyle; - -// x-ms-webview is available starting from Windows 8.1 (platformId is 'windows') -// http://msdn.microsoft.com/en-us/library/windows/apps/dn301831.aspx -var isWebViewAvailable = cordova.platformId == 'windows'; - -function attachNavigationEvents(element, callback) { - if (isWebViewAvailable) { - element.addEventListener("MSWebViewNavigationStarting", function (e) { - callback({ type: "loadstart", url: e.uri}, {keepCallback: true} ); - }); - - element.addEventListener("MSWebViewNavigationCompleted", function (e) { - callback({ type: e.isSuccess ? "loadstop" : "loaderror", url: e.uri}, {keepCallback: true}); - }); - - 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}, {keepCallback: true}); - }); - - element.addEventListener("MSWebViewContentLoading", function (e) { - if (navigationButtonsDiv) { - backButton.disabled = !popup.canGoBack; - forwardButton.disabled = !popup.canGoForward; - } - }); - } else { - var onError = function () { - callback({ type: "loaderror", 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("error", onError); - element.addEventListener("abort", onError); - } -} - -var IAB = { - close: function (win, lose) { - if (browserWrap) { - if (win) win({ type: "exit" }); - - browserWrap.parentNode.removeChild(browserWrap); - // Reset body overflow style to initial value - document.body.style.msOverflowStyle = bodyOverflowStyle; - browserWrap = null; - popup = null; - } - }, - show: function (win, lose) { - if (browserWrap) { - browserWrap.style.display = "block"; - } - }, - open: function (win, lose, args) { - var strUrl = args[0], - target = args[1], - features = args[2], - url; - - if (target === "_system") { - url = new Windows.Foundation.Uri(strUrl); - Windows.System.Launcher.launchUriAsync(url); - } 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"); - - document.head.appendChild(browserWrapStyle); - - browserWrap = document.createElement("div"); - browserWrap.className = "inAppBrowserWrap"; - - if (features.indexOf("fullscreen=yes") > -1) { - browserWrap.classList.add("inAppBrowserWrapFullscreen"); - } - - // Save body overflow style to be able to reset it back later - bodyOverflowStyle = document.body.style.msOverflowStyle; - - browserWrap.onclick = function () { - setTimeout(function () { - IAB.close(win); - }, 0); - }; - - document.body.appendChild(browserWrap); - // Hide scrollbars for the whole body while inappbrowser's window is open - document.body.style.msOverflowStyle = "none"; - } - - if (features.indexOf("hidden=yes") !== -1) { - browserWrap.style.display = "none"; - } - - popup = document.createElement(isWebViewAvailable ? "x-ms-webview" : "iframe"); - if (popup instanceof HTMLIFrameElement) { - // 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.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)"; - - 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.onclick = function (e) { - e.cancelBubble = true; - }; - - - backButton = document.createElement("button"); - backButton.style.width = "40px"; - backButton.style.height = "40px"; - backButton.style.borderRadius = "40px"; - - backButton.innerText = "<-"; - 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.innerText = "->"; - 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.innerText = "x"; - closeButton.addEventListener("click", function (e) { - setTimeout(function () { - IAB.close(win); - }, 0); - }); - - if (!isWebViewAvailable) { - // iframe navigation is not yet supported - backButton.disabled = true; - forwardButton.disabled = true; - } - - navigationButtonsDivInner.appendChild(backButton); - navigationButtonsDivInner.appendChild(forwardButton); - navigationButtonsDivInner.appendChild(closeButton); - navigationButtonsDiv.appendChild(navigationButtonsDivInner); - - browserWrap.appendChild(navigationButtonsDiv); - } else { - popup.style.height = "100%"; - } - - // start listening for navigation events - attachNavigationEvents(popup, win); - - if (isWebViewAvailable) { - strUrl = strUrl.replace("ms-appx://", "ms-appx-web://"); - } - popup.src = strUrl; - } - }, - - injectScriptCode: function (win, fail, args) { - var code = args[0], - hasCallback = args[1]; - - if (isWebViewAvailable && browserWrap && popup) { - var op = popup.invokeScriptAsync("eval", code); - op.oncomplete = function (e) { - var result = [e.target.result]; - hasCallback && win(result); - }; - op.onerror = function () { }; - op.start(); - } - }, - - injectScriptFile: function (win, fail, args) { - var filePath = args[0], - hasCallback = args[1]; - - if (!!filePath) { - filePath = urlutil.makeAbsolute(filePath); - } - - if (isWebViewAvailable && browserWrap && popup) { - var uri = new Windows.Foundation.Uri(filePath); - 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 result = [e.target.result]; - hasCallback && win(result); - }; - op.onerror = function () { }; - op.start(); - }); - }); - } - }, - - injectStyleCode: function (win, fail, args) { - var code = args[0], - hasCallback = args[1]; - - if (isWebViewAvailable && browserWrap && popup) { - injectCSS(popup, code, hasCallback && win); - } - }, - - injectStyleFile: function (win, fail, args) { - var filePath = args[0], - hasCallback = args[1]; - - filePath = filePath && urlutil.makeAbsolute(filePath); - - if (isWebViewAvailable && browserWrap && popup) { - var uri = new Windows.Foundation.Uri(filePath); - Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) { - return Windows.Storage.FileIO.readTextAsync(file); - }).done(function (code) { - injectCSS(popup, code, hasCallback && win); - }, function () { - // no-op, just catch an error - }); - } - } -}; - -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)" - .replace('%s', escapedCode); - - var op = webView.invokeScriptAsync("eval", evalWrapper); - op.oncomplete = function() { - callback && callback([]); - }; - op.onerror = function () { }; - op.start(); -} - -module.exports = IAB; - -require("cordova/exec/proxy").add("InAppBrowser", module.exports); diff --git a/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs b/plugins/cordova-plugin-inappbrowser/src/wp/InAppBrowser.cs deleted file mode 100644 index ddb51227..00000000 --- a/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); - } - } - } -} |
