From b024104a54e50cc404d156274012b7665c42f876 Mon Sep 17 00:00:00 2001 From: sgrebnov Date: Thu, 28 Jan 2016 19:08:27 +0300 Subject: [PATCH] CB-10451 InAppBrowser: loadstart event is not triggered on Windows CB-10452 InAppBrowser: 'exit' event is not triggered on Windows CB-10454 InAppBrowser: 'loaderror' event does not have code and message on Windows CB-10450 InAppBrowser: Unable to get property 'canGoBack' of undefined on Windows github close #145 --- src/windows/InAppBrowserProxy.js | 381 ++++++++++++++++--------------- 1 file changed, 202 insertions(+), 179 deletions(-) diff --git a/src/windows/InAppBrowserProxy.js b/src/windows/InAppBrowserProxy.js index 962c05e..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 @@ var browserWrap, 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,17 +48,21 @@ function attachNavigationEvents(element, callback) { }); 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) { + if (navigationButtonsDiv && popup) { if (popup.canGoBack) { backButton.removeAttribute("disabled"); } else { @@ -92,209 +96,228 @@ function attachNavigationEvents(element, callback) { 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% - 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(win); - }, 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); + 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 + }); + } + }); } };