Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

refactored script logic and fixed widgetized bug

  • Loading branch information...
commit 0014076e6e39fe76053280c988d3d21156d6d92d 1 parent 5d283b8
@kristianmandrup authored
View
8 CHANGELOG.md
@@ -0,0 +1,8 @@
+## Changelog
+
+### 0.3.6
+
+- Added Scripter for handling script logic
+- Ensure script is only output once for each request, but again for next request
+by moving state to instance level (fixes bug in 3.5)
+- Specs added to test if script works correctly on multiple requests
View
2  README.md
@@ -109,7 +109,7 @@ So, a simple pinit button can be added like this:
* `:href` - The URL to share; the default is the current URL.
* `:size` - Size of button: 'small', 'tall' or 'medium'
* `:annotation` - The style of button: 'inline', 'bubble', 'none'
-* `:lang` - The locale, fx 'es' for Spanish
+* `:lang` - The locale, fx 'es' for Spanish (alias :locale)
See [Google+ button](http://www.google.com/intl/en/webmasters/+1/button/index.html) for more info.
View
2  VERSION
@@ -1 +1 @@
-0.3.5
+0.3.6
View
8 lib/social_buttons.rb
@@ -3,6 +3,14 @@ def self.names
%w{pinit tweet like google_plus}
end
+ def self.helpers
+ %w{assistant scripter}
+ end
+
+ def self.all
+ names + helpers
+ end
+
def self.config name = nil, &block
context = name ? "SocialButtons::#{name.to_s.camelize}".constantize : self
block_given? ? yield(context) : context
View
33 lib/social_buttons/view_helper.rb
@@ -1,15 +1,30 @@
-module SocialButtons
- # autoload :Assistant, 'social_buttons/view_helpers/assistant'
-
- [SocialButtons.names << :assistant].flatten.each do |name|
+module SocialButtons
+ SocialButtons.all.flatten.each do |name|
autoload name.to_s.camelize.to_sym, "social_buttons/view_helpers/#{name}"
end
module ViewHelper
- # Include all Social Buttons into ViewHelper to be made available
- # to be included into a View as one module (see engine)
- SocialButtons.names.each do |name|
- self.send :include, "SocialButtons::#{name.to_s.camelize}".constantize
- end
+ extend ActiveSupport::Concern
+
+ included do
+ # Include all Social Buttons into ViewHelper to be made available
+ # to be included into a View as one module (see engine)
+ SocialButtons.names.each do |name|
+ self.send :include, "SocialButtons::#{name.to_s.camelize}".constantize
+
+ attr_accessor :"#{name}_widgetized"
+ alias_method :"#{name}_widgetized?", :"#{name}_widgetized"
+ end
+ end
+
+ def widgetized! name
+ meth = "#{name}_widgetized="
+ self.send(meth, name) if respond_to? meth
+ end
+
+ def widgetized? name
+ meth = "#{name}_widgetized?"
+ self.send(meth) if respond_to? meth
+ end
end
end
View
10 lib/social_buttons/view_helpers/assistant.rb
@@ -2,11 +2,9 @@ module SocialButtons
module Assistant
extend ActiveSupport::Concern
- module ClassMethods
- attr_reader :widgetized
+ module ClassMethods
attr_writer :default_options
- alias_method :widgetized?, :widgetized
-
+
def myname
self.name.demodulize
end
@@ -33,10 +31,6 @@ def options_to_query_string(subject, opts)
def help_note
"Note: SocialButons will ensure that the button script is only rendered once!"
end
-
- def empty_content
- "".html_safe
- end
end
end
end
View
46 lib/social_buttons/view_helpers/google_plus.rb
@@ -10,23 +10,26 @@ module GooglePlus
# Async script mode:
# To only output script
- # = google_button :script, lang: 'es'
+ # = google_button :script, locale: 'es'
# To NOT output script
- # = google_button :lang => 'es', script: false
+ # = google_button :locale => 'es', script: false
def google_plus_button *args
options = args.extract_options!
clazz = SocialButtons::GooglePlus
return clazz.script(options) if args.first == :script
+ use_script = options.delete :script
+ locale = options.delete(:locale) || options.delete(:lang)
+
params = clazz.options_to_data_params(clazz.default_options.merge(options))
params.merge!(class: CLASS)
- script_context = options[:script] == :async ? clazz::Async : clazz
+ scripter_class = use_script == :async ? clazz::AsyncScripter : clazz::Scripter
html = "".html_safe
- html << content_tag(:div, params)
- html << script_context.script(options[:lang]) if options[:script]
+ html << content_tag(:div, nil, params)
+ html << scripter_class.new(self).script(locale) if use_script
html
end
@@ -38,23 +41,12 @@ def default_options
annotations: "inline"
}
end
+ end
- module Async
- # Place this tag in your head or just before your close body tag
- def script lang = nil
- %Q{<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
- #{language lang}
- </script>}
- end
-
- def language lang = nil
- "{lang: '#{lang}'}" if lang
- end
- end
-
+ class Scripter < SocialButtons::Scripter
def script lang = nil
- return empty_content if widgetized?
- @widgetized = true
+ return empty_content if widgetized? :google_plus
+ widgetized! :google_plus
%q{<script type="text/javascript">
#{language lang}
(function() {
@@ -69,5 +61,19 @@ def language lang = nil
"window.___gcfg = {lang: '#{lang}'};" if lang
end
end
+
+
+ class AsyncScripter < SocialButtons::Scripter
+ # Place this tag in your head or just before your close body tag
+ def script lang = nil
+ %Q{<script type="text/javascript" src="https://apis.google.com/js/plusone.js">
+ #{language lang}
+ </script>}
+ end
+
+ def language lang = nil
+ "{lang: '#{lang}'}" if lang
+ end
+ end
end
end
View
8 lib/social_buttons/view_helpers/like.rb
@@ -11,7 +11,7 @@ def like_button(app_id, options = {})
html = "".html_safe
html << content_tag(:div, nil, id: "fb-root")
- html << clazz.script(app_id)
+ html << clazz::Scripter.new(self).script(app_id)
html << content_tag(:div, nil, params)
html
end
@@ -28,10 +28,12 @@ def default_options
colorscheme: "light"
}.merge("show-faces" => "false")
end
+ end
+ class Scripter < SocialButtons::Scripter
def script(app_id)
- return empty_content if widgetized?
- @widgetized = true
+ return empty_content if widgetized? :like
+ widgetized! :like
"<script src=#{js_sdk(app_id)} type='text/javascript'></script>".html_safe
end
View
8 lib/social_buttons/view_helpers/pinit.rb
@@ -21,7 +21,7 @@ def pinit_button(options = {})
html << link_to(pinit_link, option_params) do
image_tag PINIT_BUTTON_IMAGE, border: ("0" || options[:border]), title: (TITLE || options[:title])
end
- html << clazz.script
+ html << clazz::Scripter.new(self).script
html
end
@@ -31,10 +31,12 @@ def default_options
description: "Pin Me!"
}.merge("count-layout" => "none")
end
+ end
+ class Scripter < SocialButtons::Scripter
def script
- return empty_content if widgetized?
- @widgetized = true
+ return empty_content if widgetized? :pinit
+ widgetized! :pinit
"<script src=#{pinit_js} type='text/javascript'></script>".html_safe
end
View
22 lib/social_buttons/view_helpers/scripter.rb
@@ -0,0 +1,22 @@
+module SocialButtons
+ class Scripter
+ attr_accessor :caller, :options
+
+ def initialize caller, options = {}
+ @caller = caller
+ @options = options
+ end
+
+ def script lang = nil
+ raise NotImplementedError, "Must be implemented by subclass"
+ end
+
+ protected
+
+ delegate :widgetized!, :widgetized?, to: :caller
+
+ def empty_content
+ "".html_safe
+ end
+ end
+end
View
8 lib/social_buttons/view_helpers/tweet.rb
@@ -11,7 +11,7 @@ def tweet_button(options = {})
params.merge!(class: CLASS)
html = "".html_safe
- html << clazz.script
+ html << clazz::Scripter.new(self).script
html << link_to("Tweet", TWITTER_SHARE_URL, params)
html
end
@@ -27,10 +27,12 @@ def default_options
related: ""
}
end
+ end
+ class Scripter < SocialButtons::Scripter
def script
- return empty_content if widgetized?
- @widgetized = true
+ return empty_content if widgetized? :tweet
+ widgetized! :tweet
"<script src=#{twitter_wjs} type='text/javascript'></script>".html_safe
end
View
17 spec/social_buttons/google_plus_spec.rb
@@ -11,10 +11,23 @@
end
end
- context 'with options' do
+ context 'with script and options' do
it "should set annotation using option" do
- output = google_plus_button(:annotation => 'bubble')
+ output = google_plus_button(:annotation => 'bubble', script: true)
output.should match(/bubble/)
+ output.should match(/<script/)
+
+ output = google_plus_button(:annotation => 'none', script: true)
+ output.should match(/none/)
+ output.should_not match(/<script/)
+ end
+ end
+
+ context 'with script - on next request' do
+ it "should render script again on next request!" do
+ output = google_plus_button(:annotation => 'bubble', script: true)
+ output.should match(/bubble/)
+ output.should match(/<script/)
end
end
end
View
12 spec/social_buttons/like_spec.rb
@@ -21,6 +21,18 @@
it "should set width using option" do
output = like_button('128085897213395', :width => '400')
output.should match(/width="400"/)
+ output.should match(/<script/)
+
+ output = like_button('128085897213395', :width => '400')
+ output.should_not match(/<script/)
+ end
+ end
+
+ context 'with script - on next request' do
+ it "should render script again on next request!" do
+ output = like_button('128085897213395', :width => '400')
+ output.should match(/width="400"/)
+ output.should match(/<script/)
end
end
end
View
12 spec/social_buttons/pinit_spec.rb
@@ -15,6 +15,18 @@
it "should set description using option" do
output = pinit_button(:colorscheme => 'dark')
output.should match(/dark/)
+ output.should match(/<script/)
+
+ output = pinit_button(:colorscheme => 'dark')
+ output.should_not match(/<script/)
+ end
+ end
+
+ context 'with script - on next request' do
+ it "should render script again on next request!" do
+ output = pinit_button(:colorscheme => 'dark')
+ output.should match(/dark/)
+ output.should match(/<script/)
end
end
end
View
12 spec/social_buttons/tweet_spec.rb
@@ -15,6 +15,18 @@
it "should set description using option" do
output = tweet_button(:text => 'hello')
output.should match(/hello/)
+ output.should match(/<script/)
+
+ output = tweet_button(:text => 'hello')
+ output.should_not match(/<script/)
+ end
+ end
+
+ context 'with script - on next request' do
+ it "should render script again on next request!" do
+ output = tweet_button(:text => 'hello')
+ output.should match(/hello/)
+ output.should match(/<script/)
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.