// Meteor's OAuth flow currently only works with popups. Phonegap does
// not handle this well. Using the InAppBrowser plugin we can load the
// OAuth popup into it. Using the plugin by itself would not work with
// the MeteorRider phonegap method, this fixes it. This has not been
// tested on other Meteor phonegap methods. (tested on PG 3.3, android, iOS)
//
// http://docs.phonegap.com/en/3.3.0/cordova_inappbrowser_inappbrowser.md.html
// https://github.com/zeroasterisk/MeteorRider
window.patchWindow = function () {

    // Make sure the InAppBrowser is loaded before patching the window.
    var inAppBrowserLoaded = !!(window.cordova && window.cordova.require('org.apache.cordova.inappbrowser.inappbrowser'));
    if (!inAppBrowserLoaded) return false;

    // Keep a reference to the in app browser's window.open.
    var __open = window.open,
        oauthWin,
        timer;

    // Create an object to return from a monkeypatched window.open call. Handles
    // open/closed state of popup to keep Meteor happy. Allows one to save window
    // reference to a variable and close it later. e.g.,
    // `var foo = window.open('url');  foo.close();
    window.IAB = {
        closed: true,

        open: function (url) {
            // XXX add options param and append to current options
            oauthWin = __open(url, '_blank', 'location=no,hidden=yes');

            oauthWin.addEventListener('loadstop', checkIfOauthIsDone);

            // use hidden=yes as a hack for Android, allows popup to yield events with
            // each #show call. Lets events run on Meteor app, otherwise all listeners
            // will *only* run when tapping done button or oauthWin.close
            //
            // XXX should be a better way to do this
            if (device.platform === 'Android') {
                timer = setInterval(oauthWin.show, 200);
            } else {
                oauthWin.show();
            }

            // check if uri contains an error or code param, then manually close popup
            function checkIfOauthIsDone(event) {
                // XXX improve this regex to match twitters as well
                if (!event.url || !event.url.match(/error|code=/)) return;

                // Get the credentialToken and credentialSecret from the InAppBrowser's url hash.
                var hashes = event.url.slice(event.url.indexOf('#') + 1).split('&');
                var credentialToken = hashes[0].split('=')[1];
                var credentialSecret = hashes[1].split('=')[1];

                OAuth._handleCredentialSecret(credentialToken, credentialSecret);
                Accounts.oauth.tryLoginAfterPopupClosed(credentialToken);
                oauthWin.close();

                clearInterval(timer);
                oauthWin.removeEventListener('loadstop', checkIfOauthIsDone)
            }

            this.closed = false;
        },

        close: function () {
            if (!oauthWin) return;

            clearInterval(timer);

            oauthWin.close();
            this.closed = true;
        }
    };

    // monkeypatch window.open on the phonegap platform
    if (typeof device !== "undefined") {
        window.open = function (url) {
            IAB.open(url);
            // return InAppBrowser so you can set foo = open(...) and then foo.close()
            return IAB;
        };
    }

    // Clear patchWindow to prevent it from being called multiple times.
    window.patchWindow = function () {
    };

    return true;
};

// Patch the window after cordova is finished loading
// if the InAppBrowser is not available yet.
if (!window.patchWindow()) document.addEventListener('deviceready', window.patchWindow, false);
@@ -867,23 +867,8 @@
 hWin
-,%0A        timer
 ;%0A%0A 
@@ -1439,485 +1439,24 @@
     
-// use hidden=yes as a hack for Android, allows popup to yield events with%0A            // each #show call. Lets events run on Meteor app, otherwise all listeners%0A            // will *only* run when tapping done button or oauthWin.close%0A            //%0A            // XXX should be a better way to do this%0A            if (device.platform === 'Android') %7B%0A                timer = setInterval(oauthWin.show, 200);%0A            %7D else %7B%0A                oauthWin.show();%0A            %7D
+oauthWin.show();
 %0A%0A  
@@ -1612,56 +1612,104 @@
  // 
-XXX improve this regex to match twitters as well
+if this is the oauth prompt url, we are not done%0A                if (url === event.url) return;%0A
 %0A   
@@ -1757,16 +1757,22 @@
 .match(/
+close%7C
 error%7Cco
@@ -1779,32 +1779,101 @@
 de=/)) return;%0A%0A
+                if (event.url.indexOf('credentialToken') %3E -1) %7B%0A    
                 
@@ -1966,24 +1966,28 @@
             
+    
 var hashes =
@@ -2051,32 +2051,36 @@
                 
+   
+ 
 var credentialTo
@@ -2110,16 +2110,95 @@
 =')%5B1%5D;%0A
+%0A                    if (event.url.indexOf('credentialSecret') %3E -1) %7B%0A        
         
@@ -2245,33 +2245,38 @@
 .split('=')%5B1%5D;%0A
-%0A
+      
                 
@@ -2275,16 +2275,18 @@
         
+  
 OAuth._h
@@ -2343,16 +2343,43 @@
 ecret);%0A
+                    %7D%0A%0A    
         
@@ -2460,33 +2460,17 @@
         
-oauthWin.close();
+%7D
 %0A%0A      
@@ -2479,38 +2479,35 @@
         
-clearInterval(timer
+oauthWin.close(
 );%0A
+%0A
         
@@ -2574,16 +2574,17 @@
 hIsDone)
+;
 %0A       
@@ -2705,43 +2705,8 @@
 n;%0A%0A
-            clearInterval(timer);%0A%0A
     

Add support for twitter. Close oauth window if the user cancels the authentication.