/* * Copyright (c) 2016-2017, Michael A. Updike All rights reserved. * Licensed under Apache 2.0 * https://opensource.org/licenses/Apache-2.0 * https://github.com/opus1269/chrome-extension-utils/blob/master/LICENSE.md */ window.Chrome = window.Chrome || {}; /** * Google Analytics tracking * @namespace */ Chrome.GA = (function() { 'use strict'; /** * Google Analytics Event * @typedef {Object} Chrome.GA.Event * @property {string} eventCategory - category * @property {string} eventAction - action * @property {string} eventLabel - label * @memberOf Chrome.GA */ /** * Event: called when document and resources are loaded<br /> * Initialize Google Analytics * @private * @memberOf Chrome.GA */ function _onLoad() { // Standard Google Universal Analytics code // noinspection OverlyComplexFunctionJS (function(i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; // noinspection CommaExpressionJS i[r] = i[r] || function() { (i[r].q = i[r].q || []).push(arguments); }, i[r].l = 1 * new Date(); // noinspection CommaExpressionJS a = s.createElement(o), m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m); })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga'); } // listen for document and resources loaded window.addEventListener('load', _onLoad); /** * Event types * @type {{}} * @property {Chrome.GA.Event} INSTALLED - extension installed * @property {Chrome.GA.Event} UPDATED - extension updated * @property {Chrome.GA.Event} MENU - menu selected * @property {Chrome.GA.Event} TOGGLE - setting-toggle * @property {Chrome.GA.Event} LINK - setting-link * @property {Chrome.GA.Event} TEXT - setting-text * @property {Chrome.GA.Event} SLIDER_VALUE - setting-slider value * @property {Chrome.GA.Event} SLIDER_UNITS - setting-slider unit * @property {Chrome.GA.Event} BUTTON - button click * @property {Chrome.GA.Event} ICON - toolbar icon click * @property {Chrome.GA.Event} CHECK - checkbox click * @property {Chrome.GA.Event} KEY_COMMAND - keyboard shortcut * @const * @memberOf Chrome.GA */ const _EVENT = { INSTALLED: { eventCategory: 'extension', eventAction: 'installed', eventLabel: '', }, UPDATED: { eventCategory: 'extension', eventAction: 'updated', eventLabel: '', }, MENU: { eventCategory: 'ui', eventAction: 'menuSelect', eventLabel: '', }, TOGGLE: { eventCategory: 'ui', eventAction: 'toggle', eventLabel: '', }, LINK: { eventCategory: 'ui', eventAction: 'linkSelect', eventLabel: '', }, TEXT: { eventCategory: 'ui', eventAction: 'textChanged', eventLabel: '', }, SLIDER_VALUE: { eventCategory: 'ui', eventAction: 'sliderValueChanged', eventLabel: '', }, SLIDER_UNITS: { eventCategory: 'ui', eventAction: 'sliderUnitsChanged', eventLabel: '', }, BUTTON: { eventCategory: 'ui', eventAction: 'buttonClicked', eventLabel: '', }, ICON: { eventCategory: 'ui', eventAction: 'toolbarIconClicked', eventLabel: '', }, CHECK: { eventCategory: 'ui', eventAction: 'checkBoxClicked', eventLabel: '', }, KEY_COMMAND: { eventCategory: 'ui', eventAction: 'keyCommand', eventLabel: '', }, }; return { EVENT: _EVENT, /** * Initialize analytics * @param {string} trackingId - tracking id * @param {string} appName - extension name * @param {string} appId - extension Id * @param {string} appVersion - extension version * @memberOf Chrome.GA */ initialize: function(trackingId, appName, appId, appVersion) { ga('create', trackingId, 'auto'); // see: http://stackoverflow.com/a/22152353/1958200 ga('set', 'checkProtocolTask', function() { }); ga('set', 'appName', appName); ga('set', 'appId', appId); ga('set', 'appVersion', appVersion); ga('require', 'displayfeatures'); }, /** * Send a page * @param {string} page - page path * @memberOf Chrome.GA */ page: function(page) { if (page) { if (!Chrome.Utils.DEBUG) { ga('send', 'pageview', page); } } }, /** * Send an event * @param {Chrome.GA.Event} event - the event type * @param {?string} [label=null] - override label * @param {?string} [action=null] - override action * @memberOf Chrome.GA */ event: function(event, label = null, action = null) { if (event) { const ev = Chrome.JSONUtils.shallowCopy(event); ev.hitType = 'event'; ev.eventLabel = label ? label : ev.eventLabel; ev.eventAction = action ? action : ev.eventAction; if (!Chrome.Utils.DEBUG) { ga('send', ev); } else { // eslint-disable-next-line no-console console.log(ev); } } }, /** * Send an error * @param {?string} [label='unknown'] - override label * @param {?string} [action='unknownMethod'] - override action * @memberOf Chrome.GA */ error: function(label = 'unknown', action = 'unknownMethod') { const ev = { hitType: 'event', eventCategory: 'error', eventAction: action, eventLabel: `Err: ${label}`, }; if (!Chrome.Utils.DEBUG) { ga('send', ev); } else { console.error(ev); } }, /** * Send an exception * @param {Object} exception - the exception * @param {?string} [message=null] - the error message * @param {boolean} [fatal=true] - true if fatal * @memberOf Chrome.GA */ exception: function(exception, message = null, fatal = false) { try { let msg = 'Unknown'; if (message) { msg = message; } else if (exception.message) { msg = exception.message; } if (exception.stack) { msg += `\n\n${exception.stack}`; } const ex = { hitType: 'exception', exDescription: msg, exFatal: fatal, }; if (!Chrome.Utils.DEBUG) { ga('send', ex); } else { console.error(ex); } } catch (err) { Chrome.Utils.noop(); } }, }; })();