1/** 2 * @package JFBConnect 3 * @copyright (C) 2009-2018 by Source Coast - All rights reserved 4 * @website http://www.sourcecoast.com/ 5 * @website http://www.sourcecoast.com/joomla-facebook/ 6 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL 7 */ 8 9/** 10 * Ensure global _gaq Google Anlaytics queue has be initialized. 11 * @type {Array} 12 */ 13; 14var _gaq = _gaq || []; 15 16var jfbc = { 17 base: null, 18 return_url: null, 19 token: 't', // have a default, but this should be filled in 20 login: { 21 show_modal: false, 22 scope: null, // Permissions JFBConnect requests 23 logout_facebook: false, 24 logged_in: true, 25 login_started: false, // Prevents multiple concurrent login attempts, mainly caused by the auto-login feature enabled 26 use_popup: true, 27 28 provider: function (name) 29 { 30 if ((name == 'facebook') && jfbc.login.use_popup) 31 { 32 jfbc.debug.log('using popup' + jfbc.login.use_popup); 33 jfbc.login.facebook(); 34 } 35 else 36 self.location = jfbc.base + 'index.php?option=com_jfbconnect&task=authenticate.login&provider=' + name + '&return=' + jfbc.return_url + '&' + jfbc.token + '=1'; 37 }, 38 39 // Special method for Facebook. Should not be called directly in case it changes. Use jfbc.login.provider('facebook') instead 40 facebook: function () 41 { 42 FB.login(function (response) 43 { 44 if (!jfbc.login.logged_in) 45 jfbc.login.facebook_onlogin(); 46 else 47 jfbc.permissions.fetch(); 48 }, { 49 scope: jfbc.login.scope 50 }); 51 }, 52 53 // v5.2 - Move to jfbc.login.provider(xyz) 54 google: function () 55 { 56 jfbc.login.provider('google'); 57 }, 58 59 // Deprecated. Use jfbc.login.login_custom(); 60 login_custom: function () 61 { 62 jfbc.debug.log("jfbc.login.login_custom is deprecated. Please use jfbc.login.provider('facebook') instead"); 63 jfbc.login.provider('facebook'); 64 65 }, 66 67 // Action to perform after authentication on FB has occurred 68 facebook_onlogin: function () 69 { 70 if (!jfbc.login.login_started) 71 { 72 jfbc.login.login_started = true; 73 FB.getLoginStatus(function (response) 74 { 75 if (response.status === 'connected') 76 { 77 jfbcJQuery(document).one("jfbc-permissions-fetched", function () 78 { 79 jfbc.debug.log("Login checks"); 80// if (jfbc.permissions.check('email')) 81// { 82 jfbc.debug.log("Logging in"); 83 if (jfbc.login.show_modal == '1') 84 { 85 // First, hide the SCLogin modal if it's there 86 jfbcJQuery('#login-modal').modal('hide'); 87 jfbcJQuery("#jfbcLoginModal").css({"margin-left": function () 88 { 89 return -(jfbcJQuery("#jfbcLoginModal").width() / 2) 90 }}); 91 jfbcJQuery("#jfbcLoginModal").modal(); 92 } 93 self.location = jfbc.base + 'index.php?option=com_jfbconnect&task=authenticate.login&provider=facebook&return=' + jfbc.return_url + '&' + jfbc.token + '=1'; 94// } 95 jfbc.debug.log("Done with checks"); 96 }); 97 // Start the check_permissions asynchronous check. This will fire the code above. 98 jfbc.permissions.fetch(); 99 } 100 }); 101 } 102 jfbc.login.login_started = false; 103 }, 104 105 logout_button_click: function () 106 { 107 if (jfbc.login.logout_facebook) 108 { 109 FB.getLoginStatus(function (response) 110 { 111 if (response.status === 'connected') 112 { 113 FB.logout(function (response) 114 { 115 jfbcJQuery(document).trigger("jfbc-provider-logout-done"); 116 }); 117 } 118 else 119 { 120 jfbcJQuery(document).trigger("jfbc-provider-logout-done"); 121 } 122 }); 123 } 124 else 125 { 126 jfbcJQuery(document).trigger("jfbc-provider-logout-done"); 127 } 128 }, 129 logout: function (redirect) 130 { 131 jfbcJQuery(document).one("jfbc-provider-logout-done", function () 132 { 133 window.location = jfbc.base + 'index.php?option=com_users&task=user.logout&return=' + redirect + '&' + jfbc.token + '=1'; 134 }); 135 jfbc.login.logout_button_click(); 136 } 137 }, 138 permissions: { 139 // scope: comma-separated list of permissions to check 140 check: function (scope) 141 { 142 var c = jfbc.cookie.get('jfbconnect_permissions_granted'); 143 if (c === null) 144 return false;
145 146 var permissions = []; 147 permissions = jfbcJQuery.parseJSON(c); 148 149 var checkScope = scope.split(','); 150 var scopeFound = true; 151 jfbcJQuery.each(checkScope, function (k, v) 152 { 153 if (jfbcJQuery.inArray(v, permissions) == -1) 154 scopeFound = false; 155 }); 156 return scopeFound; 157 }, 158 159 // Called at initialization 160 // If called independently, use the jfbcJQuery.one("jfbc-permissions-fetched", ..) code to check new values 161 fetch: function () 162 { 163 jfbc.debug.log("permissions_fetch"); 164 165 FB.api('/me/permissions', function (response) 166 { 167 var permissions = ""; 168 if (response.data !== undefined && jfbcJQuery.isArray(response.data)) 169 { 170 jfbcJQuery.each(response.data, function (k, v) 171 { 172 // Check for v2.0 of Graph API 173 if ('permission' in v) 174 { 175 if (v.status == "granted") 176 permissions = permissions + '","' + v.permission; 177 } 178 else 179 { 180 jfbcJQuery.each(v, function (perm, value) 181 { 182 permissions = permissions + '","' + perm; 183 }); 184 } 185 }); 186 // Can't use JSON.stringify as it's incompatible with IE7 :( 187 permissions = permissions + '"'; 188 permissions = permissions.substring(2, permissions.length); 189 190 jfbc.cookie.set('jfbconnect_permissions_granted', "[" + permissions + "]"); 191 } 192 jfbcJQuery(document).trigger("jfbc-permissions-fetched"); 193 }); 194 }, 195 // newScope = comma-separated list of scope to request 196 update_scope: function (newScope) 197 { 198 var jfbcScope = jfbc.login.scope.split(','); 199 newScope = newScope.split(','); 200 newScope = jfbcJQuery.merge(jfbcScope, newScope); 201 newScope = jfbcJQuery.grep(newScope, function (v, k) 202 { // Create a new scope array with no duplicates 203 return jfbcJQuery.inArray(v, newScope) === k; 204 }); 205 jfbc.login.scope = newScope.join(','); 206 jfbc.debug.log("update_scope: Now set to " + jfbc.login.scope); 207 } 208 }, 209 210 social: { 211 facebook: { 212 comment: { 213 create: function (response) 214 { 215 var title = window.btoa(document.title); 216 var url = 'option=com_jfbconnect&task=social.comment&type=create&href=' + encodeURIComponent(escape(response.href)) + '&commentID=' + response.commentID + '&title=' + title; 217 jfbc.util.ajax(url, null); 218 }, 219 remove: function (response) 220 { 221 var title = window.btoa(document.title); 222 var url = 'option=com_jfbconnect&task=social.comment&type=remove&href=' + encodeURIComponent(escape(response.href)) + '&commentID=' + response.commentID + '&title=' + title; 223 jfbc.util.ajax(url, null); 224 } 225 }, 226 }, 227 google: { 228 plusone: function (response) 229 { 230 var type; 231 if (response.state == "on") 232 type = "create"; 233 else if (response.state == "off") 234 type = "remove"; 235 else 236 return; 237 238 var url = 'option=com_jfbconnect&task=social.share&provider=google&share=plusone&type=' + type + '&href=' + encodeURIComponent(escape(response.href)) + '&title=' + document.title; 239 jfbc.util.ajax(url, null); 240 } 241 }, 242 linkedin: { 243 share: function () 244 { 245 var href = document.location.href; 246 var url = 'option=com_jfbconnect&task=social.share&provider=linkedin&share=share&type=create&href=' + encodeURIComponent(escape(href)) + '&title=' + document.title; 247 jfbc.util.ajax(url, null); 248 } 249 }, 250 twitter: { 251 tweet: function (intentEvent) 252 { 253 if (!intentEvent) return; 254// var id = intentEvent.tweet_id; 255// var username = intentEvent.screen_name; 256 var href = document.location.href; 257 var url = 'option=com_jfbconnect&task=social.share&provider=twitter&share=tweet&type=create&href=' + encodeURIComponent(escape(href)) + '&title=' + document.title; 258 jfbc.util.ajax(url, null); 259 } 260 }, 261 /** 262 * Tracks Facebook likes, unlikes and sends by suscribing to the Facebook 263 * JSAPI event model. Note: This will not track facebook buttons using the 264 * iFrame method. 265 */ 266 googleAnalytics: { 267 trackFacebook: function () 268 { 269 var opt_pageUrl = window.location; 270 try 271 { 272 if (FB && FB.Event && FB.Event.subscribe) 273 { 274 FB.Event.subscribe('message.send', function (targetUrl) 275 {
276 _gaq.push(['_trackSocial', 'facebook', 'send', 277 targetUrl, opt_pageUrl]); 278 }); 279 FB.Event.subscribe('comment.create', function (targetUrl) 280 { 281 _gaq.push(['_trackSocial', 'facebook', 'comment', 282 targetUrl, opt_pageUrl]); 283 }); 284 FB.Event.subscribe('comment.remove', function (targetUrl) 285 { 286 _gaq.push(['_trackSocial', 'facebook', 'uncomment', 287 targetUrl, opt_pageUrl]); 288 }); 289 } 290 } 291 catch (e) 292 { 293 } 294 } 295 }, 296 297 // Not published yet. Need to figure out the best way to incorporate this into pages 298 feedPost: function (title, caption, description, url, picture) 299 { 300// javascript:jfbc.social.feedPost('SourceCoast JE', 'My caption', 'Great extensions!', 'http://www.sourcecoast.com/', 'https://www.sourcecoast.com/images/stories/extensions/jfbconnect/home_jfbconn.png'); 301 var obj = { 302 method: 'feed', 303 link: url, 304 picture: picture, 305 name: title, // page title? 306 caption: caption, 307 description: description 308 }; 309 310 function callback(response) 311 { 312 } 313 314 FB.ui(obj, callback); 315 }, 316 317 share: function () 318 { 319 var element = jfbcJQuery('.jfbcsocialshare'); 320 if (!element.length) 321 element = jfbcJQuery('<div class="jfbcsocialshare"></div>').appendTo('body'); 322 jfbcJQuery('.jfbcsocialshare').fadeIn(1000); 323 } 324 }, 325 326 canvas: { 327 checkFrame: function () 328 { 329 if (top == window) 330 { // crude check for any frame 331 if (window.location.search == "") 332 top.location.href = window.location.href + '?jfbcCanvasBreakout=1'; 333 else 334 top.location.href = window.location.href + '&jfbcCanvasBreakout=1'; 335 } 336 } 337 }, 338 339 request: { 340 currentId: null, 341 popup: function (jfbcReqId) 342 { 343 jfbc.request.currentId = jfbcReqId; 344 data = jfbcRequests[jfbcReqId]; 345 FB.ui({method: 'apprequests', display: 'popup', 346 message: data.message, 347 title: data.title, 348 data: jfbcReqId 349 }, jfbc.request.fbCallback); 350 351 }, 352 353 fbCallback: function (response) 354 { 355 if (response != null) 356 { 357 var rId = response.request; 358 var to = response.to; 359 360 var toQuery = ""; 361 for (var i = 0; i < to.length; i++) 362 toQuery += "&to[]=" + to[i]; 363 364 var query = 'option=com_jfbconnect&task=request.requestSent&requestId=' + rId + toQuery + '&jfbcId=' + jfbc.request.currentId; 365 jfbc.util.ajax(query, jfbc.request.redirectToThanks); 366 } 367 }, 368 369 redirectToThanks: function () 370 { 371 data = jfbcRequests[jfbc.request.currentId]; 372 if (data.thanksUrl != "" && (window.location.href != data.thanksUrl)) 373 window.location.href = data.thanksUrl; 374 } 375 }, 376 popup: { 377 display: function (ret) 378 { 379 var deferred = jfbcJQuery.Deferred(); 380 var data = jfbcJQuery.parseJSON(ret); 381 jfbcJQuery(data.target).html(data.html); 382 383 var buttons = {}; 384 if (data.buttons) 385 { 386 for (var i = 0; i < data.buttons.length; i++) 387 { 388 var button = data.buttons[i]; 389 buttons[button.name] = { 390 text: button.name, 391 id: button.id, 392 click: function () 393 { 394 var action = jfbc.get(button.action); 395 action(); 396 } 397 }; 398 } 399 } 400 buttons["Cancel"] = { 401 text: "Cancel", 402 id: 'jfbc-popup-close', 403 click: function () 404 { 405 jfbcJQuery(this).dialog("close"); 406 } 407 }; 408 jfbcJQuery(data.target).dialog({buttons: buttons, title: data.title, 409 width: '50%', 410 close: function () 411 { 412 jfbcJQuery(data.target).html(""); 413 } 414 }); 415 jfbcJQuery(data.target).css('display', 'block'); 416 // Return our promise. This is always resolved (no fail), but need the promise so it can be done after AJAX calls 417 deferred.resolve(); 418 return deferred; 419 } 420 }, 421 422 get: function (prop) 423 { 424 var path = prop.split('.'); 425 var value = window; 426 for (var i = 0; i < path.length; i++) 427 { 428 if (value[path[i]]) 429 value = value[path[i]]; 430 } 431 return value; 432 }, 433 434 util: { 435 thousands_separator: ",", 436 // format an integer such as 1234 to a string with a thousands separator: 1,234 437 format_number: function (num) 438 { 439 return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1" + jfbc.util.thousands_separator); 440 }, 441 encode_data: function (data) 442 { 443 return encodeURIComponent(data).replace(/\-/g, "%2D").replace(/\_/g, "%5F").replace(/\./g, "%2E").replace(/\!/g, "%21").replace(/\~/g, "%7E").replace(/\*/g, "%2A").replace(/\'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29"); 444 }, 445 // Abstracted originally for use in different Mootools libraries. Remains in case future jfbcJQuery changes introduced 446 ajax: function (url, callback) 447 { 448 url = url + '&' + jfbc.token + '=1'; 449 return jfbcJQuery.ajax({url: jfbc.base + 'index.php', data: url}).done(callback); 450 }, 451 452 jqueryUiLoaded: false, 453 loadJQueryUi: function () 454 { 455 if (!jfbc.util.jqueryUiLoaded) 456 { 457 jfbcJQuery.getScript(jfbc.base + "media/sourcecoast/js/jquery-ui.min.js").done(function () 458 { 459 jfbc.util.jqueryUiLoaded = true; 460 }); 461 } 462 } 463 }, 464 debug: { 465 enable: 0, 466 log: function (string) 467 { 468 if (jfbc.debug.enable == 1) 469 console.log("JFBConnect logger: " + string); 470 }, 471 stats: function () 472 { 473 var element = jfbcJQuery('#jfbcAdminStats'); 474 if (!element.length) 475 element = jfbcJQuery('<div id="jfbcAdminStats"></div>').appendTo('body'); 476 jfbcJQuery('#jfbcAdminStats').fadeIn(1000); 477 } 478 }, 479 cookie: { 480 get: function (sKey) 481 { 482 return unescape(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null; 483 }, 484 set: function (sKey, sValue) 485 { 486 if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) 487 { 488 return false;
489 } 490 document.cookie = escape(sKey) + "=" + escape(sValue) + "; path=/"; 491 return true; 492 } 493 }, 494 495 496 init: function () 497 { 498 if (typeof jfbcJQuery == "undefined") 499 { 500 jfbcJQuery = jQuery; 501 jfbc.jqcompat = false; 502 } 503 else 504 jfbc.jqcompat = true; 505 506 if (jfbc.login.logged_in && jfbc.login.logout_facebook) 507 { 508 jfbcJQuery(document).ready(function () 509 { 510 jfbcJQuery(".sclogout-button form").submit(function (e) 511 { 512 e.preventDefault(); 513 jfbcJQuery(document).one("jfbc-provider-logout-done", null, {caller: this }, function (e) 514 { 515 e.data.caller.submit(); 516 }); 517 jfbc.login.logout_button_click(); 518 return false; 519 }); 520 }); 521 } 522 523 524 jfbcJQuery(document).ready(function () 525 { 526 jfbc.social.share(); 527 if (jfbcJQuery('#social-toolbar').length) 528 { 529 jfbc.util.loadJQueryUi(); 530 jfbcJQuery('#social-toolbar button').click(function () 531 { 532 var method = jfbcJQuery(this).attr("name"); 533 jfbc.toolbar[method].display(); 534 }); 535 } 536 }); 537 } 538 539};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.