PageRenderTime 26ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/backbone.api.facebook.js

https://gitlab.com/intruxxer/facebook
JavaScript | 506 lines | 329 code | 70 blank | 107 comment | 52 complexity | 78514b6cee4e69da83b9bf5cd356395b MD5 | raw file
  1. /* Backbone API: Facebook
  2. * Source: https://github.com/backbone-api/facebook
  3. *
  4. * Created by Makis Tracend (@tracend)
  5. * Distributed through [Makesites.org](http://makesites.org)
  6. * Released under the [MIT license](http://makesites.org/licenses/MIT)
  7. */
  8. // Assuming that Facebook JS lib is loaded...
  9. if( window.FB ) (function(_, Backbone) {
  10. // Constants
  11. var api = "https://graph.facebook.com";
  12. // Base model - mainly used for setup options
  13. var Facebook = new Backbone.Model({
  14. api: api,
  15. appId: false,
  16. uri: false
  17. });
  18. // Namespace definition
  19. Facebook.Models = {};
  20. Facebook.Collections = {};
  21. Facebook.Views = {};
  22. // Helpers
  23. // Sync method
  24. var Sync = function(method, model, options) {
  25. var url = (this.url instanceof Function) ? this.url() : this.url;
  26. var params = {};
  27. // add access token if available
  28. var token = this.getToken();
  29. if( token ){
  30. if( url instanceof Object) { url["access_token"] = token; }
  31. else { url += ( url.search(/\?/) > -1 ) ? "&access_token="+ token : "?access_token="+ token; }
  32. }
  33. //FB.api(url, method, params, function( response ) {
  34. FB.api(url, method, function( response ) {
  35. // save response.paging for later?
  36. // send just the response.data:
  37. var data = response.data || response;
  38. options.success( data );
  39. });
  40. };
  41. var getToken = function(){
  42. // first priority have the local options
  43. if( this.options && this.options.access_token) return this.options.access_token;
  44. // after that the internal token
  45. if( !_.isUndefined( token.get("accessToken") ) ) return token.get("accessToken");
  46. // no token
  47. return false;
  48. }
  49. // Models
  50. // - Main Constructor
  51. var Model = Backbone.Model.extend({
  52. // available options
  53. options : {
  54. access_token : false
  55. },
  56. initialize: function(model, options){
  57. // fallbacks
  58. options = options || {};
  59. this.options = _.extend(this.options, options);
  60. //return Backbone.Model.prototype.initialize.apply(this, arguments);
  61. // auto-fetch if requested...
  62. if( options.fetch ){
  63. this.fetch();
  64. }
  65. },
  66. fetch : function(method, model, options) {
  67. var self = this;
  68. if( this.getToken() ){
  69. // we'll be using the supplied access token
  70. Backbone.Model.prototype.fetch.call( self );
  71. } else {
  72. FB.getLoginStatus(function(response){
  73. if( response.status == "connected" ){
  74. // save token
  75. token.set( response.authResponse );
  76. // continue with request
  77. Backbone.Model.prototype.fetch.call( self );
  78. }
  79. // else try to FB.Login?
  80. });
  81. }
  82. },
  83. sync: Sync,
  84. getToken: getToken
  85. });
  86. //
  87. Facebook.Models.User = Model.extend({
  88. defaults : {
  89. //installed : true
  90. }
  91. });
  92. Facebook.Models.Feed = Model.extend({
  93. defaults : {}
  94. });
  95. Facebook.Models.Post = Model.extend({
  96. defaults : {
  97. method: "feed",
  98. link: "",
  99. picture: "",
  100. name: "",
  101. caption: "",
  102. description: ""
  103. }
  104. });
  105. Facebook.Models.Page = Model.extend({
  106. defaults : {
  107. method: "oauth",
  108. client_id: false,
  109. redirect_uri: ""
  110. },
  111. isFan: function( uid ){
  112. uid = uid || "me()";
  113. return (new isFan({ id : this.id, uid : uid }) ).fetch();
  114. }
  115. });
  116. Facebook.Models.Tab = Model.extend({
  117. url: function(){ return Facebook.get("api") + "/"+ this.page +"/tabs/app_"+ this.id },
  118. defaults : {},
  119. initialize: function( data, options ){
  120. this.page = data.page;
  121. this.id = Facebook.get("appId");
  122. }
  123. });
  124. //
  125. Facebook.Models.Link = Model.extend({
  126. defaults : {
  127. url: window.location.href,
  128. normalized_url: "",
  129. share_count: 0,
  130. like_count: 0,
  131. comment_count: 0,
  132. total_count: 0,
  133. commentsbox_count: 0,
  134. comments_fbid: 0,
  135. click_count: 0
  136. },
  137. url: function(){
  138. return {
  139. method: 'fql.query',
  140. query: "SELECT url,normalized_url,share_count,like_count,comment_count,total_count,commentsbox_count,comments_fbid,click_count FROM link_stat WHERE url ='"+ this.get("url") +"'"
  141. }
  142. },
  143. parse: function( response ){
  144. // error control?
  145. if( response instanceof Array ){
  146. // use only the first item
  147. return response.shift();
  148. } else {
  149. return response;
  150. }
  151. }
  152. });
  153. Facebook.Models.Login = Model.extend({
  154. defaults : {
  155. method: "oauth",
  156. client_id: false, //fb_appId
  157. //display: "popup",
  158. //response_type: "token"
  159. //redirect_uri: "" //https://apps.facebook.com/'+ fb_uri +'/'
  160. }
  161. });
  162. Facebook.Models.AddToPage = Model.extend({
  163. defaults : {
  164. method: 'pagetab',
  165. //redirect_uri: '', //https://apps.facebook.com/{{fb_uri}}/
  166. }
  167. });
  168. // Me is an extension of the user
  169. Facebook.Models.Me = Facebook.Models.User.extend({
  170. url : function(){ return Facebook.get("api") + "/me"; },
  171. defaults : {
  172. id : "me"
  173. },
  174. // defaultOptions: {
  175. options : {
  176. auth: false,
  177. // see https://developers.facebook.com/docs/authentication/permissions/
  178. scope: [], // fb permissions
  179. autosync: true, // auto fetch profile after login
  180. protocol: location.protocol
  181. },
  182. oauth: null,
  183. initialize: function(){
  184. var self = this;
  185. FB.Event.subscribe('auth.authResponseChange', function(e){ self.onLoginStatusChange(e) });
  186. return Backbone.API.Facebook.Models.User.prototype.initialize.apply(this, arguments);
  187. },
  188. login: function(callback){
  189. callback = callback || function() {};
  190. FB.login(callback, { scope: this.options.scope.join(',') });
  191. },
  192. logout: function(){
  193. FB.logout();
  194. },
  195. onLoginStatusChange: function(response) {
  196. // only execute once?
  197. if(this.options.auth === response.status) return false;
  198. var event;
  199. if(response.status === 'not_authorized') {
  200. event = 'facebook:unauthorized';
  201. // login logic
  202. } else if (response.status === 'connected') {
  203. event = 'facebook:connected';
  204. // save request for later...
  205. this.request = FB.getAuthResponse();
  206. // copy access token
  207. this.oauth = {
  208. access_token : this.request.accessToken,
  209. expiry : (new Date).getTime() + this.request.expiresIn
  210. };
  211. if(this.options.autosync === true) this.fetch();
  212. } else {
  213. event = 'facebook:disconnected';
  214. }
  215. this.trigger(event, this, response);
  216. this.options.auth = response.status;
  217. }
  218. });
  219. Facebook.Models.WebPage = Model.extend({
  220. defaults : {
  221. "shares": 0,
  222. "comments": 0,
  223. "type": "website",
  224. "is_scraped": false
  225. },
  226. options: {
  227. },
  228. url: function(){ return Facebook.get("api") +"/?ids="+ this.options.page },
  229. parse: function( data ){
  230. // data arrives in a sub-object with the URL as the key
  231. var model = {};
  232. // - pick the first element regardless of key
  233. for(var key in data ){
  234. model = data[key];
  235. break; // "break" because this is a loop
  236. }
  237. data = model;
  238. return data;
  239. }
  240. });
  241. // Collections
  242. // - Main Constructor
  243. var Collection = Backbone.Collection.extend({
  244. // available options
  245. options : {
  246. access_token : false
  247. },
  248. initialize: function(model, options){
  249. // fallbacks
  250. options = options || {};
  251. this.options = _.extend(this.options, options);
  252. //return Backbone.Collection.prototype.initialize.apply(this, arguments);
  253. // auto-fetch if requested...
  254. if( options.fetch ){
  255. this.fetch();
  256. }
  257. },
  258. fetch : function(method, model, options) {
  259. var self = this;
  260. if( this.getToken() ){
  261. // we'll be using the supplied access token
  262. Backbone.Collection.prototype.fetch.call( self );
  263. } else {
  264. FB.getLoginStatus(function(response){
  265. if( response.status == "connected" ){
  266. // save token
  267. token.set( response.authResponse );
  268. // continue with request
  269. Backbone.Collection.prototype.fetch.call( self );
  270. }
  271. // else try to FB.Login?
  272. });
  273. }
  274. },
  275. sync : Sync,
  276. parse : function( response ){
  277. //console.log("facebook data:", response );
  278. //is uid always the id? apparently...
  279. var data = _.map(response, function( result ){
  280. if( result.uid ){
  281. result.id = result.uid;
  282. delete result.uid;
  283. }
  284. return result;
  285. });
  286. return data;
  287. },
  288. getToken: getToken
  289. });
  290. //
  291. Facebook.Collections.Friends = Collection.extend({
  292. model : Backbone.API.Facebook.Models.User,
  293. url: function(){
  294. return {
  295. method: 'fql.query',
  296. query: 'Select name, uid from user where is_app_user = 1 and uid in (select uid2 from friend where uid1 = me()) order by concat(first_name,last_name) asc'
  297. }
  298. }
  299. });
  300. Facebook.Collections.Feed = Collection.extend({
  301. // examples options:
  302. options: {
  303. //access_token : config.facebook.access_token
  304. },
  305. model : Backbone.API.Facebook.Models.Feed,
  306. url: function(){
  307. // creating an object of parameters
  308. var params = {
  309. method: 'fql.query',
  310. query: "select message,description,attachment,created_time from stream where source_id ='"+ this.id +"' limit "+ this.num,
  311. }
  312. // add access token if available
  313. if( this.options.access_token ){
  314. // we'll be using the supplied access token
  315. params["access_token"] = this.options.access_token;
  316. }
  317. return params;
  318. // old...
  319. // check if there is either an id or user set - fallback to 'me'
  320. //var page = this.user || this.id || "me";
  321. //return "/"+ page +"/feed?limit="+ this.num;
  322. },
  323. initialize: function( model, options){
  324. // parameters
  325. this.id = options.id || false;
  326. this.user = options.user || null;
  327. this.num = options.num || 10;
  328. // auto-fetch if requested...
  329. if( options.fetch ){
  330. this.fetch();
  331. }
  332. }
  333. });
  334. // Views
  335. // - Main Constructor
  336. var View = Backbone.View.extend({
  337. template : FB.ui,
  338. initialize: function( options ){
  339. // fallback
  340. options = options || {};
  341. if( options.callback ) this.callback = options.callback;
  342. // load the parent?
  343. //
  344. // fincally, render the view
  345. return this.render();
  346. },
  347. render : function(){
  348. this.template( this.model.toJSON(), this.callback );
  349. // preserve chainability?
  350. return this;
  351. },
  352. callback : function(){
  353. }
  354. });
  355. //
  356. Facebook.Views.Post = View.extend({
  357. callback : function(response) {
  358. //document.getElementById('msg').innerHTML = "Post ID: " + response['post_id'];
  359. }
  360. });
  361. Facebook.Views.Login = View.extend({
  362. initialize: function( options ){
  363. //
  364. this.model = new Backbone.API.Facebook.Models.Login({
  365. client_id: Backbone.API.Facebook.get("appId"), //fb_appId
  366. //redirect_uri: "https://apps.facebook.com/"+ Backbone.API.Facebook.get("uri") +'/'
  367. });
  368. // load the parent?
  369. //
  370. return View.prototype.initialize.call( this, options );
  371. },
  372. callback : function (response) {
  373. if( typeof( response ) != "undefined") {
  374. if(response.session) {
  375. //var user = JSON.parse(response.session);
  376. // save the userid in the form
  377. //$("#entry-form").find("input[name='fbid']").val(user.uid);
  378. top.location.href = this.model.get("redirect_uri");
  379. } else {
  380. // No session
  381. //top.location.href = 'http://facebook.com/';
  382. console.log("no session");
  383. window.location.reload();
  384. }
  385. } else {
  386. // denied access
  387. console.log("denied access");
  388. //top.location.href = tab.host;
  389. }
  390. }
  391. });
  392. Facebook.Views.AddToPage = View.extend({
  393. initialize: function( options ){
  394. //
  395. this.model = new Backbone.API.Facebook.Models.AddToPage();
  396. // load the parent?
  397. //
  398. return View.prototype.initialize.call( this, options );
  399. }
  400. });
  401. // Internal
  402. // - internal access token
  403. // Note: Always ask for the user_likes permission before calling any of the above to make sure you get a correct result
  404. var Token = Backbone.Model.extend({
  405. });
  406. // - isFan method
  407. // Note: Always ask for the user_likes permission before calling any of the above to make sure you get a correct result
  408. var isFan = Model.extend({
  409. url : function(){
  410. // alternate 'plain' url
  411. // "/"+ this.options.uid +"/likes/"+ this.options.id
  412. return {
  413. method: 'fql.query',
  414. query: 'select uid from page_fan where uid='+ this.options.uid +' and page_id='+ this.options.id
  415. }
  416. },
  417. parse: function( response ){
  418. // check if there is a data response
  419. return { fan : !(_.isEmpty(response.data) ) };
  420. }
  421. });
  422. // init token
  423. var token = new Token();
  424. // Store in selected namespace(s)
  425. if( _.isUndefined(Backbone.API) ) Backbone.API = {};
  426. Backbone.API.Facebook = Facebook;
  427. // - alias APP.API
  428. if( typeof APP != "undefined" && (_.isUndefined( APP.API) || _.isUndefined( APP.API.Facebook) ) ){
  429. APP.API = APP.API || {};
  430. APP.API.Facebook = Facebook;
  431. }
  432. // - Shortcut
  433. if(typeof window.Facebook == "undefined"){
  434. window.Facebook = Facebook;
  435. }
  436. })(this._, this.Backbone);