chrismcb
chrismcb

Reputation: 167

Opening links in default browser with InAppBrowser in PhoneGap/Cordova

I'm building an app which wraps a responsive online website into an easy to use system using PhoneGap (specifically, PhoneGap Build) and InAppBrowser.

The app loads and operates fine, except for one feature - opening external links in the system's default browser.

This is 95% working, however specific cases cause issues where the link is redirecting (e.g. http://www.facebook.com redirects to https://www.facebook.com redirects to https://m.facebook.com).

With my code, it is detecting that the URL is outwith the configured domain and opens it in a new system window, but also then loads the other two redirections AND also loads it within the app.

The desired operation would be that it opens the link in the system's default browser and stops all further processing, redirection included.

Note that just simply changing the target from the link on the HTML page to _system does not work, as it is external to the app since it is from a live website.

Any tips and advice is greatly appreciated.

The most important excerpts of the code are below:

From within the PhoneGap app:

//Called on deviceready
function launchSite(){
    // Get Webpage in InAppBrowser (using the _blank target) and hide it until loaded
    iabRef = window.open(url+'?inApp=true'), '_blank', 'location=no,hidden=yes');

    //Attach listener for external link intercepting
    iabRef.addEventListener('loadstart', iabLoad);
    //Attach listener for loading complete
    iabRef.addEventListener('loadstop', iabLoaded);     
}

//Check if links are external, if they are, open them in the system's default browser
function iabLoad(event){
    if(debug) alert('Page load request for ' + event.url);
    //Check the link to see if it is external, which is flagged by #appExt from injection.js
    if(event.url.indexOf('appExt') > -1){
        //Open the window using the _system target to use the system's default browser
        if(debug) alert('Opening '+event.url + ' in system window')
        window.open(event.url,'_system');

        if(debug) alert('Stopping anything more');
        //Mobile redirects keep triggering load events from initial link, stop the process now.
        window.stop(); // <-Does not stop
    }
    else{
        if(debug) alert('Opening normally without interference');
    }
}

//If window was hidden whilst loading, show it now that it has loaded
function iabLoaded(event){
    if(debug) alert('Showing IAB window');
    iabRef.show();
}

From a javascript file included in the responsive website:

function isExternal(url) {
    var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
    if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) return true;
    if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"), "") !== location.host) return true;
    return false;
}

function goToPage(url, external){
    if(external)
        //Go to new URL with appended hash flag
        window.location=encodeURI(url)+'#appExt';
    else{
        //Show loading screen
        $('#app-overlay').css('display','block');
        //Wait for 100ms then change page, so the loading screen gets time to show
        setTimeout(function(){window.location=encodeURI(url)},100);
    }
}

$('a').on('click',function(e){
    e.preventDefault();

    if(isExternal($(this).attr('href'))){
        //If the URL is an external one, the app.js file will open the url in a new window after setting the appExt hash flag
        if(debug) alert('Stopping navigation from injection.js as external link detected');
        goToPage($(this).attr('href'), true);
    }
    else{
        //Otherwise, continue normally
        if(debug) alert('Regular link clicked');
        goToPage($(this).attr('href'), false);
    }

    //Cancel the default link operation, as we've already handled it
    return false;
});

Update: Continued tweaking and recompiling hasn't got me any further - anyone able to cast an eye over this for me?

Upvotes: 0

Views: 2754

Answers (2)

Larry L
Larry L

Reputation: 25

I'm not sure it's the best answer, but I "solved" it by keeping track of the last URL that was visited (through the startLoad event) and when I see someone linking somewhere to a different site than the one that is already loaded (using the startLoad event), I do a window.open with _system on the external URL, and then change the page of the InAppBrowser back to the last URL it was on (which I'm keeping track of).

Not the most elegant, but I couldn't find any other way to do it, and it seems to work not bad. Using cordova 3.6.3 (hoping to upgrade next week) and inAppBrowser 0.6.0. I can probably post code snippets if someone thinks it might be useful.

Upvotes: 1

dpfauwadel
dpfauwadel

Reputation: 3934

Do you try to do a window.open to open your link in the browser? In our app we do it like this

<span class="item_link"><a href="#" onclick="window.open(\''+ YourUrl +'\', \'_system\');">' + MoreLink + '</a></span>

Upvotes: 0

Related Questions