ahoy_matey 3.0.5 → 4.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []