ga_events 4.0.1 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -1
- data/Gemfile +1 -2
- data/README.md +7 -3
- data/app/assets/javascripts/ga_events.js.coffee +44 -12
- data/ga_events.gemspec +3 -3
- data/lib/ga_events/list.rb +1 -0
- data/lib/ga_events/middleware.rb +39 -26
- data/lib/ga_events/version.rb +1 -1
- data/spec/event_spec.rb +2 -0
- data/spec/list_spec.rb +4 -2
- data/spec/middleware_spec.rb +8 -7
- data/spec/middlware_event_placement_spec.rb +119 -0
- data/spec/spec_helper.rb +0 -1
- metadata +10 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 83fd5b6e15c900730f8f41e03ade3efab0b619a7c4e9e67074db8730ac0701db
|
|
4
|
+
data.tar.gz: e866ec33593b82a6f826004c4c03486203963be5eae9e534ed6be0cad9a3e626
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0345da75e6b2500c22ef51b72823c3eaf42e71a0e57c9e617119dcacfa4a2aed07ea4120fb25db030d2c3394c322cfce44bdcd44c300ef0deaf275e36b9d5613
|
|
7
|
+
data.tar.gz: d2c2449b6117600eebd172680950a5e42c98f2669c75bb6eda9651d1e1dda0a8da731881b78d205236bedb17130f046a6df500cefd56641667e1c39bc9af35a3
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -13,9 +13,13 @@ pushes it to Google Analytics via gtag.js or Google Tag Manager.
|
|
|
13
13
|
|
|
14
14
|
## Dependencies
|
|
15
15
|
|
|
16
|
-
* Ruby >= 3.
|
|
17
|
-
* Rails
|
|
16
|
+
* Ruby >= 3.4
|
|
17
|
+
* Rails 7.2 onwards
|
|
18
|
+
|
|
19
|
+
## Optional dependencies
|
|
20
|
+
|
|
18
21
|
* jQuery
|
|
22
|
+
* Turbolinks or Hotwire Turbo
|
|
19
23
|
|
|
20
24
|
## Installation
|
|
21
25
|
|
|
@@ -27,7 +31,7 @@ gem 'ga_events'
|
|
|
27
31
|
|
|
28
32
|
Run the `bundle` command to install it.
|
|
29
33
|
|
|
30
|
-
Add to the top of your `application.js`
|
|
34
|
+
Add to the top of your `application.js`
|
|
31
35
|
|
|
32
36
|
```javascript
|
|
33
37
|
//= require ga_events.js
|
|
@@ -16,24 +16,33 @@ class GaEvents.Event
|
|
|
16
16
|
# Decompose an event-string (ruby side) into an event object.
|
|
17
17
|
@from_json: (string) ->
|
|
18
18
|
events = JSON.parse(string)
|
|
19
|
-
|
|
20
|
-
$.map events, (event) =>
|
|
19
|
+
events.map((event) ->
|
|
21
20
|
if event_name = event.__event__
|
|
22
21
|
delete event.__event__
|
|
23
22
|
new @(event_name, event)
|
|
23
|
+
, @)
|
|
24
24
|
|
|
25
25
|
@from_dom: ->
|
|
26
26
|
data_attribute = "data-#{@html_key}"
|
|
27
|
-
dom_events =
|
|
28
|
-
|
|
27
|
+
dom_events = document
|
|
28
|
+
.querySelector("div[#{data_attribute}]")
|
|
29
|
+
?.getAttribute(data_attribute)
|
|
30
|
+
|
|
31
|
+
@from_json(dom_events) if dom_events?
|
|
29
32
|
|
|
30
33
|
# Events should not be sent to an adapter unless the DOM has finished loading.
|
|
31
34
|
@flush: ->
|
|
32
35
|
return if @require_user_consent && !@user_consent_given
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
push_events = =>
|
|
38
|
+
if @list.length > 0 and @may_flush
|
|
39
|
+
@list.forEach((event) -> event.push_to_adapter())
|
|
40
|
+
@list = []
|
|
41
|
+
|
|
42
|
+
if window.requestIdleCallback
|
|
43
|
+
requestIdleCallback(push_events, timeout: 250)
|
|
44
|
+
else
|
|
45
|
+
setTimeout(push_events, 1)
|
|
37
46
|
|
|
38
47
|
# Add all events to a queue to flush them later
|
|
39
48
|
constructor: (@event_name, @options = {}) ->
|
|
@@ -49,21 +58,44 @@ class GaEvents.Event
|
|
|
49
58
|
# https://support.google.com/analytics/answer/13316687?hl=en#zippy=%2Cweb
|
|
50
59
|
is_valid_event_name: -> /^[a-z]+[a-z0-9_]*$/i.test(@event_name)
|
|
51
60
|
|
|
52
|
-
|
|
61
|
+
|
|
62
|
+
start = ->
|
|
53
63
|
@may_flush = true
|
|
54
64
|
@flush()
|
|
55
65
|
|
|
66
|
+
addEventListener = document.addEventListener
|
|
67
|
+
|
|
56
68
|
process_xhr = (xhr) =>
|
|
57
69
|
xhr_events = xhr.getResponseHeader @header_key
|
|
58
70
|
@from_json decodeURIComponent(xhr_events) if xhr_events?
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
process_fetch = (response) =>
|
|
73
|
+
events = response.headers.get @header_key
|
|
74
|
+
@from_json decodeURIComponent(events) if events?
|
|
75
|
+
|
|
76
|
+
# jQuery $.ajax
|
|
77
|
+
if window.jQuery && jQuery.ajax
|
|
78
|
+
# This event can only be caught on the jQuery event bus.
|
|
79
|
+
jQuery(document).on("ajaxComplete", (_, xhr) -> process_xhr(xhr))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# classic Turbolinks
|
|
83
|
+
addEventListener("turbolinks:request-end", (event) ->
|
|
84
|
+
process_xhr(event.originalEvent.data.xhr)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Hotwire/Turbo
|
|
88
|
+
addEventListener("turbo:before-fetch-response", (event) ->
|
|
89
|
+
process_fetch(event.detail.fetchResponse.response)
|
|
90
|
+
)
|
|
64
91
|
|
|
65
92
|
@from_dom()
|
|
66
93
|
|
|
94
|
+
if document.readyState == "loading"
|
|
95
|
+
addEventListener("DOMContentLoaded", start.bind(@), once: true)
|
|
96
|
+
else
|
|
97
|
+
start.call(@)
|
|
98
|
+
|
|
67
99
|
|
|
68
100
|
class GaEvents.GTagAdapter
|
|
69
101
|
constructor: (options) ->
|
data/ga_events.gemspec
CHANGED
|
@@ -20,12 +20,12 @@ Gem::Specification.new do |gem|
|
|
|
20
20
|
|
|
21
21
|
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
|
22
22
|
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
|
23
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
24
23
|
gem.name = 'ga_events'
|
|
25
24
|
gem.require_paths = ['lib']
|
|
26
25
|
gem.version = GaEvents::VERSION
|
|
27
26
|
gem.licenses = ['MIT']
|
|
28
27
|
|
|
29
|
-
gem.required_ruby_version = '>= 3.
|
|
30
|
-
gem.add_dependency 'rails', '>=
|
|
28
|
+
gem.required_ruby_version = '>= 3.4'
|
|
29
|
+
gem.add_dependency 'rails', '>= 7.2'
|
|
30
|
+
gem.metadata['rubygems_mfa_required'] = 'true'
|
|
31
31
|
end
|
data/lib/ga_events/list.rb
CHANGED
data/lib/ga_events/middleware.rb
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'rack/utils'
|
|
4
|
+
require 'rack/request'
|
|
5
|
+
require 'rack/headers'
|
|
6
|
+
require 'cgi'
|
|
7
|
+
require 'rubygems'
|
|
4
8
|
|
|
5
9
|
module GaEvents
|
|
6
10
|
class Middleware
|
|
7
11
|
SESSION_GA_EVENTS_KEY = 'ga_events.events'
|
|
12
|
+
RESPONSE_HEADER = 'x-ga-events'
|
|
13
|
+
|
|
14
|
+
HEADERS_KLASS = if Gem::Version.new(Rack.release) < Gem::Version.new('3.0')
|
|
15
|
+
Rack::Utils::HeaderHash
|
|
16
|
+
else
|
|
17
|
+
Rack::Headers
|
|
18
|
+
end
|
|
19
|
+
private_constant :HEADERS_KLASS
|
|
8
20
|
|
|
9
21
|
def initialize(app)
|
|
10
22
|
@app = app
|
|
@@ -12,27 +24,27 @@ module GaEvents
|
|
|
12
24
|
|
|
13
25
|
def call(env)
|
|
14
26
|
init_event_list(env)
|
|
15
|
-
status, headers,
|
|
27
|
+
status, headers, body = @app.call(env)
|
|
16
28
|
|
|
17
|
-
headers = Rack::Utils::HeaderHash.new(headers)
|
|
18
29
|
if GaEvents::List.present?
|
|
30
|
+
headers = HEADERS_KLASS.new.merge(headers)
|
|
19
31
|
request = Rack::Request.new(env)
|
|
20
32
|
|
|
21
33
|
# Can outgrow, headers might get too big
|
|
22
|
-
|
|
23
|
-
if
|
|
34
|
+
serialized_events = GaEvents::List.to_s
|
|
35
|
+
if xhr_or_turbo?(request)
|
|
24
36
|
# AJAX request
|
|
25
|
-
headers[
|
|
37
|
+
headers[RESPONSE_HEADER] = CGI.escapeURIComponent(serialized_events)
|
|
26
38
|
elsif redirect?(status)
|
|
27
39
|
# 30x/redirect? Then add event list to rack session to survive the
|
|
28
40
|
# redirect.
|
|
29
|
-
add_events_to_session(env,
|
|
41
|
+
add_events_to_session(env, serialized_events)
|
|
30
42
|
elsif html?(status, headers)
|
|
31
|
-
|
|
43
|
+
body = inject_div(body, serialized_events)
|
|
32
44
|
end
|
|
33
45
|
end
|
|
34
46
|
|
|
35
|
-
[status, headers,
|
|
47
|
+
[status, headers, body]
|
|
36
48
|
end
|
|
37
49
|
|
|
38
50
|
private
|
|
@@ -43,41 +55,42 @@ module GaEvents
|
|
|
43
55
|
end
|
|
44
56
|
|
|
45
57
|
def add_events_to_session env, serialized_data
|
|
46
|
-
if session = env
|
|
58
|
+
if session = env['rack.session']
|
|
47
59
|
session[SESSION_GA_EVENTS_KEY] = serialized_data
|
|
48
60
|
end
|
|
49
61
|
end
|
|
50
62
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def inject_div(response, serialized_data)
|
|
58
|
-
r = normalize_response(response)
|
|
59
|
-
serialized_data = CGI.escapeHTML(serialized_data)
|
|
60
|
-
[
|
|
61
|
-
r.sub('</body>') do |body|
|
|
63
|
+
def inject_div(body, serialized_data)
|
|
64
|
+
if body.respond_to?(:to_ary)
|
|
65
|
+
html = +''
|
|
66
|
+
body.to_ary.each { |chunk| html << chunk }
|
|
67
|
+
html.sub!(%r{</body>}i) do |body|
|
|
68
|
+
serialized_data = CGI.escapeHTML(serialized_data)
|
|
62
69
|
"<div data-ga-events=\"#{serialized_data}\"></div>#{body}"
|
|
63
70
|
end
|
|
64
|
-
|
|
71
|
+
body = [html]
|
|
72
|
+
end
|
|
73
|
+
body
|
|
74
|
+
ensure
|
|
75
|
+
body.close if body.respond_to?(:close)
|
|
65
76
|
end
|
|
66
77
|
|
|
67
78
|
# Taken from:
|
|
68
79
|
# https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/jsonp.rb
|
|
69
|
-
def html?(status,
|
|
80
|
+
def html?(status, response_headers)
|
|
70
81
|
!Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
|
|
71
|
-
|
|
72
|
-
|
|
82
|
+
response_headers.key?('content-type') &&
|
|
83
|
+
response_headers['content-type'].start_with?('text/html')
|
|
73
84
|
end
|
|
74
85
|
|
|
75
86
|
def redirect?(status)
|
|
76
87
|
(300..399).cover?(status)
|
|
77
88
|
end
|
|
78
89
|
|
|
79
|
-
def
|
|
80
|
-
request.xhr? ||
|
|
90
|
+
def xhr_or_turbo?(request)
|
|
91
|
+
request.xhr? ||
|
|
92
|
+
request.env['HTTP_TURBOLINKS_REFERRER'] ||
|
|
93
|
+
request.env['HTTP_X_TURBO_REQUEST_ID']
|
|
81
94
|
end
|
|
82
95
|
end
|
|
83
96
|
end
|
data/lib/ga_events/version.rb
CHANGED
data/spec/event_spec.rb
CHANGED
data/spec/list_spec.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
RSpec.describe 'GaEvents::List' do
|
|
@@ -22,7 +24,7 @@ RSpec.describe 'GaEvents::List' do
|
|
|
22
24
|
JSON
|
|
23
25
|
|
|
24
26
|
expect(
|
|
25
|
-
GaEvents::List.send(:data).to_h { [
|
|
27
|
+
GaEvents::List.send(:data).to_h { [it.event_name, it.event_params] }
|
|
26
28
|
).to eq({ 'clicked' => { 'a' => 'a' } })
|
|
27
29
|
end
|
|
28
30
|
|
|
@@ -34,7 +36,7 @@ RSpec.describe 'GaEvents::List' do
|
|
|
34
36
|
JSON
|
|
35
37
|
|
|
36
38
|
expect(
|
|
37
|
-
GaEvents::List.send(:data).to_h { [
|
|
39
|
+
GaEvents::List.send(:data).to_h { [it.event_name, it.event_params] }
|
|
38
40
|
).to be_empty
|
|
39
41
|
end
|
|
40
42
|
end
|
data/spec/middleware_spec.rb
CHANGED
|
@@ -38,12 +38,13 @@ describe GaEvents::Middleware do
|
|
|
38
38
|
'cool' => 'stuff',
|
|
39
39
|
'ding' => ["it's a bug", 'this is "fine"', 'x=1&y=2', '>:3<']
|
|
40
40
|
)
|
|
41
|
-
[200, { 'Content-Type' => 'text/html' }, response_body]
|
|
41
|
+
[200, { 'Content-Type' => 'text/html' }, [response_body]]
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
context 'when no body
|
|
45
|
+
context 'when no closing body tag exists' do
|
|
46
46
|
let(:response) { request.get('/') }
|
|
47
|
+
|
|
47
48
|
it 'leaves everything as it was' do
|
|
48
49
|
expect(response.body).to eq response_body
|
|
49
50
|
end
|
|
@@ -60,12 +61,12 @@ describe GaEvents::Middleware do
|
|
|
60
61
|
'"__event__":"test",' \
|
|
61
62
|
'"cool":"stuff",' \
|
|
62
63
|
'"ding":[' \
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
'"it's a bug",' \
|
|
65
|
+
'"this is \"fine\"",' \
|
|
66
|
+
'"x=1&y=2",' \
|
|
67
|
+
'">:3<"' \
|
|
67
68
|
']' \
|
|
68
|
-
|
|
69
|
+
'}]"></div></body>'
|
|
69
70
|
)
|
|
70
71
|
end
|
|
71
72
|
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe GaEvents::Middleware do
|
|
6
|
+
let(:app) do
|
|
7
|
+
lambda do |env|
|
|
8
|
+
status_code = env.delete('app_status_code').to_i
|
|
9
|
+
|
|
10
|
+
GaEvents::Event.new('test', 'event' => 'stuff')
|
|
11
|
+
[status_code, { 'content-type' => 'text/html' }, [<<~HTML]]
|
|
12
|
+
<!doctype html>
|
|
13
|
+
<html lang=en>
|
|
14
|
+
<head>
|
|
15
|
+
<meta charset=utf-8>
|
|
16
|
+
<title>ABC</title>
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<p>I'm the content</p>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
22
|
+
HTML
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'html requests' do
|
|
27
|
+
it 'adds events in an injected div' do
|
|
28
|
+
response = make_request
|
|
29
|
+
expect(response.body).to include('<div data-ga-events="[{')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'does no write to rack ression or response headers' do
|
|
33
|
+
session = {}
|
|
34
|
+
response = make_request('rack.session' => session)
|
|
35
|
+
expect(session[GaEvents::Middleware::SESSION_GA_EVENTS_KEY]).to be_nil
|
|
36
|
+
expect(response.headers).not_to have_key(
|
|
37
|
+
GaEvents::Middleware::RESPONSE_HEADER
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe 'non xhr/fetch redirects' do
|
|
43
|
+
it 'writes to session' do
|
|
44
|
+
session = {}
|
|
45
|
+
make_request('app_status_code' => '302', 'rack.session' => session)
|
|
46
|
+
expect(session[GaEvents::Middleware::SESSION_GA_EVENTS_KEY]).to be_present
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'does not inject html or add response headers' do
|
|
50
|
+
response = make_request('app_status_code' => '302', 'rack.session' => {})
|
|
51
|
+
expect(response.body).not_to include('<div data-ga-events="[{')
|
|
52
|
+
expect(response.headers).not_to have_key(
|
|
53
|
+
GaEvents::Middleware::RESPONSE_HEADER
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
describe 'xhr requests' do
|
|
59
|
+
it 'adds events as response header' do
|
|
60
|
+
response = make_request('HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest')
|
|
61
|
+
expect(
|
|
62
|
+
response.headers[GaEvents::Middleware::RESPONSE_HEADER]
|
|
63
|
+
).to include('__event__')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'does not inject a div or writes to session' do
|
|
67
|
+
session = {}
|
|
68
|
+
response =
|
|
69
|
+
make_request(
|
|
70
|
+
'HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest',
|
|
71
|
+
'rack.session' => session
|
|
72
|
+
)
|
|
73
|
+
expect(response.body).not_to include('<div data-ga-events')
|
|
74
|
+
expect(session[GaEvents::Middleware::SESSION_GA_EVENTS_KEY]).to be_nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe 'turbolink requests' do
|
|
79
|
+
it 'adds events as response header' do
|
|
80
|
+
response = make_request('HTTP_TURBOLINKS_REFERRER' => '...')
|
|
81
|
+
expect(
|
|
82
|
+
response.headers[GaEvents::Middleware::RESPONSE_HEADER]
|
|
83
|
+
).to include('__event__')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it 'does not inject a div with events' do
|
|
87
|
+
response = make_request('HTTP_TURBOLINKS_REFERRER' => '...')
|
|
88
|
+
expect(response.body).not_to include('<div data-ga-events')
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe 'turbo requests' do
|
|
93
|
+
it 'adds events as response header' do
|
|
94
|
+
response = make_request('HTTP_X_TURBO_REQUEST_ID' => '...')
|
|
95
|
+
expect(
|
|
96
|
+
response.headers[GaEvents::Middleware::RESPONSE_HEADER]
|
|
97
|
+
).to include('__event__')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'does not inject a div with events' do
|
|
101
|
+
response = make_request('HTTP_X_TURBO_REQUEST_ID' => '...')
|
|
102
|
+
expect(response.body).not_to include('<div data-ga-events')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def make_request(options = nil)
|
|
109
|
+
middleware = described_class.new(app)
|
|
110
|
+
options = {
|
|
111
|
+
'app_status_code' => '200',
|
|
112
|
+
:lint => true,
|
|
113
|
+
:fatal => true,
|
|
114
|
+
**options
|
|
115
|
+
}
|
|
116
|
+
r = Rack::MockRequest.new(middleware)
|
|
117
|
+
r.get('/', options)
|
|
118
|
+
end
|
|
119
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ga_events
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0
|
|
4
|
+
version: 4.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nix-wie-weg Team
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -16,14 +15,14 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
18
|
+
version: '7.2'
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - ">="
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
25
|
+
version: '7.2'
|
|
27
26
|
description: Google Analytics' Event Tracking everywhere in your Rails app)
|
|
28
27
|
email:
|
|
29
28
|
- admin@nix-wie-weg.de
|
|
@@ -50,12 +49,13 @@ files:
|
|
|
50
49
|
- spec/event_spec.rb
|
|
51
50
|
- spec/list_spec.rb
|
|
52
51
|
- spec/middleware_spec.rb
|
|
52
|
+
- spec/middlware_event_placement_spec.rb
|
|
53
53
|
- spec/spec_helper.rb
|
|
54
54
|
homepage: https://github.com/Nix-wie-weg/ga_events
|
|
55
55
|
licenses:
|
|
56
56
|
- MIT
|
|
57
|
-
metadata:
|
|
58
|
-
|
|
57
|
+
metadata:
|
|
58
|
+
rubygems_mfa_required: 'true'
|
|
59
59
|
rdoc_options: []
|
|
60
60
|
require_paths:
|
|
61
61
|
- lib
|
|
@@ -63,15 +63,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
63
63
|
requirements:
|
|
64
64
|
- - ">="
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: '3.
|
|
66
|
+
version: '3.4'
|
|
67
67
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
68
|
requirements:
|
|
69
69
|
- - ">="
|
|
70
70
|
- !ruby/object:Gem::Version
|
|
71
71
|
version: '0'
|
|
72
72
|
requirements: []
|
|
73
|
-
rubygems_version: 3.
|
|
74
|
-
signing_key:
|
|
73
|
+
rubygems_version: 3.7.2
|
|
75
74
|
specification_version: 4
|
|
76
75
|
summary: This gem allows you to annotate events everywhere in the code of your Rails
|
|
77
76
|
app. A rack middleware is automatically inserted into the stack. It transports the
|
|
@@ -79,8 +78,4 @@ summary: This gem allows you to annotate events everywhere in the code of your R
|
|
|
79
78
|
a data-pounded custom HTTP header appended. The asset pipeline-ready CoffeeScript
|
|
80
79
|
extracts this data on the client side and pushes it to Google Analytics via ga.js
|
|
81
80
|
or Google Tag Manager.
|
|
82
|
-
test_files:
|
|
83
|
-
- spec/event_spec.rb
|
|
84
|
-
- spec/list_spec.rb
|
|
85
|
-
- spec/middleware_spec.rb
|
|
86
|
-
- spec/spec_helper.rb
|
|
81
|
+
test_files: []
|