Prevent offline iphone webapp from opening link in Safari - safari

I’m developing a website that will work with mobile safari in offline mode. I'm able to bookmark it to the home screen and load it from there. But, once opened from the home screen, clicking on certain links will jump out of the app and open in mobile safari – despite the fact that I preventDefault() on all link clicks!
The app binds an onclick event handler at the <body> level. Using event delegation, it catches any click on any link, looks at its href (eg 'help' or 'review'), and dynamically calls a javascript template and update the pages. The event handler calls preventDefault() on the event object – for some of the links this works, and the page is updated with the template output. However, for the links that result in a hit against the local database before outputting the results of the template, the links are opened in mobile safari.
In desktop safari, all the links work even when i’m offline – something is happening that’s mobile safari specific.
Any thoughts on why some links would work offline, but not others? None of the link URLs in question are listed in the manifest file, but they don’t (shouldn't) need to be since the link action is prevented.
a couple extra oddities:
* once I click on a a link that loads in mobile safari, even if I'm offline, those same links now work, and the templates populated with data from the db work properly. in other words: the links fail when opened from the home screen, but not from within mobile safari offline
* changing the link to remove the database hit (populating the template with a mock db result) solves the problem, and the links can be clicked in the app from the home screen.

You may want to take a look at this: https://gist.github.com/1042026
// by https://github.com/irae
(function(document,navigator,standalone) {
// prevents links from apps from oppening in mobile safari
// this javascript must be the first script in your <head>
if ((standalone in navigator) && navigator[standalone]) {
var curnode, location=document.location, stop=/^(a|html)$/i;
document.addEventListener('click', function(e) {
curnode=e.target;
while (!(stop).test(curnode.nodeName)) {
curnode=curnode.parentNode;
}
// Condidions to do this only on links to your own app
// if you want all links, use if('href' in curnode) instead.
if('href' in curnode && ( curnode.href.indexOf('http') || ~curnode.href.indexOf(location.host) ) ) {
e.preventDefault();
location.href = curnode.href;
}
},false);
}
})(document,window.navigator,'standalone');

I got it to work, the problem was due to an unseen error in the event handler code (unrelated to stopping the link from being followed). If you bind an event handler for click events to the body tag, and call preventDefault(), then the link will not be followed and mobile safari will not open, and you can define you own logic for updating the page based on that link url.
You should be sure that you call preventDefault() before any errors could possibly occur - the problem in my case was that an error was occurring in the event handler before preventDefault() was called, but of course I couldn't see that error in the console because the link had already been followed.
Here's the code I'm using (it assumes DOM standard events and would fail in IE):
bodyOnClickHandler = function(e) {
var target = e.target;
if (target.tagName == 'A') {
e.preventDefault();
var targetUrl = target.getAttribute("href");
//show the page for targetUrl
}
}

Related

join() function onload page not working on mobile

Join function works when click on join button but not working on loading page my code for the click button is
$(document).ready(function(){
setTimeout(function() {
$( "#join" ).trigger( "click" );
}, 5000);
});
The reason for your issue is rooted in how most browsers are now handling video elements auto play functionality. (chrome, Firefox,safari).
TLDR; The browsers will block auto play on any videos that have sound enabled unless the user interacts with the page via click. For this reason it works when you have joinChannel via click, it meets the criteria for a user initiated interaction with the page and so the browser allows the video to play.
This is the recommended behavior, as it ensures the user is ready to view the content. Take a look at Google Hangouts/Meet for a commercial product that implements this logic
There is another option, which is technically possible (but not recommended). You could start the video with the audio muted. The reason this isn't recommended is there is no telling if in the future browsers will block auto play functionality all together so this could break again.

How to handle new tab opening with Splash?

I'm scraping website which has a very annoying link (<a> HTML tag) - it opens the small pop-up form on click and after submitting it, opens new browser tab (and switches focus to it) with URL that I need, and also redirects old tab to another page.
Successful submitting of the pop-up form was easy, but I don't know how to get URL of this new tab.
And as the documentation says, Splash can work only with one tab, so is it impossible to do that?
As Splash's developer comments on this GitHub issue this feature is not implemented.
But I posted my solution to this problem on the same issue.
Example:
function main(splash, args)
assert(splash:go(args.url)) -- execute JS code below only after loading the page
splash:runjs("var newTabURL")
splash:runjs("newTabURL = null") -- sometimes JS can't find variable without this line
splash:runjs("window.open = function(url){newTabURL = url}")
-- actions which open the new tab
local new_tab_url = splash:evaljs("newTabURL")
-- other actions
end

Communication Between WebView and WebPage - Titanium Studio

I am working in a Mobile project (using Titanium Studio), in which i have the below situation
1) My Mobile app contacts Rails backend to check some data, say check validity of a
user id.
2) I found a way to load web pages in Mobile app, i.e., WebView
3) I could able to load the desired url, ex http://www.mydomain.com/checkuser?uid=20121
which would return data like status:success
But i need to read this data to show whether the response from server is a success or failure, how do i achieve this?
NOTE : The above mentioned scenario is an usecase, but actually what happens is i load a third party url in WebView and when user enters the data and submits, the result will be posted back to my website url.
EDIT : So the process is like below
1) WebView loaded with third party url like http://www.anyapiprovider.com/processdata
2) User will enter set of data in this web page and submits the page
3) The submitted data will be processed by the apiprovider and it returns data to my web page say http://www.mydomain.com/recievedata
This is the reason why i am not directly using GET using HTTPClient
FYI : I tried to fire Ti.APP events right from the actual web page as suggested by few articles, but most of them says this will work only if the file loaded is in local and not a remote file. Reference Link
Please suggest me if my approach has to be improved.
Thanks
If you don't want to follow Josiah's advice, then take a look at the Titanium docs on how to add a webview.addEventListener('load',... event listener and use webview.evalJS() to inject your own code into the third party HTML.
Maybe you can inject code to trap the submit event and fire a Ti event to trigger the downloading of data from your website.
Communication Between WebViews and Titanium - Remote Web Content Section
I found a solution for my problem
1) Load the http://www.mydomain.com/checkuser?uid=20121 in a webview
2) Let user enter and submit data to third party url
3) Recieve the response from third party url and print only <div id="result">status:success</div> in http://www.mydomain.com/recievedata page.
4) Add event listener for the web view as follows
webView.addEventListener('load', function(data)
{
//Add condition to check if the loaded web page has any div with id = result (to check if this is /recievedata page)
alert(webView.evalJS("document.getElementById('result').innerHTML"));
});
The above alert would print the result status:success, read it in webview load event
and take actions in web accordingly.
It works fine for me.
Instead of loading it in a WebView why not just GET it using a HTTP Client? This is much cleaner, and more standards based:
var xhr_get = Ti.Network.createHTTPClient({
onload : function(e) {
// Here is your "status:success" string
var returnValue = this.responseText;
},
onerror : function(e) {
Ti.API.info(this.responseText);
Ti.API.info('CheckUserProgressOnActivity webservice failed with message : ' + e.error);
}
});
xhr_get.open('GET', 'http://www.mydomain.com/checkuser?uid=20121');
xhr_get.send();

facebook dialog to add facebook tab app - returns - tabs_added[pageId]=1

It seems the new dialog to tab app to a page -> https://developers.facebook.com/docs/reference/dialogs/add_to_page/ - calls the app url with a GET (redirect_uri?tabs_added[nnnnn]=1) (where nnnn - pageId of page the app is being added to)
I can't find the documentation around whether when the app is removed from the page, the same url will be called with a GET (redirect_uri?tabs_added[nnnnn]=0) ?
I am keen to process the uninstall of the app from the page, if possible. (I have tried to test this, but don't get a trigger to my redirect_uri upon an installed, unlike the one that is called upon an install..)
My question is - whether there is a way to get a delete page callback into the app (when a page uninstalls/deletes the app from the page) ? From the syntax on install GET call (?tabs_added[nnn]=1, it seems that this might have been designed with an intention to call a GET with ?tabs_removed[nnnn]=1 or tabs_added[nnnn]=0 when the app is deleted from the page ?
Empirically, the answer to your question is No. Nothing on my server gets called by Facebook when the Page Tab is removed.
Go to the advanced tab on the facebook app settings, and put a URL of your choice into the 'Deauthorize Callback URL' field. You will receive a callback on that and you need to parse the signed request.
Example in php:
$helper = $fb->getPageTabHelper();
$signedRequest = $helper->getSignedRequest();
if ($signedRequest) {
$payload = $signedRequest->getPayload();
//trace(print_r($payload, true));
$pageId = $payload['profile_id'];
//You can now update your records using $pageId
}

API Error Code 102 : javascript dialogs with php

API Error Code: 102
API Error Description: Session key invalid or no longer valid
Error Message: Iframe dialogs must be called with a session key
I get this funny message when calling a fb dialog to post to a friends wall in my new app. The same code is working for other apps. This suddenly stopped working. When i specifically dont set iframe, a weird pop up now pops up now. As browsers block pop ups it doesnt turn up.
Also auto posting directly is not working even when user permits. My app is not unresricted also. Any one has any idea ??
I've had this error, when calling dialog without user interaction. For example when both 'document ready' and 'FB js-sdk loaded events' are fired. When i called the dialog with same function, parameters, on same page but in reaction on user mouse click - it worked.
If this is similiar to what you have, here is the solution:
FB.getLoginStatus(function(response) {
if (response.authResponse) {
//call dialog here
}
});