Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* @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);
}
Dave Cohen
committed
if (FB._apiKey) {
if (typeof(Drupal.settings.fb.fb_init_settings.authResponse) == 'undefined') {
// Check the login status. If offline_access granted, this
// is the only way to know if user has logged out of facebook.
FB.getLoginStatus(function(response) {
FB_JS.initFinal(response);
});
}
else {
// With third party cookies disabled, calling getLoginStatus doesnt seem to work.
// @TODO: figure out why getLoginStatus fails! Bug on facebook's side?
FB_JS.initFinal({'authResponse' : Drupal.settings.fb.fb_init_settings.authResponse});
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});
}
});
}
Dave Cohen
committed
}
else {
// No application. Not safe to call FB.getLoginStatus().
// We still want to initialize XFBML, third-party modules, etc.
FB_JS.initFinal({'authResponse' : null});
Dave Cohen
committed
}
};
Dave Cohen
committed
/**
* Finish initializing, whether there is an application or not.
*/
FB_JS.initFinal = function(response) {
Dave Cohen
committed
var status = {
'auth': response.authResponse,
'response': response
};
Dave Cohen
committed
jQuery.event.trigger('fb_init', status); // Trigger event for third-party modules.
Dave Cohen
committed
Dave Cohen
committed
FB_JS.authResponseChange(response); // This will act only if fbu changed.
Dave Cohen
committed
FB_JS.eventSubscribe();
Dave Cohen
committed
FB.XFBML.parse();
}
Dave Cohen
committed
/**
* 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.
Dave Cohen
committed
FB.Event.subscribe('auth.authResponseChange', FB_JS.authResponseChange);
Dave Cohen
committed
// 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
*/
Dave Cohen
committed
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.
Dave Cohen
committed
*
* append fbsig, a hash of the session data, to avoid infinite reloads
* in some cases.
FB_JS.reload = function(destination) {
Dave Cohen
committed
// Determine url hash.
Dave Cohen
committed
var auth = FB.getAuthResponse();
Dave Cohen
committed
var fbhash;
Dave Cohen
committed
if (auth != null)
fbhash = auth.signedRequest; // Use sig rather than compute a new hash.
Dave Cohen
committed
fbhash = 0;
Dave Cohen
committed
// 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);
Dave Cohen
committed
if (vars.fbhash == fbhash) {
return; // Do not reload (again)
}
// Determine where to send user.
if (typeof(destination) != 'undefined' && destination) {
}
else if (typeof(Drupal.settings.fb.reload_url) != 'undefined') {
destination = Drupal.settings.fb.reload_url;
// 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('?'));
}
Dave Cohen
committed
// 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.
Dave Cohen
committed
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('<div id="fb_js_pb" class="progress"><div class="bar"><div class="filled"></div></div></div>');
window.top.location = destination;
Dave Cohen
committed
//alert(destination);
// Facebook pseudo-event handlers.
Dave Cohen
committed
FB_JS.authResponseChange = function(response) {
//debugger;
if (response.status == 'unknown') {
// @TODO can we test if third-party cookies are disabled?
}
Dave Cohen
committed
var status = {
'changed': false,
'fbu': null,
'session': response.authResponse, // deprecated, still needed???
'auth': response.authResponse, // still needed???
'response' : response
};
Dave Cohen
committed
if (response.authResponse) {
status.fbu = response.authResponse.userID;
Dave Cohen
committed
if (Drupal.settings.fb.fbu != status.fbu) {
// A user has logged in.
status.changed = true;
}
}
else if (Drupal.settings.fb && Drupal.settings.fb.fbu) {
Dave Cohen
committed
// A user has logged out.
status.changed = true;
}
Dave Cohen
committed
if (status.changed) {
// fbu has changed since server built the page.
jQuery.event.trigger('fb_session_change', status);
// Remember the fbu.
Drupal.settings.fb.fbu = status.fbu;
FB_JS.showConnectedMarkup(status.fbu);
}
Dave Cohen
committed
// edgeCreate is handler for Like button.
FB_JS.edgeCreate = function(href, widget) {
var status = {'href': href};
FB_JS.sessionChangeHandler = function(context, status) {
// Pass data to ajax event.
'event_type': 'session_change',
'is_anonymous': Drupal.settings.fb.is_anonymous
if (status.session) {
Dave Cohen
committed
data.fbu = status.session.userID;
// Suppress facebook-controlled session.
data.fb_session_handoff = true;
// Facebook's PHP SDK should find this. We can't rely on cookies being set.
//data.signed_request = status.response.authResponse.signedRequest;
FB_JS.ajaxEvent(data.event_type, data);
// No need to call window.location.reload(). It will be called from ajaxEvent, if needed.
// Helper to pass events via AJAX.
// A list of javascript functions to be evaluated is returned.
FB_JS.ajaxEvent = function(event_type, request_data) {
if (Drupal.settings.fb.ajax_event_url) {
Dave Cohen
committed
// Session data helpful in ajax callbacks. See fb_settings.inc.
Dave Cohen
committed
// request_data.fb_js_session = JSON.stringify(FB.getSession()); // FB.getSession() FAILS! REMOVE or REPLACE.
Dave Cohen
committed
if (typeof(Drupal.settings.fb_page_type) != 'undefined') {
request_data.fb_js_page_type = Drupal.settings.fb_page_type;
// FB._apikey might be an apikey or might be an appid!
if (FB._apiKey == Drupal.settings.fb.fb_init_settings.appId ||
FB._apiKey == Drupal.settings.fb.fb_init_settings.apiKey) {
Dave Cohen
committed
request_data.apikey = Drupal.settings.fb.fb_init_settings.apiKey; // deprecated
request_data.appId = Drupal.settings.fb.fb_init_settings.appId;
}
// Other values to pass to ajax handler.
if (Drupal.settings.fb.controls) {
request_data.fb_controls = Drupal.settings.fb.controls;
// In case cookies are not accurate, always pass in signed request.
response = FB.getAuthResponse();
if (response) {
request_data.signed_request = response.signedRequest;
}
else {
request_data.signedRequest = '';
}
jQuery.ajax({
url: Drupal.settings.fb.ajax_event_url + '/' + event_type,
data : request_data,
type: 'POST',
dataType: 'json',
success: function(js_array, textStatus, XMLHttpRequest) {
if (js_array.length > 0) {
for (var i = 0; i < js_array.length; i++) {
eval(js_array[i]);
}
}
else {
if (event_type == 'session_change') {
// No instructions from ajax. Notify interested parties
jQuery.event.trigger('fb_session_change_done');
}
}
},
error: function(jqXHR, textStatus, errorThrown) {
Dave Cohen
committed
// Unexpected error (i.e. ajax did not return json-encoded data).
var headers = jqXHR.getAllResponseHeaders(); // debug info.
var responseText = jqXHR.responseText; // debug info.
debugger;
// @TODO: handle error, but how?
}
});
/**
* Called when we first learn the currently logged in user's Facebook ID.
*
* Responsible for showing/hiding markup not intended for the current
* user. Some sites will choose to render pages with fb_connected and
* fb_not_connected classes, rather than reload pages when user's
* connect/disconnect.
*/
FB_JS.showConnectedMarkup = function(fbu, context) {
if (context || fbu != FB_JS.fbu) {
if (fbu) {
FB_JS.fbu = fbu;
// Show markup intended only for connected users.
jQuery('.fb_not_connected', context).hide();
jQuery('.fb_connected', context).show();
}
else {
FB_JS.fbu = null;
// Show markup intended only for not connected users.
jQuery('.fb_connected', context).hide();
jQuery('.fb_not_connected', context).show();
}
}