| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635 |
- var _excluded = ["category", "action", "label", "value", "nonInteraction", "transport"];
-
- function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
-
- function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
-
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
-
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
-
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
-
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
-
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
-
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
-
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
-
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
-
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
-
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
-
- /**
- * React Google Analytics Module
- *
- * @package react-ga
- * @author Adam Lofting <adam@mozillafoundation.org>
- * Atul Varma <atul@mozillafoundation.org>
- */
-
- /**
- * Utilities
- */
- import format from './utils/format';
- import removeLeadingSlash from './utils/removeLeadingSlash';
- import trim from './utils/trim';
- import loadGA from './utils/loadGA';
- import warn from './utils/console/warn';
- import log from './utils/console/log';
- import TestModeAPI from './utils/testModeAPI';
-
- var _isNotBrowser = typeof window === 'undefined' || typeof document === 'undefined';
-
- var _debug = false;
- var _titleCase = true;
- var _testMode = false;
- var _alwaysSendToDefaultTracker = true;
- var _redactEmail = true;
-
- var internalGa = function internalGa() {
- var _window;
-
- if (_testMode) return TestModeAPI.ga.apply(TestModeAPI, arguments);
- if (_isNotBrowser) return false;
- if (!window.ga) return warn('ReactGA.initialize must be called first or GoogleAnalytics should be loaded manually');
- return (_window = window).ga.apply(_window, arguments);
- };
-
- function _format(s) {
- return format(s, _titleCase, _redactEmail);
- }
-
- function _gaCommand(trackerNames) {
- for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- args[_key - 1] = arguments[_key];
- }
-
- var command = args[0];
-
- if (typeof internalGa === 'function') {
- if (typeof command !== 'string') {
- warn('ga command must be a string');
- return;
- }
-
- if (_alwaysSendToDefaultTracker || !Array.isArray(trackerNames)) internalGa.apply(void 0, args);
-
- if (Array.isArray(trackerNames)) {
- trackerNames.forEach(function (name) {
- internalGa.apply(void 0, _toConsumableArray(["".concat(name, ".").concat(command)].concat(args.slice(1))));
- });
- }
- }
- }
-
- function _initialize(gaTrackingID, options) {
- if (!gaTrackingID) {
- warn('gaTrackingID is required in initialize()');
- return;
- }
-
- if (options) {
- if (options.debug && options.debug === true) {
- _debug = true;
- }
-
- if (options.titleCase === false) {
- _titleCase = false;
- }
-
- if (options.redactEmail === false) {
- _redactEmail = false;
- }
-
- if (options.useExistingGa) {
- return;
- }
- }
-
- if (options && options.gaOptions) {
- internalGa('create', gaTrackingID, options.gaOptions);
- } else {
- internalGa('create', gaTrackingID, 'auto');
- }
- }
-
- export function addTrackers(configsOrTrackingId, options) {
- if (Array.isArray(configsOrTrackingId)) {
- configsOrTrackingId.forEach(function (config) {
- if (_typeof(config) !== 'object') {
- warn('All configs must be an object');
- return;
- }
-
- _initialize(config.trackingId, config);
- });
- } else {
- _initialize(configsOrTrackingId, options);
- }
-
- return true;
- }
- export function initialize(configsOrTrackingId, options) {
- if (options && options.testMode === true) {
- _testMode = true;
- } else {
- if (_isNotBrowser) {
- return;
- }
-
- if (!options || options.standardImplementation !== true) loadGA(options);
- }
-
- _alwaysSendToDefaultTracker = options && typeof options.alwaysSendToDefaultTracker === 'boolean' ? options.alwaysSendToDefaultTracker : true;
- addTrackers(configsOrTrackingId, options);
- }
- /**
- * ga:
- * Returns the original GA object.
- */
-
- export function ga() {
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- if (args.length > 0) {
- internalGa.apply(void 0, args);
-
- if (_debug) {
- log("called ga('arguments');");
- log("with arguments: ".concat(JSON.stringify(args)));
- }
- }
-
- return window.ga;
- }
- /**
- * set:
- * GA tracker set method
- * @param {Object} fieldsObject - a field/value pair or a group of field/value pairs on the tracker
- * @param {Array} trackerNames - (optional) a list of extra trackers to run the command on
- */
-
- export function set(fieldsObject, trackerNames) {
- if (!fieldsObject) {
- warn('`fieldsObject` is required in .set()');
- return;
- }
-
- if (_typeof(fieldsObject) !== 'object') {
- warn('Expected `fieldsObject` arg to be an Object');
- return;
- }
-
- if (Object.keys(fieldsObject).length === 0) {
- warn('empty `fieldsObject` given to .set()');
- }
-
- _gaCommand(trackerNames, 'set', fieldsObject);
-
- if (_debug) {
- log("called ga('set', fieldsObject);");
- log("with fieldsObject: ".concat(JSON.stringify(fieldsObject)));
- }
- }
- /**
- * send:
- * Clone of the low level `ga.send` method
- * WARNING: No validations will be applied to this
- * @param {Object} fieldObject - field object for tracking different analytics
- * @param {Array} trackerNames - trackers to send the command to
- * @param {Array} trackerNames - (optional) a list of extra trackers to run the command on
- */
-
- export function send(fieldObject, trackerNames) {
- _gaCommand(trackerNames, 'send', fieldObject);
-
- if (_debug) {
- log("called ga('send', fieldObject);");
- log("with fieldObject: ".concat(JSON.stringify(fieldObject)));
- log("with trackers: ".concat(JSON.stringify(trackerNames)));
- }
- }
- /**
- * pageview:
- * Basic GA pageview tracking
- * @param {String} path - the current page page e.g. '/about'
- * @param {Array} trackerNames - (optional) a list of extra trackers to run the command on
- * @param {String} title - (optional) the page title e. g. 'My Website'
- */
-
- export function pageview(rawPath, trackerNames, title) {
- if (!rawPath) {
- warn('path is required in .pageview()');
- return;
- }
-
- var path = trim(rawPath);
-
- if (path === '') {
- warn('path cannot be an empty string in .pageview()');
- return;
- }
-
- var extraFields = {};
-
- if (title) {
- extraFields.title = title;
- }
-
- if (typeof ga === 'function') {
- _gaCommand(trackerNames, 'send', _objectSpread({
- hitType: 'pageview',
- page: path
- }, extraFields));
-
- if (_debug) {
- log("called ga('send', 'pageview', path);");
- var extraLog = '';
-
- if (title) {
- extraLog = " and title: ".concat(title);
- }
-
- log("with path: ".concat(path).concat(extraLog));
- }
- }
- }
- /**
- * modalview:
- * a proxy to basic GA pageview tracking to consistently track
- * modal views that are an equivalent UX to a traditional pageview
- * @param {String} modalName e.g. 'add-or-edit-club'
- * @param {Array} trackerNames - (optional) a list of extra trackers to run the command on
- */
-
- export function modalview(rawModalName, trackerNames) {
- if (!rawModalName) {
- warn('modalName is required in .modalview(modalName)');
- return;
- }
-
- var modalName = removeLeadingSlash(trim(rawModalName));
-
- if (modalName === '') {
- warn('modalName cannot be an empty string or a single / in .modalview()');
- return;
- }
-
- if (typeof ga === 'function') {
- var path = "/modal/".concat(modalName);
-
- _gaCommand(trackerNames, 'send', 'pageview', path);
-
- if (_debug) {
- log("called ga('send', 'pageview', path);");
- log("with path: ".concat(path));
- }
- }
- }
- /**
- * timing:
- * GA timing
- * @param args.category {String} required
- * @param args.variable {String} required
- * @param args.value {Int} required
- * @param args.label {String} required
- * @param {Array} trackerNames - (optional) a list of extra trackers to run the command on
- */
-
- export function timing() {
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- category = _ref.category,
- variable = _ref.variable,
- value = _ref.value,
- label = _ref.label;
-
- var trackerNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
-
- if (typeof ga === 'function') {
- if (!category || !variable || typeof value !== 'number') {
- warn('args.category, args.variable ' + 'AND args.value are required in timing() ' + 'AND args.value has to be a number');
- return;
- } // Required Fields
-
-
- var fieldObject = {
- hitType: 'timing',
- timingCategory: _format(category),
- timingVar: _format(variable),
- timingValue: value
- };
-
- if (label) {
- fieldObject.timingLabel = _format(label);
- }
-
- send(fieldObject, trackerNames);
- }
- }
- /**
- * event:
- * GA event tracking
- * @param args.category {String} required
- * @param args.action {String} required
- * @param args.label {String} optional
- * @param args.value {Int} optional
- * @param args.nonInteraction {boolean} optional
- * @param args.transport {string} optional
- * @param {{action: string, category: string}} trackerNames - (optional) a list of extra trackers to run the command on
- */
-
- export function event() {
- var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
- category = _ref2.category,
- action = _ref2.action,
- label = _ref2.label,
- value = _ref2.value,
- nonInteraction = _ref2.nonInteraction,
- transport = _ref2.transport,
- args = _objectWithoutProperties(_ref2, _excluded);
-
- var trackerNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
-
- if (typeof ga === 'function') {
- // Simple Validation
- if (!category || !action) {
- warn('args.category AND args.action are required in event()');
- return;
- } // Required Fields
-
-
- var fieldObject = {
- hitType: 'event',
- eventCategory: _format(category),
- eventAction: _format(action)
- }; // Optional Fields
-
- if (label) {
- fieldObject.eventLabel = _format(label);
- }
-
- if (typeof value !== 'undefined') {
- if (typeof value !== 'number') {
- warn('Expected `args.value` arg to be a Number.');
- } else {
- fieldObject.eventValue = value;
- }
- }
-
- if (typeof nonInteraction !== 'undefined') {
- if (typeof nonInteraction !== 'boolean') {
- warn('`args.nonInteraction` must be a boolean.');
- } else {
- fieldObject.nonInteraction = nonInteraction;
- }
- }
-
- if (typeof transport !== 'undefined') {
- if (typeof transport !== 'string') {
- warn('`args.transport` must be a string.');
- } else {
- if (['beacon', 'xhr', 'image'].indexOf(transport) === -1) {
- warn('`args.transport` must be either one of these values: `beacon`, `xhr` or `image`');
- }
-
- fieldObject.transport = transport;
- }
- }
-
- Object.keys(args).filter(function (key) {
- return key.substr(0, 'dimension'.length) === 'dimension';
- }).forEach(function (key) {
- fieldObject[key] = args[key];
- });
- Object.keys(args).filter(function (key) {
- return key.substr(0, 'metric'.length) === 'metric';
- }).forEach(function (key) {
- fieldObject[key] = args[key];
- }); // Send to GA
-
- send(fieldObject, trackerNames);
- }
- }
- /**
- * exception:
- * GA exception tracking
- * @param args.description {String} optional
- * @param args.fatal {boolean} optional
- * @param {Array} trackerNames - (optional) a list of extra trackers to run the command on
- */
-
- export function exception(_ref3, trackerNames) {
- var description = _ref3.description,
- fatal = _ref3.fatal;
-
- if (typeof ga === 'function') {
- // Required Fields
- var fieldObject = {
- hitType: 'exception'
- }; // Optional Fields
-
- if (description) {
- fieldObject.exDescription = _format(description);
- }
-
- if (typeof fatal !== 'undefined') {
- if (typeof fatal !== 'boolean') {
- warn('`args.fatal` must be a boolean.');
- } else {
- fieldObject.exFatal = fatal;
- }
- } // Send to GA
-
-
- send(fieldObject, trackerNames);
- }
- }
- export var plugin = {
- /**
- * require:
- * GA requires a plugin
- * @param name {String} e.g. 'ecommerce' or 'myplugin'
- * @param options {Object} optional e.g {path: '/log', debug: true}
- * @param trackerName {String} optional e.g 'trackerName'
- */
- require: function require(rawName, options, trackerName) {
- if (typeof ga === 'function') {
- // Required Fields
- if (!rawName) {
- warn('`name` is required in .require()');
- return;
- }
-
- var name = trim(rawName);
-
- if (name === '') {
- warn('`name` cannot be an empty string in .require()');
- return;
- }
-
- var requireString = trackerName ? "".concat(trackerName, ".require") : 'require'; // Optional Fields
-
- if (options) {
- if (_typeof(options) !== 'object') {
- warn('Expected `options` arg to be an Object');
- return;
- }
-
- if (Object.keys(options).length === 0) {
- warn('Empty `options` given to .require()');
- }
-
- ga(requireString, name, options);
-
- if (_debug) {
- log("called ga('require', '".concat(name, "', ").concat(JSON.stringify(options)));
- }
- } else {
- ga(requireString, name);
-
- if (_debug) {
- log("called ga('require', '".concat(name, "');"));
- }
- }
- }
- },
-
- /**
- * execute:
- * GA execute action for plugin
- * Takes variable number of arguments
- * @param pluginName {String} e.g. 'ecommerce' or 'myplugin'
- * @param action {String} e.g. 'addItem' or 'myCustomAction'
- * @param actionType {String} optional e.g. 'detail'
- * @param payload {Object} optional e.g { id: '1x5e', name : 'My product to track' }
- */
- execute: function execute(pluginName, action) {
- var payload;
- var actionType;
-
- for (var _len3 = arguments.length, args = new Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) {
- args[_key3 - 2] = arguments[_key3];
- }
-
- if (args.length === 1) {
- payload = args[0];
- } else {
- actionType = args[0];
- payload = args[1];
- }
-
- if (typeof ga === 'function') {
- if (typeof pluginName !== 'string') {
- warn('Expected `pluginName` arg to be a String.');
- } else if (typeof action !== 'string') {
- warn('Expected `action` arg to be a String.');
- } else {
- var command = "".concat(pluginName, ":").concat(action);
- payload = payload || null;
-
- if (actionType && payload) {
- ga(command, actionType, payload);
-
- if (_debug) {
- log("called ga('".concat(command, "');"));
- log("actionType: \"".concat(actionType, "\" with payload: ").concat(JSON.stringify(payload)));
- }
- } else if (payload) {
- ga(command, payload);
-
- if (_debug) {
- log("called ga('".concat(command, "');"));
- log("with payload: ".concat(JSON.stringify(payload)));
- }
- } else {
- ga(command);
-
- if (_debug) {
- log("called ga('".concat(command, "');"));
- }
- }
- }
- }
- }
- };
- /**
- * outboundLink:
- * GA outboundLink tracking
- * @param args.label {String} e.g. url, or 'Create an Account'
- * @param {function} hitCallback - Called after processing a hit.
- */
-
- export function outboundLink(args, hitCallback, trackerNames) {
- if (typeof hitCallback !== 'function') {
- warn('hitCallback function is required');
- return;
- }
-
- if (typeof ga === 'function') {
- // Simple Validation
- if (!args || !args.label) {
- warn('args.label is required in outboundLink()');
- return;
- } // Required Fields
-
-
- var fieldObject = {
- hitType: 'event',
- eventCategory: 'Outbound',
- eventAction: 'Click',
- eventLabel: _format(args.label)
- };
- var safetyCallbackCalled = false;
-
- var safetyCallback = function safetyCallback() {
- // This prevents a delayed response from GA
- // causing hitCallback from being fired twice
- safetyCallbackCalled = true;
- hitCallback();
- }; // Using a timeout to ensure the execution of critical application code
- // in the case when the GA server might be down
- // or an ad blocker prevents sending the data
- // register safety net timeout:
-
-
- var t = setTimeout(safetyCallback, 250);
-
- var clearableCallbackForGA = function clearableCallbackForGA() {
- clearTimeout(t);
-
- if (!safetyCallbackCalled) {
- hitCallback();
- }
- };
-
- fieldObject.hitCallback = clearableCallbackForGA; // Send to GA
-
- send(fieldObject, trackerNames);
- } else {
- // if ga is not defined, return the callback so the application
- // continues to work as expected
- setTimeout(hitCallback, 0);
- }
- }
- export var testModeAPI = TestModeAPI;
- export default {
- initialize: initialize,
- ga: ga,
- set: set,
- send: send,
- pageview: pageview,
- modalview: modalview,
- timing: timing,
- event: event,
- exception: exception,
- plugin: plugin,
- outboundLink: outboundLink,
- testModeAPI: TestModeAPI
- };
|