ahoy_matey 3.0.5 → 4.2.1

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.
@@ -1,18 +1,15 @@
1
- /*
2
- * Ahoy.js
1
+ /*!
2
+ * Ahoy.js v0.4.2
3
3
  * Simple, powerful JavaScript analytics
4
4
  * https://github.com/ankane/ahoy.js
5
- * v0.3.6
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';
14
-
15
- var n=function(n){return void 0===n},e=function(n){return Array.isArray(n)},t=function(n){return n&&"number"==typeof n.size&&"string"==typeof n.type&&"function"==typeof n.slice},s=function(o,i,r,f){return (i=i||{}).indices=!n(i.indices)&&i.indices,i.nullsAsUndefineds=!n(i.nullsAsUndefineds)&&i.nullsAsUndefineds,i.booleansAsIntegers=!n(i.booleansAsIntegers)&&i.booleansAsIntegers,r=r||new FormData,n(o)?r:(null===o?i.nullsAsUndefineds||r.append(f,""):"boolean"!=typeof o?e(o)?o.length&&o.forEach(function(n,e){s(n,i,r,f+"["+(i.indices?e:"")+"]");}):o instanceof Date?r.append(f,o.toISOString()):o!==Object(o)||function(n){return t(n)&&"string"==typeof n.name&&("object"==typeof n.lastModifiedDate||"number"==typeof n.lastModified)}(o)||t(o)?r.append(f,o):Object.keys(o).forEach(function(n){var t=o[n];if(e(t)){ for(;n.length>2&&n.lastIndexOf("[]")===n.length-2;){ n=n.substring(0,n.length-2); } }s(t,i,r,f?f+"["+n+"]":n);}):r.append(f,i.booleansAsIntegers?o?1:0:o),r)};
11
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.ahoy = factory());
12
+ })(this, (function () { 'use strict';
16
13
 
17
14
  // https://www.quirksmode.org/js/cookies.html
18
15
 
@@ -28,7 +25,7 @@
28
25
  if (domain) {
29
26
  cookieDomain = "; domain=" + domain;
30
27
  }
31
- document.cookie = name + "=" + escape(value) + expires + cookieDomain + "; path=/";
28
+ document.cookie = name + "=" + escape(value) + expires + cookieDomain + "; path=/; samesite=lax";
32
29
  },
33
30
  get: function (name) {
34
31
  var i, c;
@@ -69,7 +66,7 @@
69
66
 
70
67
  ahoy.configure = function (options) {
71
68
  for (var key in options) {
72
- if (options.hasOwnProperty(key)) {
69
+ if (Object.prototype.hasOwnProperty.call(options, key)) {
73
70
  config[key] = options[key];
74
71
  }
75
72
  }
@@ -101,6 +98,16 @@
101
98
  return (config.useBeacon || config.trackNow) && isEmpty(config.headers) && canStringify && typeof(window.navigator.sendBeacon) !== "undefined" && !config.withCredentials;
102
99
  }
103
100
 
101
+ function serialize(object) {
102
+ var data = new FormData();
103
+ for (var key in object) {
104
+ if (Object.prototype.hasOwnProperty.call(object, key)) {
105
+ data.append(key, object[key]);
106
+ }
107
+ }
108
+ return data;
109
+ }
110
+
104
111
  // cookies
105
112
 
106
113
  function setCookie(name, value, ttl) {
@@ -146,17 +153,26 @@
146
153
  element.webkitMatchesSelector;
147
154
 
148
155
  if (matches) {
149
- return matches.apply(element, [selector]);
156
+ if (matches.apply(element, [selector])) {
157
+ return element;
158
+ } else if (element.parentElement) {
159
+ return matchesSelector(element.parentElement, selector);
160
+ }
161
+ return null;
150
162
  } else {
151
163
  log("Unable to match");
152
- return false;
164
+ return null;
153
165
  }
154
166
  }
155
167
 
156
168
  function onEvent(eventName, selector, callback) {
157
169
  document.addEventListener(eventName, function (e) {
158
- if (matchesSelector(e.target, selector)) {
159
- callback(e);
170
+ var matchedElement = matchesSelector(e.target, selector);
171
+ if (matchedElement) {
172
+ var skip = getClosest(matchedElement, "data-ahoy-skip");
173
+ if (skip !== null && skip !== "false") { return; }
174
+
175
+ callback.call(matchedElement, e);
160
176
  }
161
177
  });
162
178
  }
@@ -172,8 +188,9 @@
172
188
 
173
189
  // https://stackoverflow.com/a/2117523/1177228
174
190
  function generateId() {
175
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
176
- var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
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);
177
194
  return v.toString(16);
178
195
  });
179
196
  }
@@ -223,11 +240,11 @@
223
240
  xhr.withCredentials = config.withCredentials;
224
241
  xhr.setRequestHeader("Content-Type", "application/json");
225
242
  for (var header in config.headers) {
226
- if (config.headers.hasOwnProperty(header)) {
243
+ if (Object.prototype.hasOwnProperty.call(config.headers, header)) {
227
244
  xhr.setRequestHeader(header, config.headers[header]);
228
245
  }
229
246
  }
230
- xhr.onload = function() {
247
+ xhr.onload = function () {
231
248
  if (xhr.status === 200) {
232
249
  success();
233
250
  }
@@ -252,11 +269,11 @@
252
269
  }
253
270
 
254
271
  function trackEvent(event) {
255
- ahoy.ready( function () {
256
- sendRequest(eventsUrl(), eventData(event), function() {
272
+ ahoy.ready(function () {
273
+ sendRequest(eventsUrl(), eventData(event), function () {
257
274
  // remove from queue
258
275
  for (var i = 0; i < eventQueue.length; i++) {
259
- if (eventQueue[i].id == event.id) {
276
+ if (eventQueue[i].id === event.id) {
260
277
  eventQueue.splice(i, 1);
261
278
  break;
262
279
  }
@@ -267,7 +284,7 @@
267
284
  }
268
285
 
269
286
  function trackEventNow(event) {
270
- ahoy.ready( function () {
287
+ ahoy.ready(function () {
271
288
  var data = eventData(event);
272
289
  var param = csrfParam();
273
290
  var token = csrfToken();
@@ -275,7 +292,7 @@
275
292
  // stringify so we keep the type
276
293
  data.events_json = JSON.stringify(data.events);
277
294
  delete data.events;
278
- window.navigator.sendBeacon(eventsUrl(), s(data));
295
+ window.navigator.sendBeacon(eventsUrl(), serialize(data));
279
296
  });
280
297
  }
281
298
 
@@ -289,7 +306,7 @@
289
306
 
290
307
  function cleanObject(obj) {
291
308
  for (var key in obj) {
292
- if (obj.hasOwnProperty(key)) {
309
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
293
310
  if (obj[key] === null) {
294
311
  delete obj[key];
295
312
  }
@@ -298,21 +315,20 @@
298
315
  return obj;
299
316
  }
300
317
 
301
- function eventProperties(e) {
302
- var target = e.target;
318
+ function eventProperties() {
303
319
  return cleanObject({
304
- tag: target.tagName.toLowerCase(),
305
- id: presence(target.id),
306
- "class": presence(target.className),
320
+ tag: this.tagName.toLowerCase(),
321
+ id: presence(this.id),
322
+ "class": presence(this.className),
307
323
  page: page(),
308
- section: getClosestSection(target)
324
+ section: getClosest(this, "data-section")
309
325
  });
310
326
  }
311
327
 
312
- function getClosestSection(element) {
313
- for ( ; element && element !== document; element = element.parentNode) {
314
- if (element.hasAttribute('data-section')) {
315
- return element.getAttribute('data-section');
328
+ function getClosest(element, attribute) {
329
+ for (; element && element !== document; element = element.parentNode) {
330
+ if (element.hasAttribute(attribute)) {
331
+ return element.getAttribute(attribute);
316
332
  }
317
333
  }
318
334
 
@@ -364,7 +380,7 @@
364
380
  }
365
381
 
366
382
  for (var key in config.visitParams) {
367
- if (config.visitParams.hasOwnProperty(key)) {
383
+ if (Object.prototype.hasOwnProperty.call(config.visitParams, key)) {
368
384
  data[key] = config.visitParams[key];
369
385
  }
370
386
  }
@@ -418,12 +434,12 @@
418
434
  js: true
419
435
  };
420
436
 
421
- ahoy.ready( function () {
437
+ ahoy.ready(function () {
422
438
  if (config.cookies && !ahoy.getVisitId()) {
423
439
  createVisit();
424
440
  }
425
441
 
426
- ahoy.ready( function () {
442
+ ahoy.ready(function () {
427
443
  log(event);
428
444
 
429
445
  event.visit_token = ahoy.getVisitId();
@@ -436,7 +452,7 @@
436
452
  saveEventQueue();
437
453
 
438
454
  // wait in case navigating to reduce duplicate events
439
- setTimeout( function () {
455
+ setTimeout(function () {
440
456
  trackEvent(event);
441
457
  }, 1000);
442
458
  }
@@ -454,8 +470,8 @@
454
470
  };
455
471
 
456
472
  if (additionalProperties) {
457
- for(var propName in additionalProperties) {
458
- if (additionalProperties.hasOwnProperty(propName)) {
473
+ for (var propName in additionalProperties) {
474
+ if (Object.prototype.hasOwnProperty.call(additionalProperties, propName)) {
459
475
  properties[propName] = additionalProperties[propName];
460
476
  }
461
477
  }
@@ -463,37 +479,39 @@
463
479
  ahoy.track("$view", properties);
464
480
  };
465
481
 
466
- ahoy.trackClicks = function () {
467
- onEvent("click", "a, button, input[type=submit]", function (e) {
468
- var target = e.target;
469
- var properties = eventProperties(e);
470
- properties.text = properties.tag == "input" ? target.value : (target.textContent || target.innerText || target.innerHTML).replace(/[\s\r\n]+/g, " ").trim();
471
- properties.href = target.href;
482
+ ahoy.trackClicks = function (selector) {
483
+ if (selector === undefined) {
484
+ throw new Error("Missing selector");
485
+ }
486
+ onEvent("click", selector, function (e) {
487
+ var properties = eventProperties.call(this, e);
488
+ properties.text = properties.tag === "input" ? this.value : (this.textContent || this.innerText || this.innerHTML).replace(/[\s\r\n]+/g, " ").trim();
489
+ properties.href = this.href;
472
490
  ahoy.track("$click", properties);
473
491
  });
474
492
  };
475
493
 
476
- ahoy.trackSubmits = function () {
477
- onEvent("submit", "form", function (e) {
478
- var properties = eventProperties(e);
494
+ ahoy.trackSubmits = function (selector) {
495
+ if (selector === undefined) {
496
+ throw new Error("Missing selector");
497
+ }
498
+ onEvent("submit", selector, function (e) {
499
+ var properties = eventProperties.call(this, e);
479
500
  ahoy.track("$submit", properties);
480
501
  });
481
502
  };
482
503
 
483
- ahoy.trackChanges = function () {
484
- onEvent("change", "input, textarea, select", function (e) {
485
- var properties = eventProperties(e);
504
+ ahoy.trackChanges = function (selector) {
505
+ log("trackChanges is deprecated and will be removed in 0.5.0");
506
+ if (selector === undefined) {
507
+ throw new Error("Missing selector");
508
+ }
509
+ onEvent("change", selector, function (e) {
510
+ var properties = eventProperties.call(this, e);
486
511
  ahoy.track("$change", properties);
487
512
  });
488
513
  };
489
514
 
490
- ahoy.trackAll = function() {
491
- ahoy.trackView();
492
- ahoy.trackClicks();
493
- ahoy.trackSubmits();
494
- ahoy.trackChanges();
495
- };
496
-
497
515
  // push events from queue
498
516
  try {
499
517
  eventQueue = JSON.parse(getCookie("ahoy_events") || "[]");
@@ -511,7 +529,7 @@
511
529
  ahoy.start = function () {};
512
530
  };
513
531
 
514
- documentReady(function() {
532
+ documentReady(function () {
515
533
  if (config.startOnReady) {
516
534
  ahoy.start();
517
535
  }
@@ -519,4 +537,4 @@
519
537
 
520
538
  return ahoy;
521
539
 
522
- })));
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: 3.0.5
4
+ version: 4.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-09-10 00:00:00.000000000 Z
11
+ date: 2023-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '5'
27
- - !ruby/object:Gem::Dependency
28
- name: geocoder
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 1.4.5
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 1.4.5
26
+ version: '5.2'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: safely_block
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,162 +52,8 @@ dependencies:
66
52
  - - ">="
67
53
  - !ruby/object:Gem::Version
68
54
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: bundler
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: minitest
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: combustion
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: rails
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: sqlite3
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: pg
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
167
- - !ruby/object:Gem::Dependency
168
- name: mysql2
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - ">="
179
- - !ruby/object:Gem::Version
180
- version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: mongoid
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - ">="
186
- - !ruby/object:Gem::Version
187
- version: '0'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: '0'
195
- - !ruby/object:Gem::Dependency
196
- name: browser
197
- requirement: !ruby/object:Gem::Requirement
198
- requirements:
199
- - - "~>"
200
- - !ruby/object:Gem::Version
201
- version: '2.0'
202
- type: :development
203
- prerelease: false
204
- version_requirements: !ruby/object:Gem::Requirement
205
- requirements:
206
- - - "~>"
207
- - !ruby/object:Gem::Version
208
- version: '2.0'
209
- - !ruby/object:Gem::Dependency
210
- name: user_agent_parser
211
- requirement: !ruby/object:Gem::Requirement
212
- requirements:
213
- - - ">="
214
- - !ruby/object:Gem::Version
215
- version: '0'
216
- type: :development
217
- prerelease: false
218
- version_requirements: !ruby/object:Gem::Requirement
219
- requirements:
220
- - - ">="
221
- - !ruby/object:Gem::Version
222
- version: '0'
223
- description:
224
- email: andrew@chartkick.com
55
+ description:
56
+ email: andrew@ankane.org
225
57
  executables: []
226
58
  extensions: []
227
59
  extra_rdoc_files: []
@@ -266,7 +98,7 @@ homepage: https://github.com/ankane/ahoy
266
98
  licenses:
267
99
  - MIT
268
100
  metadata: {}
269
- post_install_message:
101
+ post_install_message:
270
102
  rdoc_options: []
271
103
  require_paths:
272
104
  - lib
@@ -274,15 +106,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
274
106
  requirements:
275
107
  - - ">="
276
108
  - !ruby/object:Gem::Version
277
- version: '2.4'
109
+ version: '2.6'
278
110
  required_rubygems_version: !ruby/object:Gem::Requirement
279
111
  requirements:
280
112
  - - ">="
281
113
  - !ruby/object:Gem::Version
282
114
  version: '0'
283
115
  requirements: []
284
- rubygems_version: 3.1.2
285
- signing_key:
116
+ rubygems_version: 3.4.6
117
+ signing_key:
286
118
  specification_version: 4
287
119
  summary: Simple, powerful, first-party analytics for Rails
288
120
  test_files: []