diff --git a/README.md b/README.md index 16d1d97..d59edf9 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Project documentation is located here : WARNING: Since V0.4.0, _FacebookApp_, _FacebookSdkFilters_ and _FacebookAppService_ from V0.3.* are DEPRECATED and have been replaced by _FacebookContext_. Please check [FacebookContext](http://benorama.github.com/grails-facebook-sdk/guide/facebookContext.html) doc for more info. -* 2012-10-25 **V0.4.3** : channel integration added in fb-init tag +* 2012-10-29 **V0.4.3** : tag lib improvements: channel integration (_initJS_ tag), resources plugin integration (_FacebookSdkResources_ created) * 2012-10-10 **V0.4.2** : bug fix in batch responses error handling * 2012-09-25 **V0.4.1** : bug fix in server side OAuth redirect * 2012-09-25 **V0.4.0** : complete refactoring to improve SDK architecture ([FacebookContext](http://benorama.github.com/grails-facebook-sdk/guide/facebookContext.html) implemented) and [multiple apps support](http://benorama.github.com/grails-facebook-sdk/guide/configuration.html) added diff --git a/grails-app/conf/FacebookSdkResources.groovy b/grails-app/conf/FacebookSdkResources.groovy index e69de29..b2041b5 100644 --- a/grails-app/conf/FacebookSdkResources.groovy +++ b/grails-app/conf/FacebookSdkResources.groovy @@ -0,0 +1,33 @@ +modules = { + + 'fb-sdk-add-to-page-link' { + defaultBundle 'fb-sdk' + resource url: '/js/add-to-page-link.js' + } + + 'fb-sdk-invite-link' { + defaultBundle 'fb-sdk' + resource url: '/js/invite-link.js' + } + + 'fb-sdk-login-link' { + defaultBundle 'fb-sdk' + resource url: '/js/login-link.js' + } + + 'fb-sdk-logout-link' { + defaultBundle 'fb-sdk' + resource url: '/js/logout-link.js' + } + + 'fb-sdk-publish-link' { + defaultBundle 'fb-sdk' + resource url: '/js/publish-link.js' + } + + 'fb-sdk-send-link' { + defaultBundle 'fb-sdk' + resource url: '/js/send-link.js' + } + +} \ No newline at end of file diff --git a/grails-app/taglib/grails/plugin/facebooksdk/FacebookJSTagLib.groovy b/grails-app/taglib/grails/plugin/facebooksdk/FacebookJSTagLib.groovy index c53cbf2..214596a 100644 --- a/grails-app/taglib/grails/plugin/facebooksdk/FacebookJSTagLib.groovy +++ b/grails-app/taglib/grails/plugin/facebooksdk/FacebookJSTagLib.groovy @@ -52,11 +52,12 @@ class FacebookJSTagLib { /** * Add to page link (https://developers.facebook.com/docs/reference/dialogs/add_to_page/) * + * @attr callback Optional javascript function name to call when dialog is confirmed or closed. * @attr disabled Disable click on the link. * @attr display Display mode in which to render the Dialog. Can be page (default), popup, iframe, or touch. * @attr elementClass HTML element 'class' attribute value. * @attr elementId HTML element 'id' attribute value. - * @attr returnUrl Return URL for redirect after login (if not defined page will be reloaded) + * @attr returnUrl Redirect URL after the page is added */ def addToPageLink = {attrs, body -> Map model = [body:body()] @@ -137,6 +138,7 @@ class FacebookJSTagLib { /** * Invite link (https://developers.facebook.com/docs/reference/dialogs/requests/) * + * @attr callback Optional javascript function name to call when dialog is confirmed or closed. * @attr data Additional data you may pass for tracking. The maximum length is 255 characters. * @attr disabled Disable click on the link. * @attr display Display mode in which to render the Dialog. Can be 'page' (default), 'popup', 'iframe', or 'touch'. @@ -160,6 +162,7 @@ class FacebookJSTagLib { /** * Publish link (https://developers.facebook.com/docs/reference/dialogs/feed/) * + * @attr callback Optional javascript function name to call when dialog is confirmed or closed. * @attr disabled Disable click on the link. * @attr display Display mode in which to render the Dialog. Can be page (default), popup, iframe, or touch. * @attr caption The caption of the link (appears beneath the link name). If not specified, this field is automatically populated with the URL of the link. @@ -182,6 +185,7 @@ class FacebookJSTagLib { /** * Send link (https://developers.facebook.com/docs/reference/dialogs/send/) * + * @attr callback Optional javascript function name to call when dialog is confirmed or closed. * @attr disabled Disable click on the link. * @attr display Display mode in which to render the Dialog. Can be page (default), popup, iframe, or touch. * @attr description The description of the link (appears beneath the link caption). If not specified, this field is automatically populated by information scraped from the link, typically the title of the page. diff --git a/grails-app/views/facebook-sdk/_add-to-page-link.gsp b/grails-app/views/facebook-sdk/_add-to-page-link.gsp index 5821bda..f0c2527 100644 --- a/grails-app/views/facebook-sdk/_add-to-page-link.gsp +++ b/grails-app/views/facebook-sdk/_add-to-page-link.gsp @@ -1,11 +1,10 @@ - - - function FBGrailsSDK_addToPage() { - FB.ui({ - 'method':'pagetab' - }, ${callBackJS}); - return false; - } - - -id="${elementId}" class="${elementClass}" href="#" onclick="FBGrailsSDK_addToPage();return false;">${body} \ No newline at end of file + +id="${elementId}" + class="${elementClass} fb-sdk-add-to-page-link" + data-callback="${callback}" + data-display="${display}" + data-return_url="${returnUrl}" + disabled="disabled" + href="#"> + ${body} + \ No newline at end of file diff --git a/grails-app/views/facebook-sdk/_invite-link.gsp b/grails-app/views/facebook-sdk/_invite-link.gsp index 2b004d8..77a278e 100644 --- a/grails-app/views/facebook-sdk/_invite-link.gsp +++ b/grails-app/views/facebook-sdk/_invite-link.gsp @@ -1,20 +1,17 @@ <%@ page import="grails.converters.JSON" %> - - - function FBGrailsSDK_invite() { - FB.ui({ - method: 'apprequests', - message: '${message.encodeAsJavaScript()}' - , data: '${data}' - , 'display':'${display}' - , exclude_ids: '${excludeIds as JSON}' - , filters: ${filters as JSON} - , max_recipients: ${maxRecipients} - , title: '${title.encodeAsJavaScript()}' - , to: '${to}' - }, ${callBackJS}); - return false; - } - - -id="${elementId}" class="${elementClass}" href="#" onclick="FBGrailsSDK_invite();return false;">${body} \ No newline at end of file + +id="${elementId}" + class="${elementClass} fb-sdk-invite-link" + data-message="${message.encodeAsJavaScript()}" + data-callback="${callback}" + data-data="${data}" + data-display="${display}" + data-exclude_ids="${(excludeIds as JSON).toString().replace('"',"'")}" + data-filters="${(filters as JSON).toString().replace('"',"'")}" + data-max_recipients="${maxRecipients}" + data-title="${title.encodeAsJavaScript()}" + data-to="${to}" + disabled="disabled" + href="#"> + ${body} + \ No newline at end of file diff --git a/grails-app/views/facebook-sdk/_login-link.gsp b/grails-app/views/facebook-sdk/_login-link.gsp index 55d8d84..776e60b 100644 --- a/grails-app/views/facebook-sdk/_login-link.gsp +++ b/grails-app/views/facebook-sdk/_login-link.gsp @@ -1,24 +1,10 @@ - - - - - function FBGrailsSDK_login() { - FB.login(function(response) { - if (response.authResponse) { - // user is logged - - window.location.href = "${returnUrl}"; - - - window.location.reload(); - - - } else { - // user cancelled login - window.location.href = "${cancelUrl}"; - - } - }, {scope:"${appPermissions}"}); - } - -id="${elementId}" class="${elementClass}" href="#" onclick="FBGrailsSDK_login();">${body} \ No newline at end of file + +id="${elementId}" + class="${elementClass} fb-sdk-login-link" + data-permissions="${appPermissions instanceof List ? appPermissions.join(',') : appPermissions}" + data-cancel_url="${cancelUrl}" + data-return_url="${returnUrl}" + disabled="disabled" + href="#"> + ${body} + \ No newline at end of file diff --git a/grails-app/views/facebook-sdk/_logout-link.gsp b/grails-app/views/facebook-sdk/_logout-link.gsp index fb58df3..3a9c630 100644 --- a/grails-app/views/facebook-sdk/_logout-link.gsp +++ b/grails-app/views/facebook-sdk/_logout-link.gsp @@ -1,24 +1,8 @@ - - function FBGrailsSDK_logout() { - FB.getLoginStatus(function(response) { - if (response.authResponse) { - FB.logout(function(response) { - - window.location.href = "${nextUrl}"; - - - window.location.reload(); - - }); - } else { - - window.location.href = "${nextUrl}"; - - - window.location.reload(); - - } - }); - } - -id="${elementId}" class="${elementClass}" href="#" onclick="FBGrailsSDK_logout();">${body} \ No newline at end of file + +id="${elementId}" + class="${elementClass} fb-sdk-logout-link" + data-next_url="${nextUrl}" + disabled="disabled" + href="#"> + ${body} + \ No newline at end of file diff --git a/grails-app/views/facebook-sdk/_publish-link.gsp b/grails-app/views/facebook-sdk/_publish-link.gsp index 71d7400..b6cb034 100644 --- a/grails-app/views/facebook-sdk/_publish-link.gsp +++ b/grails-app/views/facebook-sdk/_publish-link.gsp @@ -1,18 +1,15 @@ - - - function FBGrailsSDK_publish() { - FB.ui({ - 'method':'feed' - , 'display':'${display}' - , 'caption':'${caption.encodeAsJavaScript()}' - , 'description':'${description.encodeAsJavaScript()}' - , 'link':'${link}' - , 'name':'${name.encodeAsJavaScript()}' - , 'picture':'${picture}' - , 'source':'${source}' - }, ${callBackJS}); - return false; - } - - -id="${elementId}" class="${elementClass}" href="#" onclick="FBGrailsSDK_publish();return false;">${body} \ No newline at end of file + +id="${elementId}" + class="${elementClass} fb-sdk-publish-link" + data-callback="${callback}" + data-caption="${caption.encodeAsJavaScript()}" + data-display="${display}" + data-description="${description.encodeAsJavaScript()}" + data-link="${link}" + data-name="${name.encodeAsJavaScript()}" + data-picture="${picture}" + data-source="${source}" + disabled="disabled" + href="#"> + ${body} + \ No newline at end of file diff --git a/grails-app/views/facebook-sdk/_send-link.gsp b/grails-app/views/facebook-sdk/_send-link.gsp index 0482b5c..12fd64f 100644 --- a/grails-app/views/facebook-sdk/_send-link.gsp +++ b/grails-app/views/facebook-sdk/_send-link.gsp @@ -1,17 +1,13 @@ - - - function FBGrailsSDK_send() { - FB.ui({ - 'method':'send', - 'to': ${to} - , 'display':'${display}' - , 'description':'${description.encodeAsJavaScript()}' - , 'link':'${link}' - , 'name':'${name.encodeAsJavaScript()}' - , 'picture':'${picture}' - }, ${callBackJS}); - return false; - } - - -id="${elementId}" class="${elementClass}" href="#" onclick="FBGrailsSDK_send();return false;">${body} \ No newline at end of file + +id="${elementId}" + class="${elementClass} fb-sdk-send-link" + data-to="${to}" + data-display="${display}" + data-description="${description.encodeAsJavaScript()}" + data-link="${link}" + data-name="${name.encodeAsJavaScript()}" + data-picture="${picture}" + disabled="disabled" + href="#"> + ${body} + \ No newline at end of file diff --git a/src/docs/guide/introduction.gdoc b/src/docs/guide/introduction.gdoc index f9fa186..42b3344 100644 --- a/src/docs/guide/introduction.gdoc +++ b/src/docs/guide/introduction.gdoc @@ -21,7 +21,7 @@ WARNING: Since V0.4.0, @FacebookApp@, @FacebookSdkFilters@ and @FacebookAppServi Please check [@FacebookContext@|guide:facebookContext] doc for more info. {warning} -* 2012-10-25 *V0.4.3* : channel integration added in fb-init tag +* 2012-10-25 *V0.4.3* : tag lib improvements: channel integration (@initJS@ tag), resources plugin integration (@FacebookSdkResources@ created) * 2012-10-10 *V0.4.2* : bug fix in batch responses error handling * 2012-09-25 *V0.4.1* : bug fix in server side OAuth redirect * 2012-10-25 *V0.4.0* : complete refactoring to improve SDK architecture ([@FacebookContext@|guide:facebookContext] implemented) and [multiple Facebook apps|guide:configuration] support added diff --git a/src/docs/ref/Tags/addToPageLink.gdoc b/src/docs/ref/Tags/addToPageLink.gdoc index 8f612ee..f2ee228 100644 --- a/src/docs/ref/Tags/addToPageLink.gdoc +++ b/src/docs/ref/Tags/addToPageLink.gdoc @@ -10,11 +10,19 @@ The *Add Page Tab* Dialog prompts the user to add an app to a Facebook Page that Add this app to your Facebook Page {code} -To check if the app was successfully added or execute some code, you can use @callBackJS@ attribute. +To check if the app was successfully added or execute some code, you can use @callback@ attribute. {code} + + + callback="someCallbackFunction"> Add to page {code} @@ -26,9 +34,9 @@ You must define the page tab URLs on your app settings to enable this dialog. h3. Attributes Optional attributes are : -* @callBackJS@ Javascript to code to execute on call back (if the user send the form or close the dialog). +* @callback@ Optional javascript function name to call when dialog is confirmed or closed. * @disabled@ Disable click on the link. * @display@ Display mode in which to render the Dialog. Can be page (default for web), touch (default for mobile), popup or iframe. * @elementClass@ HTML element @class@ attribute value. * @elementId@ HTML element @id@ attribute value. - +* @redirectUri@ Redirect URL after the page is added diff --git a/src/docs/ref/Tags/sendLink.gdoc b/src/docs/ref/Tags/sendLink.gdoc index 5fc5a4a..5a2abc9 100644 --- a/src/docs/ref/Tags/sendLink.gdoc +++ b/src/docs/ref/Tags/sendLink.gdoc @@ -7,14 +7,22 @@ Display a link to open "Send Dialog":https://developers.facebook.com/docs/refere The *Send Dialog* lets people to send content to specific friends. They'll have the option to privately share a link as a Facebook message, Group post or email. {code} -Send a link to a friend +Send a link to a friend {code} -To check if the app was successfully added or execute some code, you can use @callBackJS@ attribute. +To check if the app was successfully added or execute some code, you can use @callback@ attribute. {code} + + Send a link to a friend @@ -28,7 +36,7 @@ Required attributes are : * @to@ A user ID or username to which to send the message. Optional attributes are : -* @callBackJS@ Javascript to code to execute on call back (if the user send the form or close the dialog). +* @callback@ Optional javascript function name to call when dialog is confirmed or closed. * @disabled@ Disable click on the link. * @description@ The description of the link (appears beneath the link caption). If not specified, this field is automatically populated by information scraped from the link, typically the title of the page. * @elementClass@ HTML element 'class' attribute value. diff --git a/src/docs/ref/tags/inviteLink.gdoc b/src/docs/ref/tags/inviteLink.gdoc index d83e92a..e461f8c 100644 --- a/src/docs/ref/tags/inviteLink.gdoc +++ b/src/docs/ref/tags/inviteLink.gdoc @@ -10,11 +10,18 @@ The *Request Dialog* sends a Request from one user (the sender) to one or more u Invite your friends {code} -To check if the app was successfully added or execute some code, you can use @callBackJS@ attribute. +To check if the app was successfully added or execute some code, you can use @callback@ attribute. {code} + + Invite your friends @@ -26,7 +33,7 @@ Required attribute is : * @message@ The Request string the receiving user will see. The maximum length is 60 characters. Optional attributes are : -* @callBackJS@ Javascript to code to execute on call back (if the user send the form or close the dialog). +* @callback@ Optional javascript function name to call when dialog is confirmed or closed. * @data@ Additional data you may pass for tracking. The maximum length is 255 characters. * @disabled@ Disable click on the link. * @display@ Display mode in which to render the Dialog. Can be page (default for web), touch (default for mobile), popup or iframe. diff --git a/src/docs/ref/tags/loginLink.gdoc b/src/docs/ref/tags/loginLink.gdoc index efaac81..eefb4f1 100644 --- a/src/docs/ref/tags/loginLink.gdoc +++ b/src/docs/ref/tags/loginLink.gdoc @@ -10,9 +10,27 @@ The *OAuth Dialog* is used within the authentication flows to enable a user to a Login {code} +To handle callback yourself, you can use @callback@ attribute. + +{code} + + + + Login + +{code} + h3. Attributes Optional attributes are : +* @callback@ Optional javascript function name to call when dialog is confirmed or closed. * @appPermissions@ Facebook app permissions/scope. * @cancelUrl@ Cancel URL for redirect if login is canceled (if not defined, nothing happens). * @elementClass@ HTML element @class@ attribute value. diff --git a/src/docs/ref/tags/logoutLink.gdoc b/src/docs/ref/tags/logoutLink.gdoc index 0c0a0f9..c11b9ff 100644 --- a/src/docs/ref/tags/logoutLink.gdoc +++ b/src/docs/ref/tags/logoutLink.gdoc @@ -6,9 +6,26 @@ Display a link to invalidate current user session. Logout {code} +To handle callback yourself, you can use @callback@ attribute. + +{code} + + + + Logout + +{code} + h3. Attributes Optional attributes are : +* @callback@ Optional javascript function name to call when dialog is confirmed or closed. * @elementClass@ HTML element @class@ attribute value. * @elementId@ HTML element @id@ attribute value. * @nextUrl@ Next URL for redirect after logout (if not defined page will be reloaded). \ No newline at end of file diff --git a/src/docs/ref/tags/publishLink.gdoc b/src/docs/ref/tags/publishLink.gdoc index 4a9a247..decf68c 100644 --- a/src/docs/ref/tags/publishLink.gdoc +++ b/src/docs/ref/tags/publishLink.gdoc @@ -10,11 +10,18 @@ The *Feed Dialog* prompts the user to publish an individual story to a profile's Publish {code} -To check if the app was successfully added or execute some code, you can use @callBackJS@ attribute. +To check if the app was successfully added or execute some code, you can use @callback@ attribute. {code} + + + callback="someCallbackFunction"> Publish {code} @@ -22,7 +29,7 @@ To check if the app was successfully added or execute some code, you can use @ca h3. Attributes Optional attributes are : -* @callBackJS@ Javascript to code to execute on call back (if the user send the form or close the dialog). +* @callback@ Optional javascript function name to call when dialog is confirmed or closed. * @disabled@ Disable click on the link. * @display@ Display mode in which to render the Dialog. Can be page (default for web), touch (default for mobile), popup or iframe. * @caption@ The caption of the link (appears beneath the link name). If not specified, this field is automatically populated with the URL of the link. diff --git a/web-app/js/add-to-page-link.js b/web-app/js/add-to-page-link.js index e937c05..110aaef 100644 --- a/web-app/js/add-to-page-link.js +++ b/web-app/js/add-to-page-link.js @@ -1,13 +1,14 @@ -$("a.facebook-sdk-add-to-page").click(function() { +$('a.fb-sdk-add-to-page-link').click(function() { var link = $(this); var options = { - + method: 'pagetab' }; - //if (link.data('data') != undefined) options['data'] = link.data('data'); + if (link.data('display') != undefined) options['display'] = link.data('display'); + if (link.data('return_url') != undefined) options['redirect_uri'] = link.data('return_url'); FB.ui(options, function(response) { if (link.data('callback') != undefined) { var callback = window[link.data('callback')]; - if (typeof fn === 'function') { + if (typeof callback === 'function') { callback(response); } } diff --git a/web-app/js/invite-link.js b/web-app/js/invite-link.js index e69de29..8ed990f 100644 --- a/web-app/js/invite-link.js +++ b/web-app/js/invite-link.js @@ -0,0 +1,23 @@ +$('a.fb-sdk-invite-link').click(function() { + var link = $(this); + var options = { + method: 'apprequests', + message: link.data('message') + }; + if (link.data('data') != undefined) options['data'] = link.data('data'); + if (link.data('display') != undefined) options['display'] = link.data('display'); + if (link.data('exclude_ids') != undefined) options['exclude_ids'] = link.data('exclude_ids'); + if (link.data('filters') != undefined) options['filters'] = link.data('filters'); + if (link.data('max_recipients') != undefined) options['max_recipients'] = link.data('max_recipients'); + if (link.data('title') != undefined) options['title'] = link.data('title'); + if (link.data('to') != undefined) options['to'] = link.data('to'); + FB.ui(options, function(response) { + if (link.data('callback') != undefined) { + var callback = window[link.data('callback')]; + if (typeof callback === 'function') { + callback(response); + } + } + }); + return false; +}); \ No newline at end of file diff --git a/web-app/js/login-link.js b/web-app/js/login-link.js index e69de29..24bc35b 100644 --- a/web-app/js/login-link.js +++ b/web-app/js/login-link.js @@ -0,0 +1,27 @@ +$('a.fb-sdk-login-link').click(function() { + var link = $(this); + link.attr('disabled', 'disabled'); + FB.login(function(response) { + if (link.data('callback') != undefined) { + var callback = window[link.data('callback')]; + if (typeof fn === 'function') { + callback(response); + } + } else if (response.authResponse) { + // user is logged + if (link.data('return_url')) { + window.location.href = link.data('return_url'); + } else { + window.location.reload(); + } + } else if (link.data('cancel_url')) { + window.location.href = link.data('cancel_url'); + } else { + link.removeAttr('disabled'); + } + }, { + scope: link.data('permissions') + }); + return false; +}); + diff --git a/web-app/js/logout-link.js b/web-app/js/logout-link.js index e69de29..472c6e6 100644 --- a/web-app/js/logout-link.js +++ b/web-app/js/logout-link.js @@ -0,0 +1,33 @@ +$('a.fb-sdk-logout-link').click(function() { + var link = $(this); + link.attr('disabled', 'disabled'); + FB.getLoginStatus(function(response) { + if (response.authResponse) { + FB.logout(function(response) { + if (link.data('callback') != undefined) { + var callback = window[link.data('callback')]; + if (typeof fn === 'function') { + callback(response); + } + } else if (link.data('next_url')) { + window.location.href = link.data('next_url'); + } else { + window.location.reload(); + } + }); + } else { + if (link.data('callback') != undefined) { + var callback = window[link.data('callback')]; + if (typeof callback === 'function') { + callback(response); + } + } else if (link.data('next_url')) { + window.location.href = link.data('next_url'); + } else { + window.location.reload(); + } + } + }); + return false; +}); + diff --git a/web-app/js/publish-link.js b/web-app/js/publish-link.js index e69de29..821956b 100644 --- a/web-app/js/publish-link.js +++ b/web-app/js/publish-link.js @@ -0,0 +1,22 @@ +$('a.fb-sdk-publish-link').click(function() { + var link = $(this); + var options = { + method: 'feed' + }; + if (link.data('caption') != undefined) options['caption'] = link.data('caption'); + if (link.data('display') != undefined) options['display'] = link.data('display'); + if (link.data('description') != undefined) options['description'] = link.data('description'); + if (link.data('link') != undefined) options['link'] = link.data('link'); + if (link.data('name') != undefined) options['name'] = link.data('name'); + if (link.data('picture') != undefined) options['picture'] = link.data('picture'); + if (link.data('source') != undefined) options['source'] = link.data('source'); + FB.ui(options, function(response) { + if (link.data('callback') != undefined) { + var callback = window[link.data('callback')]; + if (typeof callback === 'function') { + callback(response); + } + } + }); + return false; +}); \ No newline at end of file diff --git a/web-app/js/send-link.js b/web-app/js/send-link.js index e69de29..82940de 100644 --- a/web-app/js/send-link.js +++ b/web-app/js/send-link.js @@ -0,0 +1,21 @@ +$('a.fb-sdk-send-link').click(function() { + var link = $(this); + var options = { + method: 'send', + link: link.data('link'), + to: link.data('to') + }; + if (link.data('display') != undefined) options['display'] = link.data('display'); + if (link.data('description') != undefined) options['description'] = link.data('description'); + if (link.data('name') != undefined) options['name'] = link.data('name'); + if (link.data('picture') != undefined) options['picture'] = link.data('picture'); + FB.ui(options, function(response) { + if (link.data('callback') != undefined) { + var callback = window[link.data('callback')]; + if (typeof callback === 'function') { + callback(response); + } + } + }); + return false; +}); \ No newline at end of file