From 2776b14db6e949c87850d3874ad94d45208c7011 Mon Sep 17 00:00:00 2001 From: daserge Date: Tue, 16 Aug 2016 20:10:15 +0300 Subject: [PATCH] CB-10467 Hardware back button, while InAppBrowser is opened, closes the app too in addition to closing InAppBrowser --- README.md | 1 + src/windows/InAppBrowserProxy.js | 46 +++++++++++++++++++++++++++----- tests/tests.js | 23 ++++++++++++++-- 3 files changed, 62 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5df021a..e1d81b8 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ instance, or the system browser. - __hidden__: set to `yes` to create the browser and load the page, but not show it. The loadstop event fires when loading is complete. Omit or set to `no` (default) to have the browser open and load normally. - __fullscreen__: set to `yes` to create the browser control without a border around it. Please note that if __location=no__ is also specified, there will be no control presented to user to close IAB window. + - __hardwareback__: works the same way as on Android platform. ### Supported Platforms diff --git a/src/windows/InAppBrowserProxy.js b/src/windows/InAppBrowserProxy.js index b9880b3..3d65685 100644 --- a/src/windows/InAppBrowserProxy.js +++ b/src/windows/InAppBrowserProxy.js @@ -33,7 +33,8 @@ var browserWrap, forwardButton, closeButton, bodyOverflowStyle, - navigationEventsCallback; + navigationEventsCallback, + hardwareBackCallback; // x-ms-webview is available starting from Windows 8.1 (platformId is 'windows') // http://msdn.microsoft.com/en-us/library/windows/apps/dn301831.aspx @@ -105,6 +106,8 @@ var IAB = { document.body.style.msOverflowStyle = bodyOverflowStyle; browserWrap = null; popup = null; + + document.removeEventListener("backbutton", hardwareBackCallback, false); } }); }, @@ -176,6 +179,41 @@ var IAB = { browserWrap.appendChild(popup); + var closeHandler = function (e) { + setTimeout(function () { + IAB.close(navigationEventsCallback); + }, 0); + }; + + if (features.indexOf("hardwareback=yes") > -1 || features.indexOf("hardwareback") === -1) { + hardwareBackCallback = function () { + if (browserWrap.style.display === 'none') { + // NOTE: backbutton handlers have to throw an exception in order to prevent + // returning 'true' inside cordova-js, which would mean that the event is handled by user. + // Throwing an exception means that the default/system navigation behavior will take place, + // which is to exit the app if the navigation stack is empty. + throw 'Exit the app'; + } + + if (popup.canGoBack) { + popup.goBack(); + } else { + closeHandler(); + } + }; + } else if (features.indexOf("hardwareback=no") > -1) { + hardwareBackCallback = function () { + if (browserWrap.style.display === 'none') { + // See comment above + throw 'Exit the app'; + } + + closeHandler(); + }; + } + + document.addEventListener("backbutton", hardwareBackCallback, false); + if (features.indexOf("location=yes") !== -1 || features.indexOf("location") === -1) { popup.style.height = "calc(100% - 70px)"; @@ -210,11 +248,7 @@ var IAB = { 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); - }); + closeButton.addEventListener("click", closeHandler); if (!isWebViewAvailable) { // iframe navigation is not yet supported diff --git a/tests/tests.js b/tests/tests.js index 8ba8ee2..1a96029 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -438,16 +438,24 @@ exports.defineManualTests = function (contentEl, createActionButton) { '

' + 'Expected result: open successfully in InAppBrowser to the local page, scrolled to the beginning of the tall div with border.'; + var hardwareback_tests = '

HardwareBack

' + + '

' + + 'Expected result: By default hardwareback is yes so pressing back button should navigate backwards in history then close InAppBrowser' + + '

' + + 'Expected result: hardwareback=yes pressing back button should navigate backwards in history then close InAppBrowser' + + '

' + + 'Expected result: hardwareback=no pressing back button should close InAppBrowser regardless history'; + // CB-7490 We need to wrap this code due to Windows security restrictions // see http://msdn.microsoft.com/en-us/library/windows/apps/hh465380.aspx#differences for details if (window.MSApp && window.MSApp.execUnsafeLocalFunction) { MSApp.execUnsafeLocalFunction(function() { contentEl.innerHTML = info_div + local_tests + white_listed_tests + non_white_listed_tests + page_with_redirects_tests + pdf_url_tests + invalid_url_tests + - css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests; + css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests + hardwareback_tests; }); } else { contentEl.innerHTML = info_div + local_tests + white_listed_tests + non_white_listed_tests + page_with_redirects_tests + pdf_url_tests + invalid_url_tests + - css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests; + css_js_injection_tests + open_hidden_tests + clearing_cache_tests + video_tag_tests + local_with_anchor_tag_tests + hardwareback_tests; } document.getElementById("user-agent").textContent = navigator.userAgent; @@ -632,4 +640,15 @@ exports.defineManualTests = function (contentEl, createActionButton) { createActionButton('Anchor2', function () { doOpen(localhtml + '#anchor2', '_blank'); }, 'openAnchor2'); + + // Hardwareback + createActionButton('no hardwareback (defaults to yes)', function () { + doOpen('http://cordova.apache.org', '_blank'); + }, 'openHardwareBackDefault'); + createActionButton('hardwareback=yes', function () { + doOpen('http://cordova.apache.org', '_blank', 'hardwareback=yes'); + }, 'openHardwareBackYes'); + createActionButton('hardwareback=no', function () { + doOpen('http://cordova.apache.org', '_blank', 'hardwareback=no'); + }, 'openHardwareBackNo'); };