Cordova InAppBrowser executeScript() not firing callback in iOS - javascript

I have a cordova app and using InAppBrowser to login to a website. On Successful login, I need to pass the response to the App. I am using executeScript() to achieve and the same is working fine in Android, whereas in iOS, the callback for executeScript() is not getting fired.
My Load stop event listener is as follows
var ref = cordova.InAppBrowser.open("XXXX.html", "_blank", 'location=yes,toolbar=yes');
function iabLoadStop(event) {
alert("EXECUTING SCRIPT")
ref.executeScript({
code: "document.body.innerHTML"
}, function(values) {
alert("SCRIPT EXECUTED")
alert(values)
});
}
I am getting "EXECUTING SCRIPT" alert successfully on load stop event, but the executeScript() which was support to alert "SCRIPT EXECUTED" and the innerHTML is not getting fired.

As it turned out the reason was with the first alert. This function stops the programm-flow but also caused the code within XXXX.html, that is executed by executeScript, to stop.
So it should be avoided to call such functions (alert/confirm etc.) between event loadstop and executeScript, at least on iOS. There are alternatives like console.log.

Related

Beforeunload event does not fire after page refresh Chrome

I have this simple code
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<!--<script src="angular.min.js"></script>-->
<script>
window.onload = function () {
window.addEventListener("unload", function () {
debugger;
});
window.addEventListener("beforeunload", function () {
debugger;
});
window.onbeforeunload = function () {
}
}
</script>
</head>
<body ng-app="app">
</body>
</html>
I want unload or beforeunload events be fired after I refresh the page. This is not happening in Chrome VersiĆ³n 67.0.3396.62. I have tried firefox and edge and it works well. It also works when i close the tab. The error ocurrs only when i refresh the page.
You've run into an issue that was already reported. It looks like a bug, but according to a Chrome dev (kozy) it is a feature:
Thanks for repro. It is actually feature. As soon as you pressed reload we ignore all breakpoints before page reloaded. It is useful all the time when you have a lot of breakpoints and need to reload page to restart debugging session.
Workaround: instead of pressing reload button you can navigate to the same url using omnibox then all breakpoint will work as expected.
I've added bold emphasis to point out the workaround proposed by kozy. I've tried it and found that it works.
Other than the issue with the debugger statement, the handlers are executed whether you are reloading or closing the tab. In both cases that follow, I get the stock prompt that Chrome provides when returning true:
window.addEventListener("beforeunload", function (ev) {
ev.returnValue = true; // `return true` won't work here.
});
This works too:
window.onbeforeunload = function () {
return true;
}
It used to be that you could use a return value with a message and the browser would show your custom message but browsers generally no longer support this.
Whether or not you want to set the handler for beforeunload inside a handler for load is entirely dependent on your goals. For instance, I have an application for editing documents that does not set the beforeunload handler until the application has started initializing, which is much later than the load event. The beforeunload handler is there to make sure the user does not leave the page with unsaved modifications.

How to execute a content script every time a page loads?

I'm writing a Chrome extension that provides a content script to any page on GitHub (i.e. any URL matching https://github.com/*).
I'm simply trying to log something to the console each time a page on GitHub loads, like so:
window.onload = function() {
console.log("LOAD");
};
This listener function is executed the very first time a GitHub page is loaded, but if the user navigates to other pages on GitHub from there (by clicking on links or through other means), it doesn't fire. Why? :(
Steps to reproduce:
Open any repository's page on GitHub (example). You should see the message logged to the console.
Click on any link on that page. When the new page is loaded, no message is logged. :(
How do I solve this?
It seems that GitHub uses AJAX (along with history.pushState) to load some parts of the site, so onload will fire only when the page truly loads, but not when content is loaded via AJAX.
Since GitHub uses pushState to change the URL when AJAX content is done loading, you can detect when that happens, and execute your code.
There isn't actually a native event right now that fires when pushState is used, but there's this little hack:
(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({state: state});
}
return pushState.apply(history, arguments);
}
})(window.history);
So, run that, and then, instead of window.onload, you can do:
history.onpushstate = function () {
console.log("LOAD");
};
Not ALL of GitHub page's load this way (AJAX + pushState), so you'd have to use both, window.onload and history.onpushstate.
Also, you should use window.addEventListener('load', fn); instead of window.onload, since you don't know if GitHub's code could be overwriting window.onload.

Page load event outside InAppBrowser

I need to open an external page from my Phonegap app. I need to make it compatible with at least Android and iOS.
I have this code to open the external page
**var ref = window.open('http://mysite.com/', '_blank', 'location=no');**
lastPageLoaded = ref;
ref.addEventListener('loadstop', function (event) {
try {
alert('executing...');
var retVal = lastPageLoaded.executeScript(
{
code: "alert('got here!');"
}, function () {
});
}
catch (exception) {
alert(exception);
}
});
I also have this in my config.xml file:
<access origin="*" />
The code above invokes the InAppBrowser an correctly opens my external page. BUT, the InAppBrowser is not in fullscreen mode which is not good for my app.
I noticed that if I make a slight change to the bolded (that is, the text decorated with ** ) line above to this:
var ref = window.open('http://mysite.com/', **'_self'**, 'location=no');
than InAppBrowser is not invoked but the external page opens in full mode, as my entire app is, which is good!
However, adding the event listener won't work:
ref.addEventListener('loadstop', function (event)
I mean, my code never gets to execute this line:
code: "alert('got here!');"
Seems logical because now I am not running under InAppBrowser context, but I need one of two solutions:
1. Make InAppBrowser run in fullscreen mode and keep my existing event handler
2. Find a similar event to hook to so I can invoke the script on the loaded external page.
Is it possible to achieve this?

Diagnosing body.onload not being called

I have some web pages which rely on body.onload (or, equivalently, window.onload) to set them up properly. Sometimes onload is not being called.
Is there a trick with some web browser (ideally Chrome, where this apparently happens most often) which will tell me what exactly is preventing the page from loading successfully?
Clue: this rarely (maybe even never) happens when I hit F5 to reload the whole page, but more generally it happens if a page has been arrived-at by clicking a link or pasting the url into the address bar. Is there a quirk of onload semantics that might be tripping me up?
N.B. The scripts themselves are not producing any errors in the console.
I think you want window.onload
I have tested such cases, and none of the following will work:
var callback = function() { alert("Body loaded"); };
$("body").load(callback);
document.body.addEventListener("load",callback,false);
However, document.body.onload seems to work fine. Make sure that body is correctly namespaced:
document.body //<body>
body //Reference error
If you're talking about:
<body onload="callback();"></body>
Then go back and review your code, because it should work.
Personally, I suggest using the load event of the window object or a framework's ready event.
//Execute when the window is loaded
var callback = function() {
//Your code goes here...
};
if (window.addEventListener) window.addEventListener("load",callback,false);
else window.attachEvent("load",callback);
With jQuery, you only need the following:
$(window).load(callback);
jQuery's ready event is as follows:
$(document).ready(callback);
//Or just:
$(callback);
MooTools use this:
window.addEvent("domready",callback);
And different libraries all have their own way.

How to tell if a web page is being exited/unloaded via flash versus via normal HTML

I have a flash app, that redirects to another page.
I'd love to trap any other window unload event (clicking links / submitting forms) and warn the user they'll lose their progress in the Flash app.
However, I can't find any way to tell that the click/change of URL/window unload was triggered by Flash vs being triggered by a normal link etc.
Is there any way to detect this, and how reliable is it?
There's no way to tell what caused an unload event directly in the event handler. However, you might be able to achieve this by attaching an onclick event handler to every link on the page that sets a variable. In jQuery:
$("A").click(function(){window.clickedLink = this});
You might read the clickedLink in your unload event and tell the difference.
How do you redirect to the other page from Flash?
What you can do is redirect with a Javascript-function, and call this from Flash (with ExternalInterface). When you call this redirect, you set a certain flag, indicating you're redirecting from Flash. Then set a listener for the window unload event, and check if the flag is set. If not, you can show the message to the user. Otherwise, just skip this and redirect.
<script>
var callFromFlash = false;
window.unload = unloadPage;
//call this function from Flash using ExternalInterface
function doRedirect(url)
{
callFromFlash = true;
//redirecting
window.location.href = url;
}
function unloadPage()
{
if(!callFromFlash)
{
//show message and wait for response
}
}
</script>

Categories