Handle cookie expiration and visit duration better
Andrew
committed Feb 27, 2018
commit f2d2284129a1a716a975d98843154fe10e49714a
Showing 2
changed files with
142 additions
and 111 deletions
app/controllers/ahoy/visits_controller.rb
+4
-0
| @@ | @@ -2,6 +2,10 @@ module Ahoy |
| class VisitsController < BaseController | |
| def create | |
| ahoy.track_visit | |
| + | |
| + | # set proper ttl if cookie generated from JavaScript |
| + | set_ahoy_cookies if params[:js] && !Ahoy.api_only |
| + | |
| render json: { | |
| visit_token: ahoy.visit_token, | |
| visitor_token: ahoy.visitor_token, | |
vendor/assets/javascripts/ahoy.js
+138
-111
| @@ | @@ -1,76 +1,76 @@ |
| (function webpackUniversalModuleDefinition(root, factory) { | |
| - | if(typeof exports === 'object' && typeof module === 'object') |
| - | module.exports = factory(); |
| - | else if(typeof define === 'function' && define.amd) |
| - | define([], factory); |
| - | else if(typeof exports === 'object') |
| - | exports["ahoy"] = factory(); |
| - | else |
| - | root["ahoy"] = factory(); |
| + | if(typeof exports === 'object' && typeof module === 'object') |
| + | module.exports = factory(); |
| + | else if(typeof define === 'function' && define.amd) |
| + | define([], factory); |
| + | else if(typeof exports === 'object') |
| + | exports["ahoy"] = factory(); |
| + | else |
| + | root["ahoy"] = factory(); |
| })(typeof self !== 'undefined' ? self : this, function() { | |
| return /******/ (function(modules) { // webpackBootstrap | |
| - | /******/ // The module cache |
| - | /******/ var installedModules = {}; |
| + | /******/ // The module cache |
| + | /******/ var installedModules = {}; |
| /******/ | |
| - | /******/ // The require function |
| - | /******/ function __webpack_require__(moduleId) { |
| + | /******/ // The require function |
| + | /******/ function __webpack_require__(moduleId) { |
| /******/ | |
| - | /******/ // Check if module is in cache |
| - | /******/ if(installedModules[moduleId]) { |
| - | /******/ return installedModules[moduleId].exports; |
| - | /******/ } |
| - | /******/ // Create a new module (and put it into the cache) |
| - | /******/ var module = installedModules[moduleId] = { |
| - | /******/ i: moduleId, |
| - | /******/ l: false, |
| - | /******/ exports: {} |
| - | /******/ }; |
| + | /******/ // Check if module is in cache |
| + | /******/ if(installedModules[moduleId]) { |
| + | /******/ return installedModules[moduleId].exports; |
| + | /******/ } |
| + | /******/ // Create a new module (and put it into the cache) |
| + | /******/ var module = installedModules[moduleId] = { |
| + | /******/ i: moduleId, |
| + | /******/ l: false, |
| + | /******/ exports: {} |
| + | /******/ }; |
| /******/ | |
| - | /******/ // Execute the module function |
| - | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); |
| + | /******/ // Execute the module function |
| + | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); |
| /******/ | |
| - | /******/ // Flag the module as loaded |
| - | /******/ module.l = true; |
| + | /******/ // Flag the module as loaded |
| + | /******/ module.l = true; |
| /******/ | |
| - | /******/ // Return the exports of the module |
| - | /******/ return module.exports; |
| - | /******/ } |
| + | /******/ // Return the exports of the module |
| + | /******/ return module.exports; |
| + | /******/ } |
| /******/ | |
| /******/ | |
| - | /******/ // expose the modules object (__webpack_modules__) |
| - | /******/ __webpack_require__.m = modules; |
| + | /******/ // expose the modules object (__webpack_modules__) |
| + | /******/ __webpack_require__.m = modules; |
| /******/ | |
| - | /******/ // expose the module cache |
| - | /******/ __webpack_require__.c = installedModules; |
| + | /******/ // expose the module cache |
| + | /******/ __webpack_require__.c = installedModules; |
| /******/ | |
| - | /******/ // define getter function for harmony exports |
| - | /******/ __webpack_require__.d = function(exports, name, getter) { |
| - | /******/ if(!__webpack_require__.o(exports, name)) { |
| - | /******/ Object.defineProperty(exports, name, { |
| - | /******/ configurable: false, |
| - | /******/ enumerable: true, |
| - | /******/ get: getter |
| - | /******/ }); |
| - | /******/ } |
| - | /******/ }; |
| + | /******/ // define getter function for harmony exports |
| + | /******/ __webpack_require__.d = function(exports, name, getter) { |
| + | /******/ if(!__webpack_require__.o(exports, name)) { |
| + | /******/ Object.defineProperty(exports, name, { |
| + | /******/ configurable: false, |
| + | /******/ enumerable: true, |
| + | /******/ get: getter |
| + | /******/ }); |
| + | /******/ } |
| + | /******/ }; |
| /******/ | |
| - | /******/ // getDefaultExport function for compatibility with non-harmony modules |
| - | /******/ __webpack_require__.n = function(module) { |
| - | /******/ var getter = module && module.__esModule ? |
| - | /******/ function getDefault() { return module['default']; } : |
| - | /******/ function getModuleExports() { return module; }; |
| - | /******/ __webpack_require__.d(getter, 'a', getter); |
| - | /******/ return getter; |
| - | /******/ }; |
| + | /******/ // getDefaultExport function for compatibility with non-harmony modules |
| + | /******/ __webpack_require__.n = function(module) { |
| + | /******/ var getter = module && module.__esModule ? |
| + | /******/ function getDefault() { return module['default']; } : |
| + | /******/ function getModuleExports() { return module; }; |
| + | /******/ __webpack_require__.d(getter, 'a', getter); |
| + | /******/ return getter; |
| + | /******/ }; |
| /******/ | |
| - | /******/ // Object.prototype.hasOwnProperty.call |
| - | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; |
| + | /******/ // Object.prototype.hasOwnProperty.call |
| + | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; |
| /******/ | |
| - | /******/ // __webpack_public_path__ |
| - | /******/ __webpack_require__.p = ""; |
| + | /******/ // __webpack_public_path__ |
| + | /******/ __webpack_require__.p = ""; |
| /******/ | |
| - | /******/ // Load entry module and return exports |
| - | /******/ return __webpack_require__(__webpack_require__.s = 0); |
| + | /******/ // Load entry module and return exports |
| + | /******/ return __webpack_require__(__webpack_require__.s = 0); |
| /******/ }) | |
| /************************************************************************/ | |
| /******/ ([ | |
| @@ | @@ -88,8 +88,20 @@ var _objectToFormdata = __webpack_require__(1); |
| var _objectToFormdata2 = _interopRequireDefault(_objectToFormdata); | |
| + | var _cookies = __webpack_require__(2); |
| + | |
| + | var _cookies2 = _interopRequireDefault(_cookies); |
| + | |
| function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | |
| + | /* |
| + | * Ahoy.js |
| + | * Simple, powerful JavaScript analytics |
| + | * https://github.com/ankane/ahoy.js |
| + | * v0.3.0 |
| + | * MIT License |
| + | */ |
| + | |
| var config = { | |
| urlPrefix: "", | |
| visitsUrl: "/ahoy/visits", | |
| @@ | @@ -99,13 +111,7 @@ var config = { |
| platform: "Web", | |
| useBeacon: true, | |
| startOnReady: true | |
| - | }; /* |
| - | * Ahoy.js |
| - | * Simple, powerful JavaScript analytics |
| - | * https://github.com/ankane/ahoy.js |
| - | * v0.3.0 |
| - | * MIT License |
| - | */ |
| + | }; |
| var ahoy = window.ahoy || window.Ahoy || {}; | |
| @@ | @@ -145,41 +151,16 @@ function canTrackNow() { |
| // cookies | |
| - | // http://www.quirksmode.org/js/cookies.html |
| function setCookie(name, value, ttl) { | |
| - | var expires = ""; |
| - | var cookieDomain = ""; |
| - | if (ttl) { |
| - | var date = new Date(); |
| - | date.setTime(date.getTime() + ttl * 60 * 1000); |
| - | expires = "; expires=" + date.toGMTString(); |
| - | } |
| - | var domain = config.cookieDomain || config.domain; |
| - | if (domain) { |
| - | cookieDomain = "; domain=" + domain; |
| - | } |
| - | document.cookie = name + "=" + escape(value) + expires + cookieDomain + "; path=/"; |
| + | _cookies2.default.set(name, value, ttl, config.cookieDomain || config.domain); |
| } | |
| function getCookie(name) { | |
| - | var i = void 0, |
| - | c = void 0; |
| - | var nameEQ = name + "="; |
| - | var ca = document.cookie.split(';'); |
| - | for (i = 0; i < ca.length; i++) { |
| - | c = ca[i]; |
| - | while (c.charAt(0) === ' ') { |
| - | c = c.substring(1, c.length); |
| - | } |
| - | if (c.indexOf(nameEQ) === 0) { |
| - | return unescape(c.substring(nameEQ.length, c.length)); |
| - | } |
| - | } |
| - | return null; |
| + | return _cookies2.default.get(name); |
| } | |
| function destroyCookie(name) { | |
| - | setCookie(name, "", -1); |
| + | _cookies2.default.set(name, "", -1); |
| } | |
| function log(message) { | |
| @@ | @@ -400,7 +381,8 @@ function createVisit() { |
| platform: config.platform, | |
| landing_page: window.location.href, | |
| screen_width: window.screen.width, | |
| - | screen_height: window.screen.height |
| + | screen_height: window.screen.height, |
| + | js: true |
| }; | |
| // referrer | |
| @@ | @@ -452,31 +434,32 @@ ahoy.track = function (name, properties) { |
| id: generateId() | |
| }; | |
| - | // wait for createVisit to log |
| - | documentReady(function () { |
| - | log(event); |
| - | }); |
| - | |
| ready(function () { | |
| if (!ahoy.getVisitId()) { | |
| createVisit(); | |
| } | |
| - | event.visit_token = ahoy.getVisitId(); |
| - | event.visitor_token = ahoy.getVisitorId(); |
| + | ready(function () { |
| + | log(event); |
| - | if (canTrackNow()) { |
| - | trackEventNow(event); |
| - | } else { |
| - | eventQueue.push(event); |
| - | saveEventQueue(); |
| + | event.visit_token = ahoy.getVisitId(); |
| + | event.visitor_token = ahoy.getVisitorId(); |
| - | // wait in case navigating to reduce duplicate events |
| - | setTimeout(function () { |
| - | trackEvent(event); |
| - | }, 1000); |
| - | } |
| + | if (canTrackNow()) { |
| + | trackEventNow(event); |
| + | } else { |
| + | eventQueue.push(event); |
| + | saveEventQueue(); |
| + | |
| + | // wait in case navigating to reduce duplicate events |
| + | setTimeout(function () { |
| + | trackEvent(event); |
| + | }, 1000); |
| + | } |
| + | }); |
| }); | |
| + | |
| + | return true; |
| }; | |
| ahoy.trackView = function (additionalProperties) { | |
| @@ | @@ -623,6 +606,50 @@ function objectToFormData (obj, fd, pre) { |
| module.exports = objectToFormData | |
| + | /***/ }), |
| + | /* 2 */ |
| + | /***/ (function(module, exports, __webpack_require__) { |
| + | |
| + | "use strict"; |
| + | |
| + | |
| + | Object.defineProperty(exports, "__esModule", { |
| + | value: true |
| + | }); |
| + | // http://www.quirksmode.org/js/cookies.html |
| + | |
| + | exports.default = { |
| + | set: function set(name, value, ttl, domain) { |
| + | var expires = ""; |
| + | var cookieDomain = ""; |
| + | if (ttl) { |
| + | var date = new Date(); |
| + | date.setTime(date.getTime() + ttl * 60 * 1000); |
| + | expires = "; expires=" + date.toGMTString(); |
| + | } |
| + | if (domain) { |
| + | cookieDomain = "; domain=" + domain; |
| + | } |
| + | document.cookie = name + "=" + escape(value) + expires + cookieDomain + "; path=/"; |
| + | }, |
| + | get: function get(name) { |
| + | var i = void 0, |
| + | c = void 0; |
| + | var nameEQ = name + "="; |
| + | var ca = document.cookie.split(';'); |
| + | for (i = 0; i < ca.length; i++) { |
| + | c = ca[i]; |
| + | while (c.charAt(0) === ' ') { |
| + | c = c.substring(1, c.length); |
| + | } |
| + | if (c.indexOf(nameEQ) === 0) { |
| + | return unescape(c.substring(nameEQ.length, c.length)); |
| + | } |
| + | } |
| + | return null; |
| + | } |
| + | }; |
| + | |
| /***/ }) | |
| /******/ ])["default"]; | |
| - | }); |
| + | }); |
| \ No newline at end of file | |