/** * @file * Javascript behaviors and helpers for modules/fb. */ FB_JS = function(){}; FB_JS.fbu = null; /** * Drupal behaviors hook. * * Called when page is loaded, or content added via javascript. */ Drupal.behaviors.fb = function(context) { // Respond to our jquery pseudo-events var events = jQuery(document).data('events'); if (!events || !events.fb_session_change) { jQuery(document).bind('fb_session_change', FB_JS.sessionChangeHandler); } // Once upon a time, we initialized facebook's JS SDK here, but now that is done in fb_footer(). if (typeof(FB) != 'undefined') { // Render any XFBML markup that may have been added by AJAX. $(context).each(function() { var elem = $(this).get(0); FB.XFBML.parse(elem); }); FB_JS.showConnectedMarkup(Drupal.settings.fb.fbu, context); } // Markup with class .fb_show should be visible if javascript is enabled. .fb_hide should be hidden. jQuery('.fb_hide', context).hide(); jQuery('.fb_show', context).show(); }; if (typeof(window.fbAsyncInit) != 'undefined') { // There should be only one definition of fbAsyncInit! debugger; }; // This function called by facebook's javascript when it is loaded. // http://developers.facebook.com/docs/reference/javascript/ window.fbAsyncInit = function() { if (Drupal.settings.fb) { FB.init(Drupal.settings.fb.fb_init_settings); } // Facebook recommends calling getLoginStatus after FB.init (http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/) // However, it's got lots of bugs reported against it (https://developers.facebook.com/bugs/240058389381072, http://developers.facebook.com/bugs/173032012783482?browse=search_4ecd4a1aa27a81146273027) // So we make it optional whether we call it or not. if (FB._apiKey && Drupal.settings.fb.get_login_status) { FB.getLoginStatus(function(response) { FB_JS.initFinal(response); FB_JS.authResponseChange(response); }); } else if (FB._apiKey && Drupal.settings.fb.fb_init_settings.authResponse) { FB_JS.initFinal({'authResponse' : Drupal.settings.fb.fb_init_settings.authResponse}); } else { // No application. Not safe to call FB.getLoginStatus(). // Or, we are configured to not call getLoginStatus(). // We still want to initialize XFBML, third-party modules, etc. FB_JS.initFinal({'authResponse' : null}); } if (FB._apiKey && !Drupal.settings.fb.get_login_status && Drupal.settings.fb.test_login_status && FB.getUserID()) { // This is an alternative to calling getLoginStatus(). Adds some overhead to the client side by calling FB.api on every page. But, will detect if user has logged out of facebook. FB.api('/me', function(response) { // Calling FB.api is unfortunate overhead, but no other way to detect if user has logged out of facebook. if (typeof(response.error) != 'undefined') { // Fake an auth response change so Drupal knows user is logged out. FB_JS.authResponseChange({'authResponse' : null}); } else if (response.id != Drupal.settings.fb.fbu) { // Fake an auth response change so Drupal knows user has changed. FB_JS.authResponseChange({'authResponse' : {'userID' : response.id}}); } }); } }; /** * Finish initializing, whether there is an application or not. */ FB_JS.initFinal = function(response) { var status = { 'status': response.status, // not using oauth 'auth': response.authResponse, // using oauth 'response': response }; jQuery.event.trigger('fb_init', status); // Trigger event for third-party modules. FB_JS.authResponseChange(response); // This will act only if fbu changed. FB_JS.eventSubscribe(); FB.XFBML.parse(); } /** * Tell facebook to notify us of events we may need to act on. */ FB_JS.eventSubscribe = function() { // Use FB.Event to detect Connect login/logout. FB.Event.subscribe('auth.authResponseChange', FB_JS.authResponseChange); // Q: what the heck is "edge.create"? A: the like button was clicked. FB.Event.subscribe('edge.create', FB_JS.edgeCreate); } /** * Helper parses URL params. * * http://jquery-howto.blogspot.com/2009/09/get-url-parameters-values-with-jquery.html */ FB_JS.getUrlVars = function(href) { var vars = [], hash; var hashes = href.slice(href.indexOf('?') + 1).split('&'); for(var i = 0; i < hashes.length; i++) { hash = hashes[i].split('='); vars[hash[0]] = hash[1]; if (hash[0] != 'fbu') vars.push(hashes[i]); // i.e. "foo=bar" } return vars; } /** * Reload the current page, whether on canvas page or facebook connect. * * append fbsig, a hash of the session data, to avoid infinite reloads * in some cases. */ FB_JS.reload = function(destination) { if (Drupal.settings.fb.reload_url_append_hash) { var fbhash; // Determine url hash. if (FB._oauth) { var auth = FB.getAuthResponse(); if (auth != null) fbhash = auth.signedRequest; // Use sig rather than compute a new hash. else fbhash = 0; } else { var session = FB.getSession(); if (session != null) fbhash = session.sig; else fbhash = 0; } } // Avoid infinite reloads. Still needed? It would be nice to do away with this code if not needed. ///@TODO - does not work on iframe because facebook does not pass url args to canvas frame when cookies not accepted. http://forum.developers.facebook.net/viewtopic.php?id=77236 var vars = FB_JS.getUrlVars(window.location.href); if (typeof(fbhash) != 'undefined' && vars.fbhash == fbhash) { return; // Do not reload (again) } // Determine where to send user. if (typeof(destination) != 'undefined' && destination) { // Use destination passed in. } else if (typeof(Drupal.settings.fb.reload_url) != 'undefined') { destination = Drupal.settings.fb.reload_url; } else { destination = window.location.href; } // Split and parse destination var path; if (destination.indexOf('?') == -1) { vars = []; path = destination; } else { vars = FB_JS.getUrlVars(destination); path = destination.substr(0, destination.indexOf('?')); } // Add fbhash to params before reload. if (Drupal.settings.fb.reload_url_append_hash) { vars.push('fbhash=' + fbhash); } // Use window.top for iframe canvas pages. destination = vars.length ? (path + '?' + vars.join('&')) : path; if (Drupal.settings.fb.reload_url_fragment) { destination = destination + "#" + Drupal.settings.fb.reload_url_fragment; } // Feedback that entire page may be reloading. // @TODO improve the appearance of this, make it customizable. jQuery('body').prepend('