diff --git a/CHANGELOG.md b/CHANGELOG.md index 3643e28..4398e32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 1.13.0 + +* [ENHANCEMENT] hotwired/turbo support #160 (thx @wrozka) +* [BUGFIX] Use leftmost match for gtm tag injection #156 (thx @yutoji) + +# 1.12.1 + +* [ENHANCEMENT] Use local variables to prevent instance state #151 (thx @bumi) +* [ENHANCEMENT] Make middleware thread safe #150 (thx @kspe) + # 1.12.0 * [ENHANCEMENT] Add support for Heap #147 (thx @mohanzhang) diff --git a/lib/rack/tracker.rb b/lib/rack/tracker.rb index ed0a07e..4e10d87 100644 --- a/lib/rack/tracker.rb +++ b/lib/rack/tracker.rb @@ -38,10 +38,14 @@ def initialize(app, &block) end def call(env) - @status, @headers, @body = @app.call(env) - return [@status, @headers, @body] unless html? - response = Rack::Response.new([], @status, @headers) + dup._call(env) + end + + def _call(env) + status, headers, body = @app.call(env) + return [status, headers, body] unless headers['Content-Type'] =~ /html/ + response = Rack::Response.new([], status, headers) env[EVENT_TRACKING_KEY] ||= {} if session = env["rack.session"] @@ -52,16 +56,14 @@ def call(env) session[EVENT_TRACKING_KEY] = env[EVENT_TRACKING_KEY] end - @body.each { |fragment| response.write inject(env, fragment) } - @body.close if @body.respond_to?(:close) + body.each { |fragment| response.write inject(env, fragment) } + body.close if body.respond_to?(:close) response.finish end private - def html?; @headers['Content-Type'] =~ /html/; end - def inject(env, response) duplicated_response = response.dup @handlers.each(env) do |handler| diff --git a/lib/rack/tracker/google_analytics/template/google_analytics.erb b/lib/rack/tracker/google_analytics/template/google_analytics.erb index 5aa0159..d6d9d7b 100644 --- a/lib/rack/tracker/google_analytics/template/google_analytics.erb +++ b/lib/rack/tracker/google_analytics/template/google_analytics.erb @@ -8,37 +8,37 @@ ga('create', '<%= tracker %>', <%= tracker_options.to_json %>); } -<% if options[:enhanced_link_attribution] %> - ga('require', 'linkid', 'linkid.js'); -<% end %> -<% if options[:advertising] %> - ga('require', 'displayfeatures'); -<% end %> -<% if options[:enhanced_ecommerce] %> - ga('require', 'ec'); -<% end %> -<% if options[:ecommerce] %> - ga('require', 'ecommerce', 'ecommerce.js'); -<% end %> -<% if options[:optimize] %> - ga('require', '<%= options[:optimize] %>'); -<% end %> -<% if options[:anonymize_ip] %> - ga('set', 'anonymizeIp', true); -<% end %> -<% if options[:adjusted_bounce_rate_timeouts] %> - <% options[:adjusted_bounce_rate_timeouts].each do |timeout| %> - setTimeout(function() { ga('send', 'event', '<%= "#{timeout.to_s}_seconds" %>', 'read'); },<%= timeout*1000 %>); + <% if options[:enhanced_link_attribution] %> + ga('require', 'linkid', 'linkid.js'); + <% end %> + <% if options[:advertising] %> + ga('require', 'displayfeatures'); + <% end %> + <% if options[:enhanced_ecommerce] %> + ga('require', 'ec'); + <% end %> + <% if options[:ecommerce] %> + ga('require', 'ecommerce', 'ecommerce.js'); + <% end %> + <% if options[:optimize] %> + ga('require', '<%= options[:optimize] %>'); + <% end %> + <% if options[:anonymize_ip] %> + ga('set', 'anonymizeIp', true); + <% end %> + <% if options[:adjusted_bounce_rate_timeouts] %> + <% options[:adjusted_bounce_rate_timeouts].each do |timeout| %> + setTimeout(function() { ga('send', 'event', '<%= "#{timeout.to_s}_seconds" %>', 'read'); },<%= timeout*1000 %>); + <% end %> + <% end %> + <% events.each do |var| %> + ga(<%= var.write() %>); + <% end %> + <% if options[:ecommerce] && ecommerce_events.any? %> + ga('ecommerce:send'); + <% end %> + <% if tracker && options[:explicit_pageview] %> + ga('send', 'pageview', <%= pageview_url_script %>); <% end %> -<% end %> -<% end %> -<% events.each do |var| %> - ga(<%= var.write() %>); -<% end %> -<% if options[:ecommerce] && ecommerce_events.any? %> - ga('ecommerce:send'); -<% end %> -<% if tracker && options[:explicit_pageview] %> - ga('send', 'pageview', <%= pageview_url_script %>); <% end %> diff --git a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb index 2db9d2b..1a05489 100644 --- a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb +++ b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb @@ -10,7 +10,7 @@ def inject(response) # Sub! is enough, in well formed html there's only one head or body tag. # Block syntax need to be used, otherwise backslashes in input will mess the output. # @see http://stackoverflow.com/a/4149087/518204 and https://github.com/railslove/rack-tracker/issues/50 - response.sub! %r{} do |m| + response.sub! %r{} do |m| m.to_s << self.render_head end response.sub! %r{} do |m| diff --git a/lib/rack/tracker/google_tag_manager/template/google_tag_manager_head.erb b/lib/rack/tracker/google_tag_manager/template/google_tag_manager_head.erb index 3b059c0..2df1117 100644 --- a/lib/rack/tracker/google_tag_manager/template/google_tag_manager_head.erb +++ b/lib/rack/tracker/google_tag_manager/template/google_tag_manager_head.erb @@ -1,23 +1,29 @@ <% if container %> - <% unless options[:turbolinks] %> - <% if events.any? %> - - <% end %> - <% end %> - + + <% if events.any? %> + + <% end %> + + ') + allow(handler_object).to receive(:render_body).and_return('') + end + + context 'with one line html response' do + let(:example_response) { "" } + + it 'will have render_head content in head tag' do + expect(subject).to match(%r{.*.*}) + end + + it 'will have render_body content in body tag' do + expect(subject).to match(%r{.*.*}) + end + + end + end + end diff --git a/spec/integration/google_tag_manager_integration_spec.rb b/spec/integration/google_tag_manager_integration_spec.rb index f8fe375..9d2b5aa 100644 --- a/spec/integration/google_tag_manager_integration_spec.rb +++ b/spec/integration/google_tag_manager_integration_spec.rb @@ -23,7 +23,7 @@ expect(page.find("body")).to have_xpath '//body/noscript/iframe[@src="https://www.googletagmanager.com/ns.html?id=GTM-ABCDEF"]' end - it "embeds the turbolinks observer if requested" do + it "embeds turbolinks and turbo observers if requested" do visit '/' expect(page.find("head")).to_not have_content "turbolinks:load" setup_app(action: :google_tag_manager) do |tracker| @@ -31,5 +31,6 @@ end visit '/' expect(page.find("head")).to have_content "turbolinks:load" + expect(page.find("head")).to have_content "turbo:load" end -end \ No newline at end of file +end