Sunday, July 31, 2011

GSoC 2011 Integration with External APIs: Popup Blocking Policy - W10

This week, unfortunately i was not productive. I had quite problems mainly based on "same origin policy". Tonight, story of the week seems ending nice, because i finally resolved how to make cross-domain requests with JavaScript. I will write two blog posts this week, this one for another problem "popup blocking problem" and next one for "same origin policy". If you don't have extra time for reading two blog posts, i suggest you read next one, because it's the main story of the week for me.

Popup Blocker Policy
I want to mention this before "same origin policy" problem. We had to use a window popup in OAuth authentication. Popup was used to open immediately after user clicks an element whom click event is connected to an authentication required function. This authentication required function was either opening popup, or running its own logic if user was already authenticated. This was how it was working:
 
User (before page loads):
- User requests a page which uses melange.gdata.core.js on user side. This script provides gdata login methods and gdata API requests for JS.

Server:
- Page indicates melange.gdata.core.js dependecy in its template by using our dependecy *mechanism*. 
- Page also needs to init melange.gdata.core.js with some context values those tell script some initial values: gdata_is_logged_in, oauth_redirect_url.

User (after page loads):
- If a page specific Javascript function  has a logic that needs authentication to GData, for example for the proposal page:

In proposal/base.js:

function sync() {
    //code that nees authentication
}
authenticated_sync = melange.gdata.core.createAuthorizedFunction(sync);
button.click(authenticated_sync)


This is working in peace for proposal page which adds melange.gdata.core.js to dependencies in it's template and inits it with some context value which is produced by a context helper (A helper which creates gdata_is_logged_in and oauth_redirect_url values). But for the "List Exporting" this was quite redundant workforce to init melange.gdata.core.js in every template because a big per cent of Melange pages contain lists. We did not want any extra configuration for every list page. Indicating list dependecy should be enough. So we tried to skip initialization of melange.gdata.core.js until user expresses he wants to use an authorization required feature. We tried to make this initilaziation with a JSON request. For example when user clicks "Export" button, it asks server for initialization values and with respect to response, performs required authentication process if required. Every thing seemed fine until i realized tha, request time delay was causing popup window to be blocked by browser's popup blocker. If we want to open a popup it should be immediately after a click event occured, but we can't know if we need to open a popup without asking it to server (so without waiting).

So we needed to change this mechanism. Script melange.gdata.core.js must be aware of gdata_is_logged_in value before click event. We solved this by moving gdata initialization into Melange's general javascript config initialization which works for every page. So with little redundancy (because we don't need to calculate is_logged_in value for every page), we were able to init it without extra initialization code for every page that uses melange.gdata.core.js. If we can assume %90 of Melange pages contains lists, this is not a big CPU usage redundacy.

I don't know if this popup blocking policy is browser dependent or not. But from my experiences i had the conclusion that most guarantee way of opening a popup is doing immediately after a click event is occured.

No comments:

Post a Comment