/*
* 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();
}
},
};
})();