Navigating back from other app breaks click handler - angularjs

For our company we have a lot of devices rolled out with Mobicontrol Soti. This allows us to lock the device in something called a kiosk mode which disables the use of the homescreen and provides a custom screen that only have a set off apps we can decide.
One of the provided apps is a Ionic app that opens links in a browser (Soti Surf) but this gives 2 problems.
code
HTML:
<div (click)="$ctrl.doTheThing()"> something </div>
JS:
private doTheThing() {
this.inAppBrowser.create('surfs://' + url.replace(/^(https?:|)\/\//, ''), '_system');
}
First issue
First of all when I use the android back button the click doesn't seem to work anymore (I've put an alert in the first line of the doTheThing function, but nothings shows up).
Other buttons in the app seem to work just fine, when using the switch app button it also works
I tried:
preventDefault()
stopPropagation()
using the tappable attribute
(tap) instead of (click)
but none seem to work. Does anybody have an idea for fixing this?
Second issue
Note: this is less important
When opening a link it remembers the last page(in soti surf) so by using the back arrow it first navigates to the last link and when it has no more back locations it goes back to the app
I tried:
using the return value of the inAppBrowser.create() and calling close() when returning to my app
Version info
#ionic-native/core version: 4.16.0
cordova-android: 7.1.4
cordova -v: 8.1.2 (cordova-lib#8.1.1)
npm -v: 6.4.1
ionic: 4.12.0
nodeJS: 11.1.0

Here in ionic you can prevent device back button by using Navbar Class and using Lifecycle hook method
Here is a sample
ionViewDidLoad() {
this.navBar.backButtonClick = (e: UIEvent) => {
// todo something
if (condition )
{
this.getSaveDialog();
} else{
this.navCtrl.pop();
}
})
}
For opening In Appbrowser in your app, will lose control of your events, you can't track and manage the
state of pages.
It can be maintain by browser. you need to place hacks or alternative in your application which is opening in APP

Related

Detect if browser back button was clicked when coming from a different website/application with Angular

My main issue is the following. I'm redirecting a page using the router in an AngularJS application to a Angular application. This works fine but when trying to go back to the page you came from you'll have to click the back button twice because when on a page going to a route, you load to route itself and then you redirect.
Example: you're on page A (AngularJS), you go to page B (AngularJS route) which redirects to C (Angular application).
When on page C you use the back button and as a user you expect to go back to page A but instead you go to page B and are redirected again to C.
Right now I think about detecting if the back button was clicked and the going back in the history with
window.history.go(-2)
Going back in the history works and I found a lot of questions and answers on SO to detect clicking the back button. But these ways of detecting the back button do not work when your origin is an AngularJS application and your code is in your Angular application.
Any idea how to detect the back button when your previous page was not the same application?
For now I came up with this solution.
In the routing of my AngularJS app I used:
redirectTo: function(routeParams) {
window.location = 'http://externalpathtoAngularApp';
}
and then in the Angular app in the controller of the page that is redirected to I added the following to the constructor of my class
if (document.referrer === 'http://originOfAngularJSApp') {
window.onpopstate = function () {
console.log(document.referrer);
};
history.pushState({}, '');
}
and also add this HostListener in the class after the constructor
#HostListener('window:popstate', ['$event'])
onPopState(event) {
if (document.referrer === 'http://originOfAngularJSApp') {
window.history.go(-2);
}
}
This is somewhat satisfying but it doesn't cover all the scenario's yet. For example if you come from app A and are redirected to C, then it goes back to A is expected.
But if you come from A redirected to C and then go to D, F... (in the Angular app) and then go back to C using the back button and finally using the back button to go to A you will be redirected to C again.
So in this case it's not completely covered yet.

How to push the initial page resetting the pages stack?

i'm using Onsen (v1.3.12) and Angular to develop my cross-platform app.
I added a button to go back to the home page of the app, so if users make some pop or some push of pages, when they hit on "Home" button they go back to initial page.
I use the following code:
$rootScope.myNavigator.resetToPage('homepage.html');
but it doesn't show the animation effect of "popping page" that is visible with pushPage method.
To get this effect i have to use the following code:
$rootScope.myNavigator.pages.length = 1;
$rootScope.myNavigator.pushPage('splash.html');
$timeout(function() {
$rootScope.myNavigator.pages.length = 0;
});
Isn't the default behaviour of resetPage method weird? Why it doesn't show the "pop" effect?
I solved using animation option:
$rootScope.myNavigator.resetToPage('splash.html', {animation: 'slide'});
The weird thing is that pushPage, popPage and resetPage methods have default animation option set to slide. The same doesn't happen for resetPage method.
Maybe is a Onsen bug.

Click on 'Google' in Google Maps

In my angularjs mobile project I have implemented Google Maps, but in the app there is a "Google" tag at bottom left ogfmy map, and clicking on it will take me to the google map app and not able to return to my App,Please suggest a turnaround for this solution.
You have to prevent the default behaviour of the click on the link and open it on inAppBrowser instead.
First install inAppBrowser plugin and then add this code (map-canvas is the id of you map, it might be different, change it if necessary)
var googleMap = document.getElementById("map-canvas");
var anchors = googleMap.getElementsByTagName("a");
for (var i=0; i<anchors.length; i+=1)
{
anchors[i].addEventListener("click", openInAppBrowser);
}
function openInAppBrowser(e) {
e.preventDefault();
window.open(this.href, "_blank", "location=yes");
}
You probably meant to write that tapping the link opens it inside the webview of your application, replacing your own.
Find the link in the source make sure it will open in either InAppBrowser or using _blank so it'll open in the browser app instead.

I can't move website created in famous on mobile device

I've created website completely in angular + famous.
In desktop it's working great. When I try to open it in safari / chrome on iPhone it's working great as well but there is one problem. Using my finger I can't move page at all, only touch event is recognized, nothing more.
This is happening also in official examples. For example examples/views/Scrollview/example.html. If I rotate my iPhone 6 Plus to landscape I can't even access the browser toolbar to close the page, I need to kill the browser and start it again.
What I am suppose to do to fix this? Why is this even happening?
The problem is that you are using Famous in appMode. Try setting the following and see if that works:
Engine.setOptions({appMode: false});
When Famous is in appMode, it will add the following snippet when the context is created:
function initialize() {
// prevent scrolling via browser
window.addEventListener('touchmove', function(event) {
event.preventDefault();
}, true);
addRootClasses();
}
This is what prevents the browser page from moving.
function initialize() {
// prevent scrolling via browser
window.addEventListener('touchmove', function(event) {
event.preventDefault();
}, true);
addRootClasses();
}

How can I tame multiple event listeners in a Fennec extension?

I'm trying to write a restartless add-on for Firefox Mobile that will insert content onto specific web pages. It all seems to work OK until I try disabling then re-enabling the add-on, at which point I get multiple responses to the page load event, and I can't figure out a way to sort them out.
Since Fennec uses the Electrolysis multi-process platform, I know that I need to split my code into chrome and content scripts. My bootstrap.js looks something like this (trimmed for clarity):
function startup(data, reason) {
mm = Cc["#mozilla.org/globalmessagemanager;1"].getService(Ci.nsIChromeFrameMessageManager);
mm.loadFrameScript(getResourceURISpec('content.js'), true);
}
function shutdown(data, reason) {
let mm = Cc["#mozilla.org/globalmessagemanager;1"].getService(Ci.nsIChromeFrameMessageManager);
mm.sendAsyncMessage("GeoMapEnh:Disable", {reason: reason});
}
function install(data, reason) {}
function uninstall(data, reason) {}
Basically, the bootstrap.js just launches a content script, and sends a message to tell it to clean up on shutdown. The content.js sets up an eventListener to watch for page loads, that looks a bit like this:
addMessageListener("GeoMapEnh:Disable", disableScript);
addEventListener("DOMContentLoaded", loadHandler, false );
function loadHandler(e) {
LOG("Page loaded");
// Do something cool with the web page.
}
function disableScript(aMessage) {
if (aMessage.name != "GeoMapEnh:Disable") {
return;
}
LOG("Disabling content script: " + aMessage.json.reason);
try {
removeEventListener("DOMContentLoaded", loadHandler, false );
removeMessageListener("GeoMapEnh:Disable", disableScript);
} catch(e) {
LOG("Remove failed: " + e);
}
}
function LOG(msg) {
dump(msg + "\n");
var consoleService = Cc["#mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
consoleService.logStringMessage(msg);
}
When I first run the extension, everything works fine. An instance of content.js is executed for each browser tab (and any new tabs I open) and my eventListener detects the page loads it is supposed to via the DOMContentLoaded event. When I disable the extension, everything still seems OK: page loads stop being detected.
When I re-enable the extension, it all goes wrong. I still get an instance of content.js executing for each open tab, but now, if I open new tabs, DOMContentLoaded triggers mutiple eventListeners and I can't distinguish which one should handle the event. Worse yet, some of the eventListeners are active, but do not give debug info via my LOG function, and do not all of them get removed if I disable the extension a second time.
I do want to watch all browser tabs, including any new ones, but I only want my extension to insert content on the page that triggers it, and only once per page load. I've tried the following without success:
Calling e.stopPropagation() to stop the event being passed to other listeners. No effect.
Calling e.preventDefault() and testing e.defaultPrevented to see if the event has already been handled. It never has.
Testing if (this === content.document) to see if the eventListener has been triggered by its own page content. Doesn't work, as I get multiple "true" responses.
Making the eventListener capturing. No effect.
Using the load event rather than DOMContentLoaded.
I can't set a shared variable to say the event has been handled as under Electrolysis, the different eventListeners will be executing in different contexts. Also, I wouldn't be able to distinguish between multiple tabs loading the same page and one page load being detected multiple times. I could do this via IPC message passing back to the chrome bootstrap script, but I then I wouldn't know how to address the response back to the correct browser tab.
Any ideas? Is this a Firefox bug, or am I doing something silly in my code? I am using Fennec Desktop v4 for development, and will target Fennec Android v6 for production.

Resources