Merge branch 'master' of https://github.com/uareurapid/cordova-plugin-inappbrowser
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index e5fcfd6..5cb452c 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -20,6 +20,11 @@
-->
# Release Notes
+### 1.2.0 (Jan 15, 2016)
+* CB-8180: Changing methods of interception in `WebViewClient` class
+* CB-10009 Improve `InAppBrowser` toolbar look and feel on **Windows**
+* Open a new window on the **Browser** platform
+
### 1.1.1 (Dec 10, 2015)
* CB-9445 Improves executeScript callbacks on iOS
diff --git a/package.json b/package.json
index dc1c422..55ca8d7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-inappbrowser",
- "version": "1.1.2-dev",
+ "version": "1.2.1-dev",
"description": "Cordova InAppBrowser Plugin",
"cordova": {
"id": "cordova-plugin-inappbrowser",
diff --git a/plugin.xml b/plugin.xml
index 052bd13..359d660 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -20,7 +20,7 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="cordova-plugin-inappbrowser"
- version="1.1.2-dev">
+ version="1.2.1-dev">
<name>InAppBrowser</name>
<description>Cordova InAppBrowser Plugin</description>
diff --git a/src/android/InAppBrowser.java b/src/android/InAppBrowser.java
index 8487b64..6612a66 100644
--- a/src/android/InAppBrowser.java
+++ b/src/android/InAppBrowser.java
@@ -362,20 +362,22 @@
* 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() {
+ final WebView childView = inAppWebView;
+ // The JS protects against multiple calls, so this should happen only when
+ // closeDialog() is called by other native code.
+ if (childView == null) {
+ return;
+ }
+
childView.setWebViewClient(new WebViewClient() {
// NB: wait for about:blank before dismissing
public void onPageFinished(WebView view, String url) {
if (dialog != null) {
dialog.dismiss();
+ dialog = null;
}
}
});
@@ -383,16 +385,16 @@
// 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");
+ }
}
});
-
- try {
- JSONObject obj = new JSONObject();
- obj.put("type", EXIT_EVENT);
- sendUpdate(obj, false);
- } catch (JSONException ex) {
- Log.d(LOG_TAG, "Should never happen");
- }
}
/**
@@ -519,6 +521,12 @@
@SuppressLint("NewApi")
public void run() {
+
+ // CB-6702 InAppBrowser hangs when opening more than one instance
+ if (dialog != null) {
+ dialog.dismiss();
+ };
+
// 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;
@@ -544,7 +552,7 @@
actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
actionButtonContainer.setHorizontalGravity(Gravity.LEFT);
actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);
- actionButtonContainer.setId(1);
+ actionButtonContainer.setId(Integer.valueOf(1));
// Back button
Button back = new Button(cordova.getActivity());
@@ -552,7 +560,7 @@
backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);
back.setLayoutParams(backLayoutParams);
back.setContentDescription("Back Button");
- back.setId(2);
+ back.setId(Integer.valueOf(2));
Resources activityRes = cordova.getActivity().getResources();
int backResId = activityRes.getIdentifier("ic_action_previous_item", "drawable", cordova.getActivity().getPackageName());
Drawable backIcon = activityRes.getDrawable(backResId);
@@ -576,7 +584,7 @@
forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);
forward.setLayoutParams(forwardLayoutParams);
forward.setContentDescription("Forward Button");
- forward.setId(3);
+ forward.setId(Integer.valueOf(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)
@@ -599,7 +607,7 @@
textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);
textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);
edittext.setLayoutParams(textLayoutParams);
- edittext.setId(4);
+ edittext.setId(Integer.valueOf(4));
edittext.setSingleLine(true);
edittext.setText(url);
edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
@@ -622,7 +630,7 @@
closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
close.setLayoutParams(closeLayoutParams);
forward.setContentDescription("Close Button");
- close.setId(5);
+ close.setId(Integer.valueOf(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)
@@ -642,6 +650,7 @@
// WebView
inAppWebView = new WebView(cordova.getActivity());
inAppWebView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ inAppWebView.setId(Integer.valueOf(6));
inAppWebView.setWebChromeClient(new InAppChromeClient(thatWebView));
WebViewClient client = new InAppBrowserClient(thatWebView, edittext);
inAppWebView.setWebViewClient(client);
@@ -668,7 +677,7 @@
}
inAppWebView.loadUrl(url);
- inAppWebView.setId(6);
+ inAppWebView.setId(Integer.valueOf(6));
inAppWebView.getSettings().setLoadWithOverviewMode(true);
inAppWebView.getSettings().setUseWideViewPort(true);
inAppWebView.requestFocus();
@@ -756,34 +765,30 @@
}
/**
- * Notify the host application that a page has started loading.
+ * Override the URL that should be loaded
*
- * @param view The webview initiating the callback.
- * @param url The url of the page.
+ * This handles a small subset of all the URIs that would be encountered.
+ *
+ * @param webView
+ * @param url
*/
@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)) {
+ public boolean shouldOverrideUrlLoading(WebView webView, String url) {
+ if (url.startsWith(WebView.SCHEME_TEL)) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse(url));
cordova.getActivity().startActivity(intent);
+ return true;
} 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:")) {
+ } 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);
+ return true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error with " + url + ": " + e.toString());
}
@@ -798,8 +803,7 @@
int parmIndex = url.indexOf('?');
if (parmIndex == -1) {
address = url.substring(4);
- }
- else {
+ } else {
address = url.substring(4, parmIndex);
// If body, then set sms body
@@ -815,29 +819,54 @@
intent.putExtra("address", address);
intent.setType("vnd.android-dir/mms-sms");
cordova.getActivity().startActivity(intent);
+ return true;
} catch (android.content.ActivityNotFoundException e) {
LOG.e(LOG_TAG, "Error sending sms " + url + ":" + e.toString());
}
}
- else {
+ return false;
+ }
+
+
+ /*
+ * onPageStarted fires the LOAD_START_EVENT
+ *
+ * @param view
+ * @param url
+ * @param favicon
+ */
+ @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;
+ }
+ else
+ {
+ // Assume that everything is HTTP at this point, because if we don't specify,
+ // it really should be. Complain loudly about this!!!
+ LOG.e(LOG_TAG, "Possible Uncaught/Unknown URI");
newloc = "http://" + url;
}
+ // Update the UI if we haven't already
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");
+ LOG.e(LOG_TAG, "URI passed in has caused a JSON error.");
}
}
+
+
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
diff --git a/src/windows/InAppBrowserProxy.js b/src/windows/InAppBrowserProxy.js
index fc037bd..f6d1da6 100644
--- a/src/windows/InAppBrowserProxy.js
+++ b/src/windows/InAppBrowserProxy.js
@@ -25,7 +25,6 @@
var cordova = require('cordova'),
- channel = require('cordova/channel'),
urlutil = require('cordova/urlutil');
var browserWrap,
@@ -35,11 +34,12 @@
backButton,
forwardButton,
closeButton,
- bodyOverflowStyle;
+ bodyOverflowStyle,
+ navigationEventsCallback;
// 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';
+var isWebViewAvailable = cordova.platformId === 'windows';
function attachNavigationEvents(element, callback) {
if (isWebViewAvailable) {
@@ -48,19 +48,32 @@
});
element.addEventListener("MSWebViewNavigationCompleted", function (e) {
- callback({ type: e.isSuccess ? "loadstop" : "loaderror", url: e.uri}, {keepCallback: true});
+ if (e.isSuccess) {
+ callback({ type: "loadstop", url: e.uri }, { keepCallback: true });
+ } else {
+ callback({ type: "loaderror", url: e.uri, code: e.webErrorStatus, message: "Navigation failed with error code " + e.webErrorStatus}, { keepCallback: true });
+ }
});
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});
+ callback({ type: "loaderror", url: e.uri, code: e.webErrorStatus, message: "Navigation failed with error code " + e.webErrorStatus}, { keepCallback: true });
});
element.addEventListener("MSWebViewContentLoading", function (e) {
- if (navigationButtonsDiv) {
- backButton.disabled = !popup.canGoBack;
- forwardButton.disabled = !popup.canGoForward;
+ if (navigationButtonsDiv && popup) {
+ if (popup.canGoBack) {
+ backButton.removeAttribute("disabled");
+ } else {
+ backButton.setAttribute("disabled", "true");
+ }
+
+ if (popup.canGoForward) {
+ forwardButton.removeAttribute("disabled");
+ } else {
+ forwardButton.setAttribute("disabled", "true");
+ }
}
});
} else {
@@ -83,228 +96,228 @@
var IAB = {
close: function (win, lose) {
- if (browserWrap) {
- if (win) win({ type: "exit" });
+ setImmediate(function () {
+ if (browserWrap) {
+ if (navigationEventsCallback) {
+ navigationEventsCallback({ type: "exit" });
+ }
- browserWrap.parentNode.removeChild(browserWrap);
- // Reset body overflow style to initial value
- document.body.style.msOverflowStyle = bodyOverflowStyle;
- browserWrap = null;
- popup = null;
- }
+ 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";
- }
+ setImmediate(function () {
+ if (browserWrap) {
+ browserWrap.style.display = "block";
+ }
+ });
},
open: function (win, lose, args) {
- var strUrl = args[0],
- target = args[1],
- features = args[2],
- url;
+ // make function async so that we can add navigation events handlers before view is loaded and navigation occured
+ setImmediate(function () {
+ var strUrl = args[0],
+ target = args[1],
+ features = args[2],
+ url;
- 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");
+ navigationEventsCallback = win;
- 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);
+ if (target === "_system") {
+ url = new Windows.Foundation.Uri(strUrl);
+ Windows.System.Launcher.launchUriAsync(url);
+ } else if (target === "_self" || !target) {
+ window.location = strUrl;
} else {
- popup.style.height = "100%";
- }
+ // "_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");
- // start listening for navigation events
- attachNavigationEvents(popup, win);
+ document.head.appendChild(browserWrapStyle);
- if (isWebViewAvailable) {
- strUrl = strUrl.replace("ms-appx://", "ms-appx-web://");
+ 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(navigationEventsCallback);
+ }, 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% - 70px)";
+
+ navigationButtonsDiv = document.createElement("div");
+ navigationButtonsDiv.className = "inappbrowser-app-bar";
+ navigationButtonsDiv.onclick = function (e) {
+ e.cancelBubble = true;
+ };
+
+ navigationButtonsDivInner = document.createElement("div");
+ navigationButtonsDivInner.className = "inappbrowser-app-bar-inner"
+ navigationButtonsDivInner.onclick = function (e) {
+ e.cancelBubble = true;
+ };
+
+ backButton = document.createElement("div");
+ backButton.innerText = "back";
+ backButton.className = "app-bar-action action-back";
+ backButton.addEventListener("click", function (e) {
+ if (popup.canGoBack)
+ popup.goBack();
+ });
+
+ forwardButton = document.createElement("div");
+ forwardButton.innerText = "forward";
+ forwardButton.className = "app-bar-action action-forward";
+ forwardButton.addEventListener("click", function (e) {
+ if (popup.canGoForward)
+ popup.goForward();
+ });
+
+ closeButton = document.createElement("div");
+ closeButton.innerText = "close";
+ closeButton.className = "app-bar-action action-close";
+ closeButton.addEventListener("click", function (e) {
+ setTimeout(function () {
+ IAB.close(navigationEventsCallback);
+ }, 0);
+ });
+
+ if (!isWebViewAvailable) {
+ // iframe navigation is not yet supported
+ backButton.setAttribute("disabled", "true");
+ forwardButton.setAttribute("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, navigationEventsCallback);
+
+ if (isWebViewAvailable) {
+ strUrl = strUrl.replace("ms-appx://", "ms-appx-web://");
+ }
+ popup.src = strUrl;
}
- popup.src = strUrl;
- }
+ });
},
injectScriptCode: function (win, fail, args) {
- var code = args[0],
- hasCallback = args[1];
+ setImmediate(function () {
+ var code = args[0],
+ hasCallback = args[1];
- if (isWebViewAvailable && browserWrap && popup) {
- var op = popup.invokeScriptAsync("eval", code);
- op.oncomplete = function (e) {
- // return null if event target is unavailable by some reason
- var result = (e && e.target) ? [e.target.result] : [null];
- hasCallback && win(result);
- };
- op.onerror = function () { };
- op.start();
- }
+ if (isWebViewAvailable && browserWrap && popup) {
+ var op = popup.invokeScriptAsync("eval", code);
+ op.oncomplete = function (e) {
+ // return null if event target is unavailable by some reason
+ var result = (e && e.target) ? [e.target.result] : [null];
+ hasCallback && win(result);
+ };
+ op.onerror = function () { };
+ op.start();
+ }
+ });
},
injectScriptFile: function (win, fail, args) {
- var filePath = args[0],
- hasCallback = args[1];
+ setImmediate(function () {
+ var filePath = args[0],
+ hasCallback = args[1];
- if (!!filePath) {
- filePath = urlutil.makeAbsolute(filePath);
- }
+ 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();
+ 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];
+ setImmediate(function () {
+ var code = args[0],
+ hasCallback = args[1];
- if (isWebViewAvailable && browserWrap && popup) {
- injectCSS(popup, code, hasCallback && win);
- }
+ if (isWebViewAvailable && browserWrap && popup) {
+ injectCSS(popup, code, hasCallback && win);
+ }
+ });
},
injectStyleFile: function (win, fail, args) {
- var filePath = args[0],
- hasCallback = args[1];
+ setImmediate(function () {
+ var filePath = args[0],
+ hasCallback = args[1];
- filePath = filePath && urlutil.makeAbsolute(filePath);
+ 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
- });
- }
+ 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
+ });
+ }
+ });
}
};
diff --git a/tests/plugin.xml b/tests/plugin.xml
index 5f1a8b0..8562fab 100644
--- a/tests/plugin.xml
+++ b/tests/plugin.xml
@@ -20,10 +20,12 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="cordova-plugin-inappbrowser-tests"
- version="1.1.2-dev">
+ version="1.2.1-dev">
<name>Cordova InAppBrowser Plugin Tests</name>
<license>Apache 2.0</license>
+ <dependency id="cordova-plugin-dialogs" />
+
<js-module src="tests.js" name="tests">
</js-module>
diff --git a/tests/tests.js b/tests/tests.js
index a827986..67dd4b6 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -24,6 +24,110 @@
window.alert = window.alert || navigator.notification.alert;
+exports.defineAutoTests = function () {
+
+ describe('cordova.InAppBrowser', function () {
+
+ it("inappbrowser.spec.1 should exist", function () {
+ expect(cordova.InAppBrowser).toBeDefined();
+ });
+
+ it("inappbrowser.spec.2 should contain open function", function () {
+ expect(cordova.InAppBrowser.open).toBeDefined();
+ expect(cordova.InAppBrowser.open).toEqual(jasmine.any(Function));
+ });
+ });
+
+ describe('open method', function () {
+
+ var iabInstance;
+ var originalTimeout;
+ var url = 'http://apache.org/';
+ var badUrl = 'http://bad-uri/';
+
+ beforeEach(function () {
+ // increase timeout to ensure test url could be loaded within test time
+ originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000;
+
+ iabInstance = null;
+ });
+
+ afterEach(function (done) {
+ // restore original timeout
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
+
+ if (iabInstance !== null && iabInstance.close) {
+ iabInstance.close();
+ }
+ iabInstance = null;
+ // add some extra time so that iab dialog is closed
+ setTimeout(done, 2000);
+ });
+
+ function verifyEvent(evt, type) {
+ expect(evt).toBeDefined();
+ expect(evt.type).toEqual(type);
+ if (type !== 'exit') { // `exit` event does not have url field
+ expect(evt.url).toEqual(url);
+ }
+ }
+
+ function verifyLoadErrorEvent(evt) {
+ expect(evt).toBeDefined();
+ expect(evt.type).toEqual('loaderror');
+ expect(evt.url).toEqual(badUrl);
+ expect(evt.code).toEqual(jasmine.any(Number));
+ expect(evt.message).toEqual(jasmine.any(String));
+ }
+
+ it("inappbrowser.spec.3 should retun InAppBrowser instance with required methods", function () {
+ iabInstance = cordova.InAppBrowser.open(url, '_blank');
+
+ expect(iabInstance).toBeDefined();
+
+ expect(iabInstance.addEventListener).toEqual(jasmine.any(Function));
+ expect(iabInstance.removeEventListener).toEqual(jasmine.any(Function));
+ expect(iabInstance.close).toEqual(jasmine.any(Function));
+ expect(iabInstance.show).toEqual(jasmine.any(Function));
+ expect(iabInstance.executeScript).toEqual(jasmine.any(Function));
+ expect(iabInstance.insertCSS).toEqual(jasmine.any(Function));
+ });
+
+ it("inappbrowser.spec.4 should support loadstart and loadstop events", function (done) {
+ var onLoadStart = jasmine.createSpy('loadstart event callback').and.callFake(function (evt) {
+ verifyEvent(evt, 'loadstart');
+ });
+
+ iabInstance = cordova.InAppBrowser.open(url, '_blank');
+ iabInstance.addEventListener('loadstart', onLoadStart);
+ iabInstance.addEventListener('loadstop', function (evt) {
+ verifyEvent(evt, 'loadstop');
+ expect(onLoadStart).toHaveBeenCalled();
+ done();
+ });
+ });
+
+ it("inappbrowser.spec.5 should support exit event", function (done) {
+ iabInstance = cordova.InAppBrowser.open(url, '_blank');
+ iabInstance.addEventListener('exit', function (evt) {
+ verifyEvent(evt, 'exit');
+ done();
+ });
+ iabInstance.close();
+ iabInstance = null;
+ });
+
+ it("inappbrowser.spec.6 should support loaderror event", function (done) {
+ iabInstance = cordova.InAppBrowser.open(badUrl, '_blank');
+ iabInstance.addEventListener('loaderror', function (evt) {
+ verifyLoadErrorEvent(evt);
+ done();
+ });
+ });
+ });
+};
+
exports.defineManualTests = function (contentEl, createActionButton) {
function doOpen(url, target, params, numExpectedRedirects, useWindowOpen) {
diff --git a/www/inappbrowser.css b/www/inappbrowser.css
index bd1526d..5762c74 100644
--- a/www/inappbrowser.css
+++ b/www/inappbrowser.css
@@ -38,3 +38,77 @@
.inAppBrowserWrapFullscreen {
border: 0;
}
+
+.inappbrowser-app-bar {
+ height: 70px;
+ background-color: #404040;
+ z-index: 9999999;
+}
+
+.inappbrowser-app-bar-inner {
+ padding-top: 10px;
+ height: 60px;
+ width: 155px;
+ margin: 0 auto;
+ background-color: #404040;
+ z-index: 9999999;
+}
+
+.app-bar-action {
+ width: auto;
+ height: 40px;
+ margin-left: 20px;
+ font-family: "Segoe UI Symbol";
+ float: left;
+ color: white;
+ font-size: 12px;
+ text-transform: lowercase;
+ text-align: center;
+ cursor: default;
+}
+
+.app-bar-action[disabled] {
+ color: gray;
+ /*disable click*/
+ pointer-events: none;
+}
+
+.app-bar-action::before {
+ font-size: 28px;
+ display: block;
+ height: 36px;
+}
+
+/* Back */
+.action-back {
+ margin-left: 0px;
+}
+
+.action-back::before {
+ content: "\E0BA";
+}
+
+.action-back:not([disabled]):hover::before {
+ content: "\E0B3";
+}
+
+/* Forward */
+.action-forward::before {
+ content: "\E0AC";
+}
+
+.action-forward:not([disabled]):hover::before {
+ content: "\E0AF";
+}
+
+/* Close */
+.action-close::before {
+ content: "\E0C7";
+ /* close icon is larger so we re-size it to fit other icons */
+ font-size: 20px;
+ line-height: 40px;
+}
+
+.action-close:not([disabled]):hover::before {
+ content: "\E0CA";
+}
diff --git a/www/inappbrowser.js b/www/inappbrowser.js
index 93eb420..25f6271 100644
--- a/www/inappbrowser.js
+++ b/www/inappbrowser.js
@@ -19,92 +19,93 @@
*
*/
-// special patch to correctly work on Ripple emulator (CB-9760)
-if (window.parent && !!window.parent.ripple) { // https://gist.github.com/triceam/4658021
- module.exports = window.open.bind(window); // fallback to default window.open behaviour
- return;
-}
-
-var exec = require('cordova/exec');
-var channel = require('cordova/channel');
-var modulemapper = require('cordova/modulemapper');
-var urlutil = require('cordova/urlutil');
-
-function InAppBrowser() {
- this.channels = {
- 'loadstart': channel.create('loadstart'),
- 'loadstop' : channel.create('loadstop'),
- 'loaderror' : channel.create('loaderror'),
- 'exit' : channel.create('exit')
- };
-}
-
-InAppBrowser.prototype = {
- _eventHandler: function (event) {
- if (event && (event.type in this.channels)) {
- this.channels[event.type].fire(event);
- }
- },
- close: function (eventname) {
- exec(null, null, "InAppBrowser", "close", []);
- },
- show: function (eventname) {
- exec(null, null, "InAppBrowser", "show", []);
- },
- addEventListener: function (eventname,f) {
- if (eventname in this.channels) {
- this.channels[eventname].subscribe(f);
- }
- },
- removeEventListener: function(eventname, f) {
- if (eventname in this.channels) {
- this.channels[eventname].unsubscribe(f);
- }
- },
-
- executeScript: function(injectDetails, cb) {
- if (injectDetails.code) {
- exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);
- } else if (injectDetails.file) {
- exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);
- } else {
- throw new Error('executeScript requires exactly one of code or file to be specified');
- }
- },
-
- insertCSS: function(injectDetails, cb) {
- if (injectDetails.code) {
- exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);
- } else if (injectDetails.file) {
- exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);
- } else {
- throw new Error('insertCSS requires exactly one of code or file to be specified');
- }
- }
-};
-
-module.exports = function(strUrl, strWindowName, strWindowFeatures, callbacks) {
- // Don't catch calls that write to existing frames (e.g. named iframes).
- if (window.frames && window.frames[strWindowName]) {
- var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
- return origOpenFunc.apply(window, arguments);
+(function() {
+ // special patch to correctly work on Ripple emulator (CB-9760)
+ if (window.parent && !!window.parent.ripple) { // https://gist.github.com/triceam/4658021
+ module.exports = window.open.bind(window); // fallback to default window.open behaviour
+ return;
}
- strUrl = urlutil.makeAbsolute(strUrl);
- var iab = new InAppBrowser();
+ var exec = require('cordova/exec');
+ var channel = require('cordova/channel');
+ var modulemapper = require('cordova/modulemapper');
+ var urlutil = require('cordova/urlutil');
- callbacks = callbacks || {};
- for (var callbackName in callbacks) {
- iab.addEventListener(callbackName, callbacks[callbackName]);
+ function InAppBrowser() {
+ this.channels = {
+ 'loadstart': channel.create('loadstart'),
+ 'loadstop' : channel.create('loadstop'),
+ 'loaderror' : channel.create('loaderror'),
+ 'exit' : channel.create('exit')
+ };
}
- var cb = function(eventname) {
- iab._eventHandler(eventname);
+ InAppBrowser.prototype = {
+ _eventHandler: function (event) {
+ if (event && (event.type in this.channels)) {
+ this.channels[event.type].fire(event);
+ }
+ },
+ close: function (eventname) {
+ exec(null, null, "InAppBrowser", "close", []);
+ },
+ show: function (eventname) {
+ exec(null, null, "InAppBrowser", "show", []);
+ },
+ addEventListener: function (eventname,f) {
+ if (eventname in this.channels) {
+ this.channels[eventname].subscribe(f);
+ }
+ },
+ removeEventListener: function(eventname, f) {
+ if (eventname in this.channels) {
+ this.channels[eventname].unsubscribe(f);
+ }
+ },
+
+ executeScript: function(injectDetails, cb) {
+ if (injectDetails.code) {
+ exec(cb, null, "InAppBrowser", "injectScriptCode", [injectDetails.code, !!cb]);
+ } else if (injectDetails.file) {
+ exec(cb, null, "InAppBrowser", "injectScriptFile", [injectDetails.file, !!cb]);
+ } else {
+ throw new Error('executeScript requires exactly one of code or file to be specified');
+ }
+ },
+
+ insertCSS: function(injectDetails, cb) {
+ if (injectDetails.code) {
+ exec(cb, null, "InAppBrowser", "injectStyleCode", [injectDetails.code, !!cb]);
+ } else if (injectDetails.file) {
+ exec(cb, null, "InAppBrowser", "injectStyleFile", [injectDetails.file, !!cb]);
+ } else {
+ throw new Error('insertCSS requires exactly one of code or file to be specified');
+ }
+ }
};
- strWindowFeatures = strWindowFeatures || "";
+ module.exports = function(strUrl, strWindowName, strWindowFeatures, callbacks) {
+ // Don't catch calls that write to existing frames (e.g. named iframes).
+ if (window.frames && window.frames[strWindowName]) {
+ var origOpenFunc = modulemapper.getOriginalSymbol(window, 'open');
+ return origOpenFunc.apply(window, arguments);
+ }
- exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
- return iab;
-};
+ strUrl = urlutil.makeAbsolute(strUrl);
+ var iab = new InAppBrowser();
+ callbacks = callbacks || {};
+ for (var callbackName in callbacks) {
+ iab.addEventListener(callbackName, callbacks[callbackName]);
+ }
+
+ var cb = function(eventname) {
+ iab._eventHandler(eventname);
+ };
+
+ strWindowFeatures = strWindowFeatures || "";
+
+ exec(cb, cb, "InAppBrowser", "open", [strUrl, strWindowName, strWindowFeatures]);
+ return iab;
+ };
+})();