facebook-social_plugins 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/AddToTimeline.txt +49 -0
  4. data/Gemfile +15 -0
  5. data/Gemfile.lock +121 -0
  6. data/LICENSE.txt +20 -0
  7. data/README.rdoc +277 -0
  8. data/Rakefile +49 -0
  9. data/VERSION +1 -0
  10. data/facebook-social_plugins.gemspec +93 -0
  11. data/lib/facebook-social_plugins.rb +22 -0
  12. data/lib/facebook-social_plugins/activity_feed.rb +35 -0
  13. data/lib/facebook-social_plugins/add_to_timeline.rb +18 -0
  14. data/lib/facebook-social_plugins/button.rb +18 -0
  15. data/lib/facebook-social_plugins/comments.rb +20 -0
  16. data/lib/facebook-social_plugins/facepile.rb +37 -0
  17. data/lib/facebook-social_plugins/like_box.rb +28 -0
  18. data/lib/facebook-social_plugins/like_button.rb +51 -0
  19. data/lib/facebook-social_plugins/live_stream.rb +21 -0
  20. data/lib/facebook-social_plugins/login_button.rb +26 -0
  21. data/lib/facebook-social_plugins/rails/engine.rb +10 -0
  22. data/lib/facebook-social_plugins/recommendations_box.rb +41 -0
  23. data/lib/facebook-social_plugins/registration.rb +52 -0
  24. data/lib/facebook-social_plugins/script_helper.rb +48 -0
  25. data/lib/facebook-social_plugins/send_button.rb +24 -0
  26. data/lib/facebook-social_plugins/social_plugin.rb +84 -0
  27. data/lib/facebook-social_plugins/subscribe_button.rb +27 -0
  28. data/lib/facebook-social_plugins/ui_helper.rb +10 -0
  29. data/lib/facebook-social_plugins/view_helper.rb +56 -0
  30. data/spec/facebook-social_plugins/script_helper_spec.rb +55 -0
  31. data/spec/facebook-social_plugins/view_helper_spec.rb +113 -0
  32. data/spec/spec_helper.rb +47 -0
  33. data/vendor/assets/html/facebook_channel.html +1 -0
  34. metadata +211 -0
@@ -0,0 +1,41 @@
1
+ module FacebookSocialPlugins
2
+ class RecommendationsBox < SocialPlugin
3
+ def initialize options = {}
4
+ super
5
+ end
6
+
7
+ def plugin_class
8
+ 'fb-recommendations'
9
+ end
10
+
11
+ # site - the domain to show recommendations for. The XFBML version defaults to the current domain.
12
+ # action - a comma separated list of actions to show recommendations for.
13
+ # app_id - will display recommendations for all types of actions, custom and global, associated with this app_id.
14
+ # width - the width of the plugin in pixels. Default width: 300px.
15
+ # height - the height of the plugin in pixels. Default height: 300px.
16
+ # header - specifies whether to show the Facebook header.
17
+ # colorscheme - the color scheme for the plugin. Options: 'light', 'dark'
18
+ # font - the font to display in the plugin. Options: 'arial', 'lucida grande', 'segoe ui', 'tahoma', 'trebuchet ms', 'verdana'
19
+ # border_color - the border color of the plugin.
20
+
21
+ # linktarget - This specifies the context in which content links are opened.
22
+ # By default all links within the plugin will open a new window.
23
+ # If you want the content links to open in the same window, you can set this parameter
24
+ # to _top or _parent. Links to Facebook URLs will always open in a new window.
25
+
26
+ # ref - a label for tracking referrals; must be less than 50 characters and can contain
27
+ # alphanumeric characters and some punctuation (currently +/=-.:_).
28
+ # Specifying a value for the ref attribute adds the 'fb_ref' parameter to the any links back to your site
29
+ # which are clicked from within the plugin. Using different values for the ref parameter for different positions
30
+ # and configurations of this plugin within your pages allows you to track which instances are performing the best.
31
+
32
+ # max_age - a limit on recommendation and creation time of articles that are surfaced in
33
+ # the plugins, the default is 0 (we don’t take age into account).
34
+ # Otherwise the valid values are 1-180, which specifies the number of days.
35
+ def attributes
36
+ super.merge(:site => :string, :action => :string, :app_id => :string, :height => :integer,
37
+ :header => :string, :linktarget => ['_top', '_parent'], :ref => :string,
38
+ :max_age => :integer, :width => :integer)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,52 @@
1
+ module FacebookSocialPlugins
2
+ class Registration < SocialPlugin
3
+ attr_reader :named_fields
4
+
5
+ # <fb:registration
6
+ # fields="name,birthday,gender,location,email"
7
+ # redirect-uri="https://developers.facebook.com/tools/echo/"
8
+ # width="530">
9
+ # </fb:registration>
10
+
11
+ def initialize options = {}
12
+ super
13
+ @named_fields = options[:fields]
14
+ end
15
+
16
+ def plugin_class
17
+ 'fb-registration'
18
+ end
19
+
20
+ # client_id Your App ID.
21
+ # redirect_uri The URI that will process the signed_request. It must be prefixed by your Site URL.
22
+ # fields Comma separated list of Named Fields, or JSON of Custom Fields.
23
+ # fb_only Optional. (boolean) Only allow users to register by linking their Facebook profile. Use this if you do not have your own registration system. Default: false.
24
+ # fb_register Optional. (boolean) Allow users to register for Facebook during the registration process. Use this if you do not have your own registration system. Default: false.
25
+ # width Optional. (int) The width of the iframe in pixels. If the width is < 520 the plugin will render in a small layout.
26
+ # border_color Optional. The border color of the plugin.
27
+ # target Optional. The target of the form submission: _top (default), _parent, or _self.
28
+ def attributes
29
+ super.merge(:client_id => :string, :redirect_uri => :string, :fields => :string,
30
+ :fb_only => :boolean, :fb_register => :boolean, :border_color => :string, :target => ['_top', '_parent', '_self']
31
+ )
32
+ end
33
+
34
+ # Named Fields
35
+
36
+ # Specify these in the order you want them to appear in the form. The name field must always be the first field.
37
+
38
+ # Field type Description
39
+ # name Full name of the user
40
+ # birthday Returned as mm/dd/yyyy
41
+ # email Email address of user (if the user registers with her Facebook account, this will be a verified email address)
42
+ # gender Gender of user
43
+ # location Name and ID of the user's current city
44
+ # password A newly created password (not their Facebook password)
45
+ # captcha A test to stop automatic registration
46
+ # Less common fields:
47
+
48
+ # Field type Description
49
+ # first_name The first name of the user. Useful with view=not_prefilled.
50
+ # last_name The last name of the user.
51
+ end
52
+ end
@@ -0,0 +1,48 @@
1
+ module FacebookSocialPlugins
2
+ module ScriptHelper
3
+
4
+ # app_id - facebook app id, a number/string, fx '753632322'
5
+ # domain - fx www.example.com
6
+ # options - status, cookie, xfbml (true|false)
7
+ # - :channel => 'channel.html'
8
+ def async_init_script app_id, domain, options = {}
9
+ %Q{
10
+ window.fbAsyncInit = function() {
11
+ FB.init({
12
+ appId : '#{app_id}', // App ID
13
+ channelUrl : '//#{domain}/#{options[:channel] || 'assets/facebook_channel'}.html', // Channel File
14
+ status : #{options[:status] || true}, // check login status
15
+ cookie : #{options[:cookie] || true}, // enable cookies to allow the server to access the session
16
+ xfbml : #{options[:xfbml] || true } // parse XFBML
17
+ });
18
+
19
+ // Additional initialization code here
20
+ };
21
+ }
22
+ end
23
+
24
+ def facebook_script locale = :en_US
25
+ %Q{
26
+ (function(d){
27
+ var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
28
+ js = d.createElement('script'); js.id = id; js.async = true;
29
+ js.src = "#{all_script locale}";
30
+ d.getElementsByTagName('head')[0].appendChild(js);
31
+ }(document));
32
+ }
33
+ end
34
+
35
+ protected
36
+
37
+ # The JavaScript SDK is available in all locales that are supported by Facebook.
38
+ # This list of supported locales is available as an XML file.
39
+ # To change the locale of the SDK to match the locale of your site, change en_US to a
40
+ # supported locale code when loading the SDK.
41
+ # For example, if your site is in Spanish use es_LA
42
+
43
+
44
+ def all_script locale = :en_US
45
+ "//connect.facebook.net/#{locale}/all.js"
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ module FacebookSocialPlugins
2
+ class SendButton < Button
3
+ def initialize options = {}
4
+ super
5
+ end
6
+
7
+ def plugin_class
8
+ 'fb-send'
9
+ end
10
+
11
+ # href - the URL to send.
12
+ # font - the font to display in the button. Options: 'arial', 'lucida grande', 'segoe ui', 'tahoma', 'trebuchet ms', 'verdana'
13
+ # colorscheme - the color scheme for the button. Options: 'light', 'dark'
14
+ # ref - a label for tracking referrals; must be less than 50 characters and can contain alphanumeric characters and some punctuation (currently +/=-.:_). The ref attribute causes two parameters to be added to the referrer URL when a user clicks a link from a stream story about a Send action:
15
+ # fb_ref - the ref parameter
16
+ # fb_source - the story type ('message', 'group', 'email') in which the click occurred.
17
+ def attributes
18
+ super.merge(:href => :string, :ref => :string, :fb_ref => :string,
19
+ :fb_source => ['message', 'group', 'email']
20
+ )
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,84 @@
1
+ require 'facebook-social_plugins/ui_helper'
2
+
3
+ module FacebookSocialPlugins
4
+ class SocialPlugin < UiHelper
5
+
6
+ attr_reader :options
7
+
8
+ def initialize options = {}
9
+ @options = options
10
+ validate!
11
+ end
12
+
13
+ def render
14
+ content_tag :div, '', render_options.merge(:class => plugin_class)
15
+ end
16
+
17
+ # the :special type indicates call to special type validator
18
+ def validate!
19
+ return if options.empty?
20
+ valid_options = {}
21
+ options.each do |key, value|
22
+ attr_key = find_att_key(key)
23
+ raise ArgumentError, "Unknown or unsupported attribute #{key}" unless attr_key
24
+ attributes[attr_key] == :special ? send("validate_#{key.to_s.underscore}", value) : valid?(value, attributes[attr_key])
25
+ valid_options[attr_key] = value
26
+ end
27
+ @options = valid_options
28
+ end
29
+
30
+ protected
31
+
32
+ def find_att_key key
33
+ return key if attributes[key]
34
+ key = key.to_s.dasherize.to_sym
35
+ return key if attributes[key]
36
+ key = key.to_s.underscore.to_sym
37
+ key if attributes[key]
38
+ end
39
+
40
+ # :width => 200 mapped to become 'data-width' => 200
41
+ def render_options
42
+ options.inject({}) {|res, opt| res["data-#{opt.first}"] = opt.last; res}
43
+ end
44
+
45
+ def plugin_class
46
+ raise NotImplementedError, 'Must be implemented by subclass'
47
+ end
48
+
49
+ def attributes
50
+ @attributes ||= {}
51
+ end
52
+
53
+ def valid? value, valid_type
54
+ case valid_type
55
+ when :string
56
+ raise ArgumentError, "Must be a String, was #{value}" unless string?(value)
57
+ when :array
58
+ raise ArgumentError, "Must be an Array or a String, was #{value}" unless array?(value)
59
+ when :integer
60
+ raise ArgumentError, "Must be a Fixnum, was #{value}" unless integer?(value)
61
+ when :boolean
62
+ raise ArgumentError, "Must be a Boolean, was #{value}" unless boolean?(value)
63
+ when Array
64
+ raise ArgumentError, "Must be a one of #{valid_type.inspect}, was #{value}" unless valid_type.include?(value.to_s)
65
+ end
66
+ end
67
+
68
+ def string? value
69
+ value.is_a?(String) || value.is_a?(Symbol)
70
+ end
71
+
72
+ def array? value
73
+ value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(Array)
74
+ end
75
+
76
+ def integer? value
77
+ value.is_a?(Fixnum) && value > 0
78
+ end
79
+
80
+ def boolean? value
81
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,27 @@
1
+ module FacebookSocialPlugins
2
+ class SubscribeButton < Button
3
+ def initialize options = {}
4
+ super
5
+ end
6
+
7
+ def plugin_class
8
+ 'fb-subscribe'
9
+ end
10
+
11
+ # href - profile URL of the user to subscribe to. This must be a facebook.com profile URL.
12
+ # layout - there are three options.
13
+ # standard - displays social text to the right of the button and friends' profile photos below. Minimum width: 225 pixels. Default width: 450 pixels. Height: 35 pixels (without photos) or 80 pixels (with photos).
14
+ # button_count - displays the total number of subscribers to the right of the button. Minimum width: 90 pixels. Default width: 90 pixels. Height: 20 pixels.
15
+ # box_count - displays the total number of subscribers above the button. Minimum width: 55 pixels. Default width: 55 pixels. Height: 65 pixels.
16
+ # show_faces - specifies whether to display profile photos below the button (standard layout only)
17
+ # colorscheme - the color scheme for the plugin. Options: 'light' (default) and 'dark'
18
+ # font - the font to display in the plugin. Options: 'arial', 'lucida grande', 'segoe ui', 'tahoma', 'trebuchet ms', 'verdana'
19
+ # width - the width of the plugin.
20
+ def attributes
21
+ super.merge(:href => :string, :layout => ['standard', 'button_count', 'box_count'],
22
+ :show_faces => :boolean, :width => :integer)
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -0,0 +1,10 @@
1
+ module FacebookSocialPlugins
2
+ class UiHelper
3
+ include ActionView::Helpers::TagHelper,
4
+ ActionView::Helpers::UrlHelper,
5
+ ActionView::Helpers::CaptureHelper,
6
+ ActionView::Helpers::JavaScriptHelper
7
+
8
+ attr_accessor :html, :javascript
9
+ end
10
+ end
@@ -0,0 +1,56 @@
1
+ module FacebookSocialPlugins
2
+ module ViewHelper
3
+ def fb_root
4
+ content_tag :div, :class => "fb-root"
5
+ end
6
+
7
+ def fb_activity_feed options = {}
8
+ FacebookSocialPlugins::ActivityFeed.new(options).render
9
+ end
10
+
11
+ def fb_add_to_timeline options = {}
12
+ FacebookSocialPlugins::AddToTimeline.new(options).render
13
+ end
14
+
15
+ def fb_comments options = {}
16
+ FacebookSocialPlugins::Comments.new(options).render
17
+ end
18
+
19
+ def fb_facepile options = {}
20
+ FacebookSocialPlugins::Facepile.new(options).render
21
+ end
22
+
23
+ def fb_like_box options = {}
24
+ FacebookSocialPlugins::LikeBox.new(options).render
25
+ end
26
+
27
+ def fb_like_button options = {}
28
+ FacebookSocialPlugins::LikeButton.new(options).render
29
+ end
30
+
31
+ def fb_live_stream options = {}
32
+ FacebookSocialPlugins::LiveStream.new(options).render
33
+ end
34
+
35
+ def fb_login_button options = {}
36
+ FacebookSocialPlugins::LoginButton.new(options).render
37
+ end
38
+
39
+ def fb_recommendations_box options = {}
40
+ FacebookSocialPlugins::RecommendationsBox.new(options).render
41
+ end
42
+
43
+ def fb_registration options = {}
44
+ FacebookSocialPlugins::Registration.new(options).render
45
+ end
46
+
47
+ def fb_send_button options = {}
48
+ FacebookSocialPlugins::SendButton.new(options).render
49
+ end
50
+
51
+ def fb_subscribe_button options = {}
52
+ FacebookSocialPlugins::SubscribeButton.new(options).render
53
+ end
54
+ end
55
+ end
56
+
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ async_script = %Q{
5
+ window.fbAsyncInit = function() {
6
+ FB.init({
7
+ appId : '123', // App ID
8
+ channelUrl : '//www.example.com/assets/facebook_channel.html', // Channel File
9
+ status : true, // check login status
10
+ cookie : true, // enable cookies to allow the server to access the session
11
+ xfbml : true // parse XFBML
12
+ });
13
+
14
+ // Additional initialization code here
15
+ };
16
+ }
17
+
18
+ fb_script = %Q{
19
+ (function(d){
20
+ var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
21
+ js = d.createElement('script'); js.id = id; js.async = true;
22
+ js.src = "//connect.facebook.net/en_US/all.js";
23
+ d.getElementsByTagName('head')[0].appendChild(js);
24
+ }(document));
25
+ }
26
+
27
+ fb_script_es = %Q{
28
+ (function(d){
29
+ var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
30
+ js = d.createElement('script'); js.id = id; js.async = true;
31
+ js.src = "//connect.facebook.net/es_LA/all.js";
32
+ d.getElementsByTagName('head')[0].appendChild(js);
33
+ }(document));
34
+ }
35
+
36
+
37
+ describe FacebookSocialPlugins::ScriptHelper do
38
+ include ControllerTestHelpers,
39
+ FacebookSocialPlugins::ScriptHelper
40
+
41
+ it "should create async init script" do
42
+ output = async_init_script '123', 'www.example.com'
43
+ output.should == async_script
44
+ end
45
+
46
+ it "should create facebook script" do
47
+ output = facebook_script
48
+ output.should == fb_script
49
+ end
50
+
51
+ it "should create localized facebook script" do
52
+ output = facebook_script :es_LA
53
+ output.should == fb_script_es
54
+ end
55
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe FacebookSocialPlugins::ViewHelper do
4
+ include ControllerTestHelpers,
5
+ FacebookSocialPlugins::ViewHelper
6
+
7
+ describe 'Social plugin' do
8
+ it "should not create plugin if unknown attribute is encountered" do
9
+ lambda { fb_activity_feed :my_site => 'www.example.com' }.should raise_error
10
+ end
11
+ end
12
+
13
+ describe 'Activity Feed' do
14
+ it "should create :activity div" do
15
+ output = fb_activity_feed :site => 'www.example.com'
16
+ output.should == "<div class=\"fb-activity\" data-site=\"www.example.com\"></div>"
17
+ end
18
+ end
19
+
20
+ describe 'Add To Timeline' do
21
+ it "should create :add-to-timeline div" do
22
+ output = fb_add_to_timeline :mode => 'box'
23
+ output.should == "<div class=\"fb-add-to-timeline\" data-mode=\"box\"></div>"
24
+ end
25
+ end
26
+
27
+ describe 'Comments' do
28
+ it "should create :comments div" do
29
+ output = fb_comments :href => 'http://www.example.com'
30
+ output.should == "<div class=\"fb-comments\" data-href=\"http://www.example.com\"></div>"
31
+ end
32
+ end
33
+
34
+ describe 'Facepile' do
35
+ it "should create :facepile div" do
36
+ output = fb_facepile :event_app_id => '276334346'
37
+ output.should == "<div class=\"fb-facepile\" data-event-app-id=\"276334346\"></div>"
38
+ end
39
+ end
40
+
41
+ describe 'Like Box' do
42
+ it "should create :like-box div" do
43
+ output = fb_like_box :href => 'http://www.example.com'
44
+ output.should == "<div class=\"fb-like-box\" data-href=\"http://www.example.com\"></div>"
45
+ end
46
+ end
47
+
48
+ describe 'Like Button' do
49
+ it "should create :like-button div" do
50
+ output = fb_like_button :href => 'http://www.example.com'
51
+ output.should == "<div class=\"fb-like\" data-href=\"http://www.example.com\"></div>"
52
+ end
53
+ end
54
+
55
+ describe 'Live Stream' do
56
+ it "should create :live-stream div" do
57
+ output = fb_live_stream :'via-url' => 'http://www.example.com'
58
+ output.should == "<div class=\"fb-live-stream\" data-via-url=\"http://www.example.com\"></div>"
59
+ end
60
+
61
+ it "should create :live-stream div even if non-dashed attribute" do
62
+ output = fb_live_stream :via_url => 'http://www.example.com'
63
+ output.should == "<div class=\"fb-live-stream\" data-via-url=\"http://www.example.com\"></div>"
64
+ end
65
+ end
66
+
67
+ describe 'Login Button' do
68
+ it "should create :login-button div" do
69
+ output = fb_login_button :show_faces => true
70
+ output.should == "<div class=\"fb-login-button\" data-show-faces=\"true\"></div>"
71
+ end
72
+ end
73
+
74
+ describe 'Recommendations Box' do
75
+ it "should NOT create :recommendations div when invalid kind of linktarget" do
76
+ lambda { fb_recommendations_box :linktarget => '_other' }.should raise_error
77
+ end
78
+
79
+ it "should create :recommendations div when valid kind of linktarget" do
80
+ output = fb_recommendations_box :linktarget => '_parent'
81
+ output.should == "<div class=\"fb-recommendations\" data-linktarget=\"_parent\"></div>"
82
+ end
83
+ end
84
+
85
+ describe 'Registration' do
86
+ it "should create :registration div" do
87
+ output = fb_registration :target => '_self'
88
+ output.should == "<div class=\"fb-registration\" data-target=\"_self\"></div>"
89
+ end
90
+ end
91
+
92
+ describe 'Send Button' do
93
+ it "should NOT create :send-button div if invalid font" do
94
+ lambda { fb_send_button :colorscheme => 'light', :font => 'unknown' }.should raise_error
95
+ end
96
+
97
+ it "should NOT create :send-button div if invalid colorscheme" do
98
+ lambda { fb_send_button :colorscheme => 'brown', :font => 'arial' }.should raise_error
99
+ end
100
+
101
+ it "should create :send-button div" do
102
+ output = fb_send_button :colorscheme => 'light', :font => 'arial'
103
+ output.should == "<div class=\"fb-send\" data-colorscheme=\"light\" data-font=\"arial\"></div>"
104
+ end
105
+ end
106
+
107
+ describe 'Subscribe Button' do
108
+ it "should create :subscribe-button div" do
109
+ output = fb_subscribe_button :width => 200
110
+ output.should == "<div class=\"fb-subscribe\" data-width=\"200\"></div>"
111
+ end
112
+ end
113
+ end