ahoy_matey 4.1.0 → 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/CHANGELOG.md +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +3 -21
- data/lib/ahoy/version.rb +1 -1
- data/lib/ahoy.rb +12 -12
- data/lib/ahoy_matey.rb +1 -1
- data/lib/generators/ahoy/activerecord_generator.rb +12 -0
- data/lib/generators/ahoy/templates/active_record_migration.rb.tt +5 -5
- data/vendor/assets/javascripts/ahoy.js +32 -29
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e92b695b80a72d0e60e30f459c8b8e8a72df4d33652aafab25cd6798c3b39b60
|
|
4
|
+
data.tar.gz: e1654e31ba9add55b36290bd0e8da150abd5bd358662e11a34120bd074ef2ed3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 34654baa122484f10b8cb0a169fafae0018aa06d31b341ac43c5d202ef7314f96bb17cb87247f04c47b87173d055d0a61a211792b4a6958266c00e2ed1135799
|
|
7
|
+
data.tar.gz: 35d424209a166bf189b87b4dc9c37a3106b522ae6ce9614debc8a8ce550a416de7bb78ab055b6e433ca46a0e207357ccd57078dd2ddbcece7ccf3dfe3d43e568
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
Track visits and events in Ruby, JavaScript, and native apps. Data is stored in your database by default, and you can customize it for any data store as you grow.
|
|
6
6
|
|
|
7
|
-
**Ahoy 4.0 was recently released** - see [how to upgrade](#upgrading)
|
|
8
|
-
|
|
9
7
|
:postbox: Check out [Ahoy Email](https://github.com/ankane/ahoy_email) for emails and [Field Test](https://github.com/ankane/field_test) for A/B testing
|
|
10
8
|
|
|
11
9
|
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
|
@@ -813,26 +811,10 @@ bundle install
|
|
|
813
811
|
bundle exec rake test
|
|
814
812
|
```
|
|
815
813
|
|
|
816
|
-
To test
|
|
814
|
+
To test different adapters, use:
|
|
817
815
|
|
|
818
816
|
```sh
|
|
817
|
+
ADAPTER=postgresql bundle exec rake test
|
|
818
|
+
ADAPTER=mysql2 bundle exec rake test
|
|
819
819
|
ADAPTER=mongoid bundle exec rake test
|
|
820
820
|
```
|
|
821
|
-
|
|
822
|
-
To test query methods, use:
|
|
823
|
-
|
|
824
|
-
```sh
|
|
825
|
-
# Postgres
|
|
826
|
-
createdb ahoy_test
|
|
827
|
-
bundle exec rake test:query_methods:postgresql
|
|
828
|
-
|
|
829
|
-
# SQLite
|
|
830
|
-
bundle exec rake test:query_methods:sqlite
|
|
831
|
-
|
|
832
|
-
# MySQL and MariaDB
|
|
833
|
-
mysqladmin create ahoy_test
|
|
834
|
-
bundle exec rake test:query_methods:mysql
|
|
835
|
-
|
|
836
|
-
# MongoDB
|
|
837
|
-
bundle exec rake test:query_methods:mongoid
|
|
838
|
-
```
|
data/lib/ahoy/version.rb
CHANGED
data/lib/ahoy.rb
CHANGED
|
@@ -7,18 +7,18 @@ require "active_support/core_ext"
|
|
|
7
7
|
require "safely/core"
|
|
8
8
|
|
|
9
9
|
# modules
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
10
|
+
require_relative "ahoy/utils"
|
|
11
|
+
require_relative "ahoy/base_store"
|
|
12
|
+
require_relative "ahoy/controller"
|
|
13
|
+
require_relative "ahoy/database_store"
|
|
14
|
+
require_relative "ahoy/helper"
|
|
15
|
+
require_relative "ahoy/model"
|
|
16
|
+
require_relative "ahoy/query_methods"
|
|
17
|
+
require_relative "ahoy/tracker"
|
|
18
|
+
require_relative "ahoy/version"
|
|
19
|
+
require_relative "ahoy/visit_properties"
|
|
20
|
+
|
|
21
|
+
require_relative "ahoy/engine" if defined?(Rails)
|
|
22
22
|
|
|
23
23
|
module Ahoy
|
|
24
24
|
mattr_accessor :visit_duration
|
data/lib/ahoy_matey.rb
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative "ahoy"
|
|
@@ -50,6 +50,18 @@ module Ahoy
|
|
|
50
50
|
def migration_version
|
|
51
51
|
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
|
52
52
|
end
|
|
53
|
+
|
|
54
|
+
def primary_key_type
|
|
55
|
+
", id: :#{key_type}" if key_type
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def foreign_key_type
|
|
59
|
+
", type: :#{key_type}" if key_type
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def key_type
|
|
63
|
+
Rails.configuration.generators.options.dig(:active_record, :primary_key_type)
|
|
64
|
+
end
|
|
53
65
|
end
|
|
54
66
|
end
|
|
55
67
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
|
|
2
2
|
def change
|
|
3
|
-
create_table :ahoy_visits do |t|
|
|
3
|
+
create_table :ahoy_visits<%= primary_key_type %> do |t|
|
|
4
4
|
t.string :visit_token
|
|
5
5
|
t.string :visitor_token
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
|
|
|
8
8
|
# simply remove any you don't want
|
|
9
9
|
|
|
10
10
|
# user
|
|
11
|
-
t.references :user
|
|
11
|
+
t.references :user<%= foreign_key_type %>
|
|
12
12
|
|
|
13
13
|
# standard
|
|
14
14
|
t.string :ip
|
|
@@ -46,9 +46,9 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
|
|
|
46
46
|
|
|
47
47
|
add_index :ahoy_visits, :visit_token, unique: true
|
|
48
48
|
|
|
49
|
-
create_table :ahoy_events do |t|
|
|
50
|
-
t.references :visit
|
|
51
|
-
t.references :user
|
|
49
|
+
create_table :ahoy_events<%= primary_key_type %> do |t|
|
|
50
|
+
t.references :visit<%= foreign_key_type %>
|
|
51
|
+
t.references :user<%= foreign_key_type %>
|
|
52
52
|
|
|
53
53
|
t.string :name
|
|
54
54
|
t.<%= properties_type %> :properties
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Ahoy.js
|
|
2
|
+
* Ahoy.js v0.4.1
|
|
3
3
|
* Simple, powerful JavaScript analytics
|
|
4
4
|
* https://github.com/ankane/ahoy.js
|
|
5
|
-
* v0.4.0
|
|
6
5
|
* MIT License
|
|
7
6
|
*/
|
|
8
7
|
|
|
9
8
|
(function (global, factory) {
|
|
10
9
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
11
10
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
12
|
-
(global = global || self, global.ahoy = factory());
|
|
13
|
-
}(this, (function () { 'use strict';
|
|
11
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ahoy = factory());
|
|
12
|
+
})(this, (function () { 'use strict';
|
|
14
13
|
|
|
15
14
|
// https://www.quirksmode.org/js/cookies.html
|
|
16
15
|
|
|
@@ -67,7 +66,7 @@
|
|
|
67
66
|
|
|
68
67
|
ahoy.configure = function (options) {
|
|
69
68
|
for (var key in options) {
|
|
70
|
-
if (
|
|
69
|
+
if (Object.prototype.hasOwnProperty.call(options, key)) {
|
|
71
70
|
config[key] = options[key];
|
|
72
71
|
}
|
|
73
72
|
}
|
|
@@ -102,7 +101,7 @@
|
|
|
102
101
|
function serialize(object) {
|
|
103
102
|
var data = new FormData();
|
|
104
103
|
for (var key in object) {
|
|
105
|
-
if (
|
|
104
|
+
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
|
106
105
|
data.append(key, object[key]);
|
|
107
106
|
}
|
|
108
107
|
}
|
|
@@ -170,6 +169,9 @@
|
|
|
170
169
|
document.addEventListener(eventName, function (e) {
|
|
171
170
|
var matchedElement = matchesSelector(e.target, selector);
|
|
172
171
|
if (matchedElement) {
|
|
172
|
+
var skip = getClosest(matchedElement, "data-ahoy-skip");
|
|
173
|
+
if (skip !== null && skip !== "false") { return; }
|
|
174
|
+
|
|
173
175
|
callback.call(matchedElement, e);
|
|
174
176
|
}
|
|
175
177
|
});
|
|
@@ -186,8 +188,9 @@
|
|
|
186
188
|
|
|
187
189
|
// https://stackoverflow.com/a/2117523/1177228
|
|
188
190
|
function generateId() {
|
|
189
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
190
|
-
var r = Math.random()*16|0
|
|
191
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
|
192
|
+
var r = Math.random() * 16 | 0;
|
|
193
|
+
var v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
191
194
|
return v.toString(16);
|
|
192
195
|
});
|
|
193
196
|
}
|
|
@@ -237,11 +240,11 @@
|
|
|
237
240
|
xhr.withCredentials = config.withCredentials;
|
|
238
241
|
xhr.setRequestHeader("Content-Type", "application/json");
|
|
239
242
|
for (var header in config.headers) {
|
|
240
|
-
if (
|
|
243
|
+
if (Object.prototype.hasOwnProperty.call(config.headers, header)) {
|
|
241
244
|
xhr.setRequestHeader(header, config.headers[header]);
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
|
-
xhr.onload = function() {
|
|
247
|
+
xhr.onload = function () {
|
|
245
248
|
if (xhr.status === 200) {
|
|
246
249
|
success();
|
|
247
250
|
}
|
|
@@ -266,11 +269,11 @@
|
|
|
266
269
|
}
|
|
267
270
|
|
|
268
271
|
function trackEvent(event) {
|
|
269
|
-
ahoy.ready(
|
|
270
|
-
sendRequest(eventsUrl(), eventData(event), function() {
|
|
272
|
+
ahoy.ready(function () {
|
|
273
|
+
sendRequest(eventsUrl(), eventData(event), function () {
|
|
271
274
|
// remove from queue
|
|
272
275
|
for (var i = 0; i < eventQueue.length; i++) {
|
|
273
|
-
if (eventQueue[i].id
|
|
276
|
+
if (eventQueue[i].id === event.id) {
|
|
274
277
|
eventQueue.splice(i, 1);
|
|
275
278
|
break;
|
|
276
279
|
}
|
|
@@ -281,7 +284,7 @@
|
|
|
281
284
|
}
|
|
282
285
|
|
|
283
286
|
function trackEventNow(event) {
|
|
284
|
-
ahoy.ready(
|
|
287
|
+
ahoy.ready(function () {
|
|
285
288
|
var data = eventData(event);
|
|
286
289
|
var param = csrfParam();
|
|
287
290
|
var token = csrfToken();
|
|
@@ -303,7 +306,7 @@
|
|
|
303
306
|
|
|
304
307
|
function cleanObject(obj) {
|
|
305
308
|
for (var key in obj) {
|
|
306
|
-
if (
|
|
309
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
307
310
|
if (obj[key] === null) {
|
|
308
311
|
delete obj[key];
|
|
309
312
|
}
|
|
@@ -318,14 +321,14 @@
|
|
|
318
321
|
id: presence(this.id),
|
|
319
322
|
"class": presence(this.className),
|
|
320
323
|
page: page(),
|
|
321
|
-
section:
|
|
324
|
+
section: getClosest(this, "data-section")
|
|
322
325
|
});
|
|
323
326
|
}
|
|
324
327
|
|
|
325
|
-
function
|
|
326
|
-
for (
|
|
327
|
-
if (element.hasAttribute(
|
|
328
|
-
return element.getAttribute(
|
|
328
|
+
function getClosest(element, attribute) {
|
|
329
|
+
for (; element && element !== document; element = element.parentNode) {
|
|
330
|
+
if (element.hasAttribute(attribute)) {
|
|
331
|
+
return element.getAttribute(attribute);
|
|
329
332
|
}
|
|
330
333
|
}
|
|
331
334
|
|
|
@@ -377,7 +380,7 @@
|
|
|
377
380
|
}
|
|
378
381
|
|
|
379
382
|
for (var key in config.visitParams) {
|
|
380
|
-
if (
|
|
383
|
+
if (Object.prototype.hasOwnProperty.call(config.visitParam, key)) {
|
|
381
384
|
data[key] = config.visitParams[key];
|
|
382
385
|
}
|
|
383
386
|
}
|
|
@@ -431,12 +434,12 @@
|
|
|
431
434
|
js: true
|
|
432
435
|
};
|
|
433
436
|
|
|
434
|
-
ahoy.ready(
|
|
437
|
+
ahoy.ready(function () {
|
|
435
438
|
if (config.cookies && !ahoy.getVisitId()) {
|
|
436
439
|
createVisit();
|
|
437
440
|
}
|
|
438
441
|
|
|
439
|
-
ahoy.ready(
|
|
442
|
+
ahoy.ready(function () {
|
|
440
443
|
log(event);
|
|
441
444
|
|
|
442
445
|
event.visit_token = ahoy.getVisitId();
|
|
@@ -449,7 +452,7 @@
|
|
|
449
452
|
saveEventQueue();
|
|
450
453
|
|
|
451
454
|
// wait in case navigating to reduce duplicate events
|
|
452
|
-
setTimeout(
|
|
455
|
+
setTimeout(function () {
|
|
453
456
|
trackEvent(event);
|
|
454
457
|
}, 1000);
|
|
455
458
|
}
|
|
@@ -467,8 +470,8 @@
|
|
|
467
470
|
};
|
|
468
471
|
|
|
469
472
|
if (additionalProperties) {
|
|
470
|
-
for(var propName in additionalProperties) {
|
|
471
|
-
if (
|
|
473
|
+
for (var propName in additionalProperties) {
|
|
474
|
+
if (Object.prototype.hasOwnProperty.call(additionalProperties, propName)) {
|
|
472
475
|
properties[propName] = additionalProperties[propName];
|
|
473
476
|
}
|
|
474
477
|
}
|
|
@@ -482,7 +485,7 @@
|
|
|
482
485
|
}
|
|
483
486
|
onEvent("click", selector, function (e) {
|
|
484
487
|
var properties = eventProperties.call(this, e);
|
|
485
|
-
properties.text = properties.tag
|
|
488
|
+
properties.text = properties.tag === "input" ? this.value : (this.textContent || this.innerText || this.innerHTML).replace(/[\s\r\n]+/g, " ").trim();
|
|
486
489
|
properties.href = this.href;
|
|
487
490
|
ahoy.track("$click", properties);
|
|
488
491
|
});
|
|
@@ -526,7 +529,7 @@
|
|
|
526
529
|
ahoy.start = function () {};
|
|
527
530
|
};
|
|
528
531
|
|
|
529
|
-
documentReady(function() {
|
|
532
|
+
documentReady(function () {
|
|
530
533
|
if (config.startOnReady) {
|
|
531
534
|
ahoy.start();
|
|
532
535
|
}
|
|
@@ -534,4 +537,4 @@
|
|
|
534
537
|
|
|
535
538
|
return ahoy;
|
|
536
539
|
|
|
537
|
-
}))
|
|
540
|
+
}));
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ahoy_matey
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-02-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -113,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
113
113
|
- !ruby/object:Gem::Version
|
|
114
114
|
version: '0'
|
|
115
115
|
requirements: []
|
|
116
|
-
rubygems_version: 3.
|
|
116
|
+
rubygems_version: 3.4.6
|
|
117
117
|
signing_key:
|
|
118
118
|
specification_version: 4
|
|
119
119
|
summary: Simple, powerful, first-party analytics for Rails
|