From 87a2147b395fe70d23a8a70ea801ee956365d188 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 17:37:26 -0700 Subject: [PATCH 01/30] WEB-1471:ADD: Apache license modification notice --- bin/build.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/build.js b/bin/build.js index fba6ebd..d2b90ce 100644 --- a/bin/build.js +++ b/bin/build.js @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * Modifications Copyright (C) 2017 Anki, Inc. */ From 266b63e8755eab0729f765830fd74a0c6205bbc5 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 17:37:50 -0700 Subject: [PATCH 02/30] WEB-1471:FIX: Example in readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8d08434..24191eb 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ For details on how `analytics.js` plugin methods work and how to invoke them, se ### Setting a Custom Dimension at every hit: -This example sets a Custom Dimension `dimension2` at every Hit: +This example sets a Custom Dimension `dimension2` at every Hit: ```js var index = 1; @@ -59,8 +59,8 @@ This example delegates the generation of the value for the Custom Dimension to a ```js var index = 2; - ga('gaTaskManager:setCustomDimension', index, function(){ - return Date.now() / 1000 | 0; + ga('gaTaskManager:setCustomDimension', index, function(){ + return Date.now() / 1000 | 0; }); ``` @@ -71,7 +71,7 @@ This example adds an arbitrary function to be executed after sending the normal request to www.google-analytics.com/collect. ```js -ga('gaTaskManager:addFunctionToTask', function(model) { +ga('gaTaskManager:addFunctionToTask', 'sendHitTask', 'sendHitToMyServer', function(model) { // Send a copy of the request to a local server var xhr = new XMLHttpRequest(); xhr.open('POST', '/localhits', true); From 21bdca68e0a15e96346e1b3b2069ad2581636267 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 17:39:30 -0700 Subject: [PATCH 03/30] WEB-1471:ADD: Apache license --- LICENSE | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b9bce91 --- /dev/null +++ b/LICENSE @@ -0,0 +1,13 @@ +Copyright 2018 Anki, Inc. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. From 6affd38c12f067710824602bff95283590ce488e Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 17:40:42 -0700 Subject: [PATCH 04/30] WEB-1471:ADD: Apache license modification notice --- lib/provide.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/provide.js b/lib/provide.js index f5da89a..19d51a1 100644 --- a/lib/provide.js +++ b/lib/provide.js @@ -12,6 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * Modifications Copyright (C) 2017 Anki, Inc */ From 60b4f26b8c3c094602d9cd8321dfcf299c42b08c Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 18:13:30 -0700 Subject: [PATCH 05/30] WEB-1471:FIX: Copyright notice --- lib/utilities.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/utilities.js b/lib/utilities.js index 8d93e9f..2a6ab55 100644 --- a/lib/utilities.js +++ b/lib/utilities.js @@ -12,8 +12,8 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * - * Modifications Copyright (C) 2017 Anki, Inc. + * + * Modifications Copyright (C) 2018 Anki, Inc. */ /** From d89cf61bace675d91cd22624c1b3764264da2448 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 18:14:02 -0700 Subject: [PATCH 06/30] WEB-1471:FIX: Use placeholder for GA Property ID --- ga-task-manager.html | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ga-task-manager.html b/ga-task-manager.html index b871397..0f5c830 100644 --- a/ga-task-manager.html +++ b/ga-task-manager.html @@ -6,18 +6,18 @@ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();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'); - + // Anki Test Property - ga('create', 'UA-40941061-3', 'auto'); - + ga('create', 'GA-PROPERTY-ID', 'auto'); + // Require the plugin ga('require', 'gaTaskManager'); - + // Add a function to customTask ga('gaTaskManager:addFunctionToTask', 'customTask', 'logShinyString', function(model){ console.log("Look at my shiny new random customTask"); }); - + // Add a second function to customTask ga('gaTaskManager:addFunctionToTask', 'customTask', 'logShinyStringAgain', function(model){ console.log("Look at my shiny second random customTask which will be executed after the first!"); @@ -25,7 +25,7 @@ // Set Dimensions with a static string value ga('gaTaskManager:setCustomDimension', 1, 14) - + // Set Dimensions with function to return the value at time of execution ga('gaTaskManager:setCustomDimension', 2, function(){return Date.now() / 1000 | 0}) From d252abae4a96083d1d80ff0ccc8c7a33d0563cf5 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 19:49:12 -0700 Subject: [PATCH 07/30] WEB-1471:FIX: Typo --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07ae223..bb81c39 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ ], "author": { "name": "Vinnie Frietas", - "email": "vinnie.freitas@gmail.com", + "email": "vinnie.freitas@gmail.com" }, "homepage": "https://github.com/anki/ga-task-manager#readme", "dependencies": { From 58413cc6d05a68ab1ddf7d0a7d6988de53f1102b Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 19:50:58 -0700 Subject: [PATCH 08/30] WEB-1471:ADD: Docs --- lib/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 49c378d..dacbb3f 100644 --- a/lib/index.js +++ b/lib/index.js @@ -49,12 +49,13 @@ class gaTaskManager { * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension. * If a function is given, it will be executed every time at the moment of task execution. * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs - * @param {string} gaTaskName The name of the GA Task to add the taskFunction to. + * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. */ setCustomDimension(index, value, gaTaskName = 'customTask') { const userTaskName = 'customDimension' + index; this.addFunctionToTask(gaTaskName, userTaskName, function(model){ let auxValue = value; + // If user provided a function to set value at execution time, then type check itsreturn value. if (typeof value == 'function') { auxValue = value(); const auxType = typeof auxValue; @@ -62,6 +63,7 @@ class gaTaskManager { throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.'); } } + // Set the dimension value to be sent to GA. model.set('dimension' + index, auxValue); }); } From 368116e0d4812566efc6215a2097f819d116ecbb Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 19:54:10 -0700 Subject: [PATCH 09/30] WEB-1471:ADD: Add all currently supported GA Tasks --- lib/index.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index dacbb3f..4155b8d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -12,7 +12,20 @@ class gaTaskManager { constructor(tracker) { this.tracker = tracker; this.registry = {}; - this.gaTaskNames = ['customTask', 'sendHitTask']; + // @see https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks + this.gaTaskNames = [ + 'customTask', + 'previewTask', + 'checkProtocolTask', + 'validationTask', + 'checkStorageTask', + 'historyImportTask', + 'samplerTask', + 'buildHitTask', + 'sendHitTask', + 'timingTask', + 'displayFeaturesTask' + ]; // Bind methods. this.addFunctionToTask = this.addFunctionToTask.bind(this); From 6885a35eb8485767a145c947d5f8ff020d8f3c3b Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 19:55:35 -0700 Subject: [PATCH 10/30] WEB-1471:ADD: input safety for addFunctionToTask --- lib/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/index.js b/lib/index.js index 4155b8d..32771ca 100644 --- a/lib/index.js +++ b/lib/index.js @@ -53,6 +53,7 @@ class gaTaskManager { * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution. */ addFunctionToTask(gaTaskName, userTaskName, taskFunction) { + if (this.registry[gaTaskName]) { this.registry[gaTaskName].push({name: userTaskName, func: taskFunction}); } From d5b760f83ebcd39a1774857882bbb5badc9726aa Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 19:58:10 -0700 Subject: [PATCH 11/30] WEB-1471:ADD: API method to remove previously added function from a Task --- lib/index.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/index.js b/lib/index.js index 32771ca..41cea51 100644 --- a/lib/index.js +++ b/lib/index.js @@ -29,6 +29,7 @@ class gaTaskManager { // Bind methods. this.addFunctionToTask = this.addFunctionToTask.bind(this); + this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this); this.setCustomDimension = this.setCustomDimension.bind(this); this.gaTaskNames.forEach((gaTaskName) => { @@ -56,6 +57,23 @@ class gaTaskManager { if (this.registry[gaTaskName]) { this.registry[gaTaskName].push({name: userTaskName, func: taskFunction}); } + } + + /** + * Removes a function from the specified GA Task by the name given by the user. + * @param {string} gaTaskName The name of the GA Task to remove the task from. + * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask. + */ + removeFunctionFromTask(gaTaskName, userTaskName) { + if (this.registry[gaTaskName]) { + var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){ + return userTask.name === userTaskName; + }); + if (userTaskIndex > -1) { + this.registry[gaTaskName].splice(userTaskIndex, 1); + } + } + } /** * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task. From e0aaf0e2cc23b5d33a64af1227730e8c367bfe27 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 19:59:15 -0700 Subject: [PATCH 12/30] WEB-1471:ADD: API method to unset a previously added custom dimension set from a Task --- lib/index.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/index.js b/lib/index.js index 41cea51..437b00e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -31,6 +31,7 @@ class gaTaskManager { this.addFunctionToTask = this.addFunctionToTask.bind(this); this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this); this.setCustomDimension = this.setCustomDimension.bind(this); + this.unsetCustomDimension = this.unsetCustomDimension.bind(this); this.gaTaskNames.forEach((gaTaskName) => { this.registry[gaTaskName] = []; @@ -100,6 +101,16 @@ class gaTaskManager { }); } + /** + * Removes a function added with setCustomDimension. + * @param {string} index The index of your dimension as defined in your Google Analytics property settings. + * @param {string} gaTaskName The name of the GA Task to add the taskFunction to. + */ + unsetCustomDimension(index, gaTaskName = 'customTask') { + const userTaskName = 'customDimension' + index; + this.removeFunctionFromTask(gaTaskName, userTaskName); + } + /** * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required. */ From 687644e4387555b8caf9c3e20e8d452a6608be76 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 20:00:50 -0700 Subject: [PATCH 13/30] WEB-1471:REMOVE: whitespace --- lib/index.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/index.js b/lib/index.js index 437b00e..eb3d68b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -32,7 +32,7 @@ class gaTaskManager { this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this); this.setCustomDimension = this.setCustomDimension.bind(this); this.unsetCustomDimension = this.unsetCustomDimension.bind(this); - + this.gaTaskNames.forEach((gaTaskName) => { this.registry[gaTaskName] = []; // Grab a reference to the default function for this task and register it as the first task. @@ -48,7 +48,7 @@ class gaTaskManager { } /** - * Adds a function to be executed at the specified GA Task. + * Adds a function to be executed at the specified GA Task. * @param {string} gaTaskName The name of the GA Task to add the taskFunction to. * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction. * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName. @@ -56,8 +56,8 @@ class gaTaskManager { */ addFunctionToTask(gaTaskName, userTaskName, taskFunction) { if (this.registry[gaTaskName]) { - this.registry[gaTaskName].push({name: userTaskName, func: taskFunction}); - } + this.registry[gaTaskName].push({name: userTaskName, func: taskFunction}); + } } /** @@ -77,9 +77,9 @@ class gaTaskManager { } /** - * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task. + * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task. * @param {string} index The index of your dimension as defined in your Google Analytics property settings. - * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension. + * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension. * If a function is given, it will be executed every time at the moment of task execution. * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. From 0dae1d45a5d7b29fd24e1e8f9b73a4d601da528a Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 20:02:09 -0700 Subject: [PATCH 14/30] WEB-1471:ADD: New APi methods to html example/test file --- ga-task-manager.html | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ga-task-manager.html b/ga-task-manager.html index 0f5c830..5c77a68 100644 --- a/ga-task-manager.html +++ b/ga-task-manager.html @@ -7,7 +7,6 @@ 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'); - // Anki Test Property ga('create', 'GA-PROPERTY-ID', 'auto'); // Require the plugin @@ -30,6 +29,16 @@ ga('gaTaskManager:setCustomDimension', 2, function(){return Date.now() / 1000 | 0}) ga('send', 'pageview'); + + // Remove logShinyStringAgain function + ga('gaTaskManager:removeFunctionFromTask', 'customTask', 'logShinyStringAgain'); + + // Unset the function setting the dimension at every hit which we added earlier + ga('gaTaskManager:unsetCustomDimension', 1); + + // Trigger a second hit + ga('send', 'pageview'); + From 1a39486d9e41e6e46e754e1f09c19101b64deb86 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 21:39:36 -0700 Subject: [PATCH 15/30] WEB-1471:ADD: New API methods to public interface --- lib/externs/ga-task-manager.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/externs/ga-task-manager.js b/lib/externs/ga-task-manager.js index 56c4d2b..e1661d4 100644 --- a/lib/externs/ga-task-manager.js +++ b/lib/externs/ga-task-manager.js @@ -8,11 +8,21 @@ class GATaskManagerPublicInterface { * @param {function(!Model)} taskFunction */ addFunctionToTask(gaTaskName, userTaskName, taskFunction) {} + /** + * @param {string} gaTaskName + * @param {string} userTaskName + */ + removeFunctionFromTask(gaTaskName, userTaskName) {} /** * @param {string} index * @param {string|number|function(): string|number} value * @param {string} gaTaskName */ setCustomDimension(index, value, gaTaskName) {} + /** + * @param {string} index + * @param {string} gaTaskName + */ + unsetCustomDimension(index, gaTaskName) {} remove() {} } From 6fc654937ee7ce22d3ebb837fb8b662eff6e09d5 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 21:40:18 -0700 Subject: [PATCH 16/30] WEB-1471:CHANGE: Update production distribution files --- ga-task-manager.js | 7 ++++--- ga-task-manager.js.map | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ga-task-manager.js b/ga-task-manager.js index 4ef599c..3fac412 100644 --- a/ga-task-manager.js +++ b/ga-task-manager.js @@ -1,4 +1,5 @@ -(function(){function e(b){var c=this;this.c=b;this.a={};this.b=["customTask","sendHitTask"];this.addFunctionToTask=this.addFunctionToTask.bind(this);this.setCustomDimension=this.setCustomDimension.bind(this);this.b.forEach(function(a){c.a[a]=[];c.addFunctionToTask(a,"original",b.get(a));c.c.set(a,function(b){c.a[a].forEach(function(a){a.f(b)})})})}e.prototype.addFunctionToTask=function(b,c,a){this.a[b].push({name:c,f:a})}; -e.prototype.setCustomDimension=function(b,c,a){this.addFunctionToTask(void 0===a?"customTask":a,"customDimension"+b,function(a){var f=c;if("function"==typeof c){var f=c(),d=typeof f;if("string"!=d&&"number"!=d)throw Error("Function "+c.name+" must return a string or number. Got "+d+"instead.");}a.set("dimension"+b,f)})};e.prototype.remove=function(){var b=this;this.b.forEach(function(c){var a=b.a[c].find(function(a){return"original"==a.name});b.c.set(c,a)})}; -(function(b,c){var a=window.GoogleAnalyticsObject||"ga";window[a]=window[a]||function(c){for(var b=[],d=0;d {\n this.registry[gaTaskName] = [];\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor.\n this.tracker.set(gaTaskName, (model) => {\n this.registry[gaTaskName].forEach((userTask) => {\n userTask.func(model);\n });\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task. \n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n this.registry[gaTaskName].push({name: userTaskName, func: taskFunction});\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task. \n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension. \n * If a function is given, it will be executed every time at the moment of task execution.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to. \n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('gaTaskManager', gaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * \n * Modifications Copyright (C) 2017 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file +{"version":3,"sources":["lib/index.js","lib/provide.js","lib/utilities.js"],"names":["constructor","gaTaskManager","tracker","registry","gaTaskNames","addFunctionToTask","bind","removeFunctionFromTask","setCustomDimension","unsetCustomDimension","forEach","gaTaskName","get","set","model","userTask","func","userTaskName","taskFunction","push","name","userTaskIndex","findIndex","splice","index","value","auxValue","auxType","Error","remove","originalTaskFunction","find","element","provide","pluginName","pluginConstructor","gaAlias","window","GoogleAnalyticsObject","q","args","gaplugins","charAt","toUpperCase","slice"],"mappings":"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","file":"","sourcesContent":["import provide from './provide';\n\n/**\n * Class for the `ga-task-manager` analytics.js plugin.\n * @implements {GATaskManagerPublicInterface}\n */\nclass gaTaskManager {\n /**\n * Registers declarative event tracking.\n * @param {!Tracker} tracker Passed internally by analytics.js\n */\n constructor(tracker) {\n this.tracker = tracker;\n this.registry = {};\n // @see https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks\n this.gaTaskNames = [\n 'customTask',\n 'previewTask',\n 'checkProtocolTask',\n 'validationTask',\n 'checkStorageTask',\n 'historyImportTask',\n 'samplerTask',\n 'buildHitTask',\n 'sendHitTask',\n 'timingTask',\n 'displayFeaturesTask'\n ];\n\n // Bind methods.\n this.addFunctionToTask = this.addFunctionToTask.bind(this);\n this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this);\n this.setCustomDimension = this.setCustomDimension.bind(this);\n this.unsetCustomDimension = this.unsetCustomDimension.bind(this);\n\n this.gaTaskNames.forEach((gaTaskName) => {\n this.registry[gaTaskName] = [];\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor.\n this.tracker.set(gaTaskName, (model) => {\n this.registry[gaTaskName].forEach((userTask) => {\n userTask.func(model);\n });\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName].push({name: userTaskName, func: taskFunction});\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName]) {\n var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){\n return userTask.name === userTaskName;\n });\n if (userTaskIndex > -1) {\n this.registry[gaTaskName].splice(userTaskIndex, 1);\n }\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('gaTaskManager', gaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file From 40bc3984f638dabd669c81e6c56d604281eb8744 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Sun, 18 Mar 2018 23:04:12 -0700 Subject: [PATCH 17/30] WEB-1471:ADD: Automatically cast number value for dimension to a string so that GA doesn't throw warnings --- ga-task-manager.js | 2 +- ga-task-manager.js.map | 2 +- lib/index.js | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ga-task-manager.js b/ga-task-manager.js index 3fac412..5e73d67 100644 --- a/ga-task-manager.js +++ b/ga-task-manager.js @@ -1,5 +1,5 @@ (function(){function e(a){var b=this;this.c=a;this.a={};this.b="customTask previewTask checkProtocolTask validationTask checkStorageTask historyImportTask samplerTask buildHitTask sendHitTask timingTask displayFeaturesTask".split(" ");this.addFunctionToTask=this.addFunctionToTask.bind(this);this.removeFunctionFromTask=this.removeFunctionFromTask.bind(this);this.setCustomDimension=this.setCustomDimension.bind(this);this.unsetCustomDimension=this.unsetCustomDimension.bind(this);this.b.forEach(function(c){b.a[c]= [];b.addFunctionToTask(c,"original",a.get(c));b.c.set(c,function(a){b.a[c].forEach(function(b){b.f(a)})})})}e.prototype.addFunctionToTask=function(a,b,c){this.a[a]&&this.a[a].push({name:b,f:c})};e.prototype.removeFunctionFromTask=function(a,b){if(this.a[a]){var c=this.a[a].findIndex(function(a){return a.name===b});-1 {\n this.registry[gaTaskName] = [];\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor.\n this.tracker.set(gaTaskName, (model) => {\n this.registry[gaTaskName].forEach((userTask) => {\n userTask.func(model);\n });\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName].push({name: userTaskName, func: taskFunction});\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName]) {\n var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){\n return userTask.name === userTaskName;\n });\n if (userTaskIndex > -1) {\n this.registry[gaTaskName].splice(userTaskIndex, 1);\n }\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('gaTaskManager', gaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file +{"version":3,"sources":["lib/index.js","lib/provide.js","lib/utilities.js"],"names":["constructor","gaTaskManager","tracker","registry","gaTaskNames","addFunctionToTask","bind","removeFunctionFromTask","setCustomDimension","unsetCustomDimension","forEach","gaTaskName","get","set","model","userTask","func","userTaskName","taskFunction","push","name","userTaskIndex","findIndex","splice","index","value","auxValue","auxType","Error","toString","remove","originalTaskFunction","find","element","provide","pluginName","pluginConstructor","gaAlias","window","GoogleAnalyticsObject","q","args","gaplugins","charAt","toUpperCase","slice"],"mappings":"A,YAWEA,QALIC,EAKO,CAACC,CAAD,CAAU,CAAA,IAAA,EAAA,IACnB,KAAAA,EAAA,CAAeA,CACf,KAAAC,EAAA,CAAgB,EAEhB,KAAAC,EAAA,CAAmB,gKAAA,MAAA,CAAA,GAAA,CAenB,KAAAC,kBAAA,CAAyB,IAAAA,kBAAAC,KAAA,CAA4B,IAA5B,CACzB,KAAAC,uBAAA,CAA8B,IAAAA,uBAAAD,KAAA,CAAiC,IAAjC,CAC9B,KAAAE,mBAAA,CAA0B,IAAAA,mBAAAF,KAAA,CAA6B,IAA7B,CAC1B,KAAAG,qBAAA,CAA4B,IAAAA,qBAAAH,KAAA,CAA+B,IAA/B,CAE5B,KAAAF,EAAAM,QAAA,CAAyB,QAAA,CAACC,CAAD,CAAgB,CACvC,CAAAR,EAAA,CAAcQ,CAAd,CAAA;AAA4B,EAE5B,EAAAN,kBAAA,CAAuBM,CAAvB,CAAmC,UAAnC,CAA+CT,CAAAU,IAAA,CAAYD,CAAZ,CAA/C,CAGA,EAAAT,EAAAW,IAAA,CAAiBF,CAAjB,CAA6B,QAAA,CAACG,CAAD,CAAW,CACtC,CAAAX,EAAA,CAAcQ,CAAd,CAAAD,QAAA,CAAkC,QAAA,CAACK,CAAD,CAAc,CAC9CA,CAAAC,EAAA,CAAcF,CAAd,CAD8C,CAAhD,CADsC,CAAxC,CANuC,CAAzC,CAxBmB,CA6CrB,CAAA,UAAA,kBAAA,CAAAT,QAAiB,CAACM,CAAD,CAAaM,CAAb,CAA2BC,CAA3B,CAAyC,CACpD,IAAAf,EAAA,CAAcQ,CAAd,CAAJ,EACE,IAAAR,EAAA,CAAcQ,CAAd,CAAAQ,KAAA,CAA+B,CAACC,KAAMH,CAAP,CAAqBD,EAAME,CAA3B,CAA/B,CAFsD,CAW1D,EAAA,UAAA,uBAAA,CAAAX,QAAsB,CAACI,CAAD,CAAaM,CAAb,CAA2B,CAC/C,GAAI,IAAAd,EAAA,CAAcQ,CAAd,CAAJ,CAA+B,CAC7B,IAAIU,EAAgB,IAAAlB,EAAA,CAAcQ,CAAd,CAAAW,UAAA,CAAoC,QAAA,CAASP,CAAT,CAAkB,CACxE,MAAOA,EAAAK,KAAP,GAAyBH,CAD+C,CAAtD,CAGC,GAArB,CAAII,CAAJ,EACE,IAAAlB,EAAA,CAAcQ,CAAd,CAAAY,OAAA,CAAiCF,CAAjC,CAAgD,CAAhD,CAL2B,CADgB,CAoBjD;CAAA,UAAA,mBAAA,CAAAb,QAAkB,CAACgB,CAAD,CAAQC,CAAR,CAAed,CAAf,CAA0C,CAE1D,IAAAN,kBAAA,CAF+B,IAAA,EAAAM,GAAAA,CAAAA,CAAa,YAAbA,CAAAA,CAE/B,CADqB,iBACrB,CADyCa,CACzC,CAAiD,QAAA,CAASV,CAAT,CAAe,CAC5D,IAAIY,EAAWD,CAEf,IAAoB,UAApB,EAAI,MAAOA,EAAX,CAAgC,CAC9B,IAAAC,EAAWD,CAAA,EAAX,CACME,EAAU,MAAOD,EACvB,IAAe,QAAf,EAAIC,CAAJ,EAAsC,QAAtC,EAA2BA,CAA3B,CACE,KAAUC,MAAJ,CAAU,WAAV,CAAwBH,CAAAL,KAAxB,CAAqC,uCAArC,CAA+EO,CAA/E,CAAyF,UAAzF,CAAN,CAJ4B,CAQR,QAAxB,GAAI,MAAOD,EAAX,GAAkCA,CAAlC,CAA6CA,CAAAG,SAAA,EAA7C,CAGAf,EAAAD,IAAA,CAAU,WAAV,CAAwBW,CAAxB,CAA+BE,CAA/B,CAd4D,CAAhE,CAF0D,CAyB5D,EAAA,UAAA,qBAAA,CAAAjB,QAAoB,CAACe,CAAD,CAAQb,CAAR,CAAmC,CAErD,IAAAJ,uBAAA,CAF0B,IAAA,EAAAI,GAAAA,CAAAA,CAAa,YAAbA,CAAAA,CAE1B,CADqB,iBACrB,CADyCa,CACzC,CAFqD,CAQvD;CAAA,UAAA,OAAA,CAAAM,QAAM,EAAG,CAAA,IAAA,EAAA,IACP,KAAA1B,EAAAM,QAAA,CAAyB,QAAA,CAACC,CAAD,CAAgB,CACvC,IAAMoB,EAAuB,CAAA5B,EAAA,CAAcQ,CAAd,CAAAqB,KAAA,CAA+B,QAAA,CAACC,CAAD,CAAa,CACvE,MAAuB,UAAvB,EAAOA,CAAAb,KADgE,CAA5C,CAG7B,EAAAlB,EAAAW,IAAA,CAAiBF,CAAjB,CAA6BoB,CAA7B,CAJuC,CAAzC,CADO,CC5FXG,UAA+B,CAACC,CAAD,CAAaC,CAAb,CAAgC,CAC7D,IAAMC,EAAUC,MAAAC,sBAAVF,EAA0C,IAChDC,OAAA,CAAOD,CAAP,CAAA,CAAkBC,MAAA,CAAOD,CAAP,CAAlB,EAAqC,QAAA,CAAS,CAAT,CAAkB,CAAT,IAAA,IAAA,EAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,SAAA,OAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,SAAA,CAAA,CAAA,CAC5ClB,EAACmB,MAAA,CAAOD,CAAP,CAAAG,EAADrB,CAAqBmB,MAAA,CAAOD,CAAP,CAAAG,EAArBrB,EAA0C,EAA1CA,MAAA,CADqDsB,CACrD,CADqD,CAKvDH,OAAA,CAAOD,CAAP,CAAA,CAAgB,SAAhB,CAA2BF,CAA3B,CAAuCC,CAAvC,CAGAE,OAAAI,UAAA,CAAmBJ,MAAAI,UAAnB,EAAuC,EACvCJ,OAAAI,UAAA,CAA4BP,CCMrBQ,OAAA,CAAW,CAAX,CAAAC,YAAA,EDNP,CAA4BT,CCMSU,MAAA,CAAU,CAAV,CDNrC,CAAA,CAA2CT,CAXkB,CAA/DF,CDsGA,CAAQ,eAAR,CAAyBjC,CAAzB","file":"","sourcesContent":["import provide from './provide';\n\n/**\n * Class for the `ga-task-manager` analytics.js plugin.\n * @implements {GATaskManagerPublicInterface}\n */\nclass gaTaskManager {\n /**\n * Registers declarative event tracking.\n * @param {!Tracker} tracker Passed internally by analytics.js\n */\n constructor(tracker) {\n this.tracker = tracker;\n this.registry = {};\n // @see https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks\n this.gaTaskNames = [\n 'customTask',\n 'previewTask',\n 'checkProtocolTask',\n 'validationTask',\n 'checkStorageTask',\n 'historyImportTask',\n 'samplerTask',\n 'buildHitTask',\n 'sendHitTask',\n 'timingTask',\n 'displayFeaturesTask'\n ];\n\n // Bind methods.\n this.addFunctionToTask = this.addFunctionToTask.bind(this);\n this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this);\n this.setCustomDimension = this.setCustomDimension.bind(this);\n this.unsetCustomDimension = this.unsetCustomDimension.bind(this);\n\n this.gaTaskNames.forEach((gaTaskName) => {\n this.registry[gaTaskName] = [];\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor.\n this.tracker.set(gaTaskName, (model) => {\n this.registry[gaTaskName].forEach((userTask) => {\n userTask.func(model);\n });\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName].push({name: userTaskName, func: taskFunction});\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName]) {\n var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){\n return userTask.name === userTaskName;\n });\n if (userTaskIndex > -1) {\n this.registry[gaTaskName].splice(userTaskIndex, 1);\n }\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * If a number is given, it will be cast automatically to a string by calling Number.toString() method.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n\n if (typeof auxValue === 'number') auxValue = auxValue.toString();\n\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('gaTaskManager', gaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index eb3d68b..0acf17b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -81,6 +81,7 @@ class gaTaskManager { * @param {string} index The index of your dimension as defined in your Google Analytics property settings. * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension. * If a function is given, it will be executed every time at the moment of task execution. + * If a number is given, it will be cast automatically to a string by calling Number.toString() method. * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. */ @@ -96,6 +97,9 @@ class gaTaskManager { throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.'); } } + + if (typeof auxValue === 'number') auxValue = auxValue.toString(); + // Set the dimension value to be sent to GA. model.set('dimension' + index, auxValue); }); From 8f13d6f14943480f4afad393ebf02abaf048d512 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 00:28:05 -0700 Subject: [PATCH 18/30] WEB-1471:CHANGE: CamelCase on class name and improve docs --- lib/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/index.js b/lib/index.js index 0acf17b..5ce830a 100644 --- a/lib/index.js +++ b/lib/index.js @@ -2,9 +2,9 @@ import provide from './provide'; /** * Class for the `ga-task-manager` analytics.js plugin. - * @implements {GATaskManagerPublicInterface} + * @implements {GaTaskManagerPublicInterface} */ -class gaTaskManager { +class GaTaskManager { /** * Registers declarative event tracking. * @param {!Tracker} tracker Passed internally by analytics.js @@ -83,7 +83,7 @@ class gaTaskManager { * If a function is given, it will be executed every time at the moment of task execution. * If a number is given, it will be cast automatically to a string by calling Number.toString() method. * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs - * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. + * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. Defaults to 'customTask'. */ setCustomDimension(index, value, gaTaskName = 'customTask') { const userTaskName = 'customDimension' + index; @@ -128,4 +128,4 @@ class gaTaskManager { } } -provide('gaTaskManager', gaTaskManager); +provide('GaTaskManager', GaTaskManager); From a3ccebd5b3277ef461b6156011ea70f9872fd380 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 00:39:08 -0700 Subject: [PATCH 19/30] WEB-1471:CHANGE: CamelCase on interface name and rebuilding prod version --- ga-task-manager.js | 2 +- ga-task-manager.js.map | 2 +- lib/externs/ga-task-manager.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ga-task-manager.js b/ga-task-manager.js index 5e73d67..fd57906 100644 --- a/ga-task-manager.js +++ b/ga-task-manager.js @@ -1,5 +1,5 @@ (function(){function e(a){var b=this;this.c=a;this.a={};this.b="customTask previewTask checkProtocolTask validationTask checkStorageTask historyImportTask samplerTask buildHitTask sendHitTask timingTask displayFeaturesTask".split(" ");this.addFunctionToTask=this.addFunctionToTask.bind(this);this.removeFunctionFromTask=this.removeFunctionFromTask.bind(this);this.setCustomDimension=this.setCustomDimension.bind(this);this.unsetCustomDimension=this.unsetCustomDimension.bind(this);this.b.forEach(function(c){b.a[c]= [];b.addFunctionToTask(c,"original",a.get(c));b.c.set(c,function(a){b.a[c].forEach(function(b){b.f(a)})})})}e.prototype.addFunctionToTask=function(a,b,c){this.a[a]&&this.a[a].push({name:b,f:c})};e.prototype.removeFunctionFromTask=function(a,b){if(this.a[a]){var c=this.a[a].findIndex(function(a){return a.name===b});-1 {\n this.registry[gaTaskName] = [];\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor.\n this.tracker.set(gaTaskName, (model) => {\n this.registry[gaTaskName].forEach((userTask) => {\n userTask.func(model);\n });\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName].push({name: userTaskName, func: taskFunction});\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName]) {\n var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){\n return userTask.name === userTaskName;\n });\n if (userTaskIndex > -1) {\n this.registry[gaTaskName].splice(userTaskIndex, 1);\n }\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * If a number is given, it will be cast automatically to a string by calling Number.toString() method.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n\n if (typeof auxValue === 'number') auxValue = auxValue.toString();\n\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('gaTaskManager', gaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file +{"version":3,"sources":["lib/index.js","lib/provide.js","lib/utilities.js"],"names":["constructor","GaTaskManager","tracker","registry","gaTaskNames","addFunctionToTask","bind","removeFunctionFromTask","setCustomDimension","unsetCustomDimension","forEach","gaTaskName","get","set","model","userTask","func","userTaskName","taskFunction","push","name","userTaskIndex","findIndex","splice","index","value","auxValue","auxType","Error","toString","remove","originalTaskFunction","find","element","provide","pluginName","pluginConstructor","gaAlias","window","GoogleAnalyticsObject","q","args","gaplugins","charAt","toUpperCase","slice"],"mappings":"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","file":"","sourcesContent":["import provide from './provide';\n\n/**\n * Class for the `ga-task-manager` analytics.js plugin.\n * @implements {GaTaskManagerPublicInterface}\n */\nclass GaTaskManager {\n /**\n * Registers declarative event tracking.\n * @param {!Tracker} tracker Passed internally by analytics.js\n */\n constructor(tracker) {\n this.tracker = tracker;\n this.registry = {};\n // @see https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks\n this.gaTaskNames = [\n 'customTask',\n 'previewTask',\n 'checkProtocolTask',\n 'validationTask',\n 'checkStorageTask',\n 'historyImportTask',\n 'samplerTask',\n 'buildHitTask',\n 'sendHitTask',\n 'timingTask',\n 'displayFeaturesTask'\n ];\n\n // Bind methods.\n this.addFunctionToTask = this.addFunctionToTask.bind(this);\n this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this);\n this.setCustomDimension = this.setCustomDimension.bind(this);\n this.unsetCustomDimension = this.unsetCustomDimension.bind(this);\n\n this.gaTaskNames.forEach((gaTaskName) => {\n this.registry[gaTaskName] = [];\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor.\n this.tracker.set(gaTaskName, (model) => {\n this.registry[gaTaskName].forEach((userTask) => {\n userTask.func(model);\n });\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName].push({name: userTaskName, func: taskFunction});\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName]) {\n var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){\n return userTask.name === userTaskName;\n });\n if (userTaskIndex > -1) {\n this.registry[gaTaskName].splice(userTaskIndex, 1);\n }\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * If a number is given, it will be cast automatically to a string by calling Number.toString() method.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. Defaults to 'customTask'.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n\n if (typeof auxValue === 'number') auxValue = auxValue.toString();\n\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('GaTaskManager', GaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file diff --git a/lib/externs/ga-task-manager.js b/lib/externs/ga-task-manager.js index e1661d4..a02e207 100644 --- a/lib/externs/ga-task-manager.js +++ b/lib/externs/ga-task-manager.js @@ -1,7 +1,7 @@ /** * @interface */ -class GATaskManagerPublicInterface { +class GaTaskManagerPublicInterface { /** * @param {string} gaTaskName * @param {string} userTaskName From 40a5580ee908f9d14eb0c472d273db948b3e6d2a Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 17:57:31 -0700 Subject: [PATCH 20/30] WEB-1471:ADD: Modification notices --- bin/errors.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/errors.js b/bin/errors.js index d60ce63..3e3a40c 100644 --- a/bin/errors.js +++ b/bin/errors.js @@ -12,12 +12,13 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * Modifications Copyright (C) 2018 Anki, Inc. + * */ const chalk = require('chalk'); - - const log = (msg) => process.stderr.write(msg); From bda447a7a669edd81e358a51c1a66fbf4939ec3a Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 17:58:08 -0700 Subject: [PATCH 21/30] WEB-1471:CHANGE: Modification notice --- bin/build.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/build.js b/bin/build.js index d2b90ce..a6b0bf3 100644 --- a/bin/build.js +++ b/bin/build.js @@ -12,7 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * * Modifications Copyright (C) 2017 Anki, Inc. */ @@ -25,7 +25,6 @@ const fs = require('fs-extra'); const glob = require('glob'); const {compile}= require('google-closure-compiler-js'); const {rollup} = require('rollup'); -const memory = require('rollup-plugin-memory'); const nodeResolve = require('rollup-plugin-node-resolve'); const path = require('path'); const {SourceMapGenerator, SourceMapConsumer} = require('source-map'); @@ -47,7 +46,6 @@ module.exports = (output) => { const externs = glob.sync(path.join(externsDir, '*.js')) .reduce((acc, cur) => acc + fs.readFileSync(cur, 'utf-8'), ''); - const closureFlags = { jsCode: [{ src: rollupResult.code, From ef3d4ed71312118c0abbc29751327d4b110a90c4 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 18:00:01 -0700 Subject: [PATCH 22/30] WEB-1471:CHANGE: Use debug version of GA for testing. --- ga-task-manager.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ga-task-manager.html b/ga-task-manager.html index 5c77a68..e1eea66 100644 --- a/ga-task-manager.html +++ b/ga-task-manager.html @@ -5,7 +5,9 @@ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();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'); + })(window,document,'script','https://www.google-analytics.com/analytics_debug.js','ga'); + + window.ga_debug = {trace: true}; ga('create', 'GA-PROPERTY-ID', 'auto'); From 956d77bae3cf0f13a1bcf794a2ea8e0e97581211 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 18:00:35 -0700 Subject: [PATCH 23/30] WEB-1471:CHANGE: Update plugin name to capitlized --- ga-task-manager.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ga-task-manager.html b/ga-task-manager.html index e1eea66..3122f3d 100644 --- a/ga-task-manager.html +++ b/ga-task-manager.html @@ -12,31 +12,31 @@ ga('create', 'GA-PROPERTY-ID', 'auto'); // Require the plugin - ga('require', 'gaTaskManager'); + ga('require', 'GaTaskManager'); // Add a function to customTask - ga('gaTaskManager:addFunctionToTask', 'customTask', 'logShinyString', function(model){ + ga('GaTaskManager:addFunctionToTask', 'customTask', 'logShinyString', function(model){ console.log("Look at my shiny new random customTask"); }); // Add a second function to customTask - ga('gaTaskManager:addFunctionToTask', 'customTask', 'logShinyStringAgain', function(model){ + ga('GaTaskManager:addFunctionToTask', 'customTask', 'logShinyStringAgain', function(model){ console.log("Look at my shiny second random customTask which will be executed after the first!"); }); // Set Dimensions with a static string value - ga('gaTaskManager:setCustomDimension', 1, 14) + ga('GaTaskManager:setCustomDimension', 1, 14) // Set Dimensions with function to return the value at time of execution - ga('gaTaskManager:setCustomDimension', 2, function(){return Date.now() / 1000 | 0}) + ga('GaTaskManager:setCustomDimension', 2, function(){return Date.now() / 1000 | 0}) ga('send', 'pageview'); // Remove logShinyStringAgain function - ga('gaTaskManager:removeFunctionFromTask', 'customTask', 'logShinyStringAgain'); + ga('GaTaskManager:removeFunctionFromTask', 'customTask', 'logShinyStringAgain'); // Unset the function setting the dimension at every hit which we added earlier - ga('gaTaskManager:unsetCustomDimension', 1); + ga('GaTaskManager:unsetCustomDimension', 1); // Trigger a second hit ga('send', 'pageview'); From f9c2aa02d410307ea2cd8cb731d865f5d601e146 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 18:01:09 -0700 Subject: [PATCH 24/30] WEB-1471:CHANGE: Wait 5 second for second hit in test file --- ga-task-manager.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ga-task-manager.html b/ga-task-manager.html index 3122f3d..ac60f1b 100644 --- a/ga-task-manager.html +++ b/ga-task-manager.html @@ -38,8 +38,10 @@ // Unset the function setting the dimension at every hit which we added earlier ga('GaTaskManager:unsetCustomDimension', 1); - // Trigger a second hit + // Trigger a second hit after 5 seconds + setTimeout(function () { ga('send', 'pageview'); + }, 5000); From a67ca007090c2600b23647095a3dca7d9b54fcca Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 18:04:46 -0700 Subject: [PATCH 25/30] WEB-1471:CHANGE: Internal registry to use objects instead of arrays. --- ga-task-manager.js | 8 ++++---- ga-task-manager.js.map | 2 +- lib/index.js | 23 ++++++++++------------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/ga-task-manager.js b/ga-task-manager.js index fd57906..ca925a0 100644 --- a/ga-task-manager.js +++ b/ga-task-manager.js @@ -1,5 +1,5 @@ -(function(){function e(a){var b=this;this.c=a;this.a={};this.b="customTask previewTask checkProtocolTask validationTask checkStorageTask historyImportTask samplerTask buildHitTask sendHitTask timingTask displayFeaturesTask".split(" ");this.addFunctionToTask=this.addFunctionToTask.bind(this);this.removeFunctionFromTask=this.removeFunctionFromTask.bind(this);this.setCustomDimension=this.setCustomDimension.bind(this);this.unsetCustomDimension=this.unsetCustomDimension.bind(this);this.b.forEach(function(c){b.a[c]= -[];b.addFunctionToTask(c,"original",a.get(c));b.c.set(c,function(a){b.a[c].forEach(function(b){b.f(a)})})})}e.prototype.addFunctionToTask=function(a,b,c){this.a[a]&&this.a[a].push({name:b,f:c})};e.prototype.removeFunctionFromTask=function(a,b){if(this.a[a]){var c=this.a[a].findIndex(function(a){return a.name===b});-1 {\n this.registry[gaTaskName] = [];\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor.\n this.tracker.set(gaTaskName, (model) => {\n this.registry[gaTaskName].forEach((userTask) => {\n userTask.func(model);\n });\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName].push({name: userTaskName, func: taskFunction});\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName]) {\n var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){\n return userTask.name === userTaskName;\n });\n if (userTaskIndex > -1) {\n this.registry[gaTaskName].splice(userTaskIndex, 1);\n }\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * If a number is given, it will be cast automatically to a string by calling Number.toString() method.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. Defaults to 'customTask'.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n\n if (typeof auxValue === 'number') auxValue = auxValue.toString();\n\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('GaTaskManager', GaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file +{"version":3,"sources":["lib/index.js","lib/provide.js","lib/utilities.js"],"names":["constructor","GaTaskManager","tracker","registry","gaTaskNames","addFunctionToTask","bind","removeFunctionFromTask","setCustomDimension","unsetCustomDimension","forEach","gaTaskName","get","set","model","userTask","hasOwnProperty","userTaskName","taskFunction","index","value","auxValue","auxType","Error","name","toString","remove","originalTaskFunction","find","element","provide","pluginName","pluginConstructor","gaAlias","window","GoogleAnalyticsObject","push","q","args","gaplugins","charAt","toUpperCase","slice"],"mappings":"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","file":"","sourcesContent":["import provide from './provide';\n\n/**\n * Class for the `ga-task-manager` analytics.js plugin.\n * @implements {GaTaskManagerPublicInterface}\n */\nclass GaTaskManager {\n /**\n * Registers declarative event tracking.\n * @param {!Tracker} tracker Passed internally by analytics.js\n */\n constructor(tracker) {\n this.tracker = tracker;\n this.registry = {};\n // @see https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks\n this.gaTaskNames = [\n 'customTask',\n 'previewTask',\n 'checkProtocolTask',\n 'validationTask',\n 'checkStorageTask',\n 'historyImportTask',\n 'samplerTask',\n 'buildHitTask',\n 'sendHitTask',\n 'timingTask',\n 'displayFeaturesTask'\n ];\n\n // Bind methods.\n this.addFunctionToTask = this.addFunctionToTask.bind(this);\n this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this);\n this.setCustomDimension = this.setCustomDimension.bind(this);\n this.unsetCustomDimension = this.unsetCustomDimension.bind(this);\n\n this.gaTaskNames.forEach((gaTaskName) => {\n this.registry[gaTaskName] = {};\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor which calls all user tasks added to the registry.\n this.tracker.set(gaTaskName, (model) => {\n for (var userTask in this.registry[gaTaskName]) {\n if (this.registry[gaTaskName].hasOwnProperty(userTask)) {\n this.registry[gaTaskName][userTask](model);\n }\n }\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName][userTaskName] = taskFunction;\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName] && this.registry[gaTaskName][userTaskName]) {\n delete this.registry[gaTaskName][userTaskName];\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * If a number is given, it will be cast automatically to a string by calling Number.toString() method.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. Defaults to 'customTask'.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n\n if (typeof auxValue === 'number') auxValue = auxValue.toString();\n\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('GaTaskManager', GaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index 5ce830a..9210b26 100644 --- a/lib/index.js +++ b/lib/index.js @@ -34,15 +34,17 @@ class GaTaskManager { this.unsetCustomDimension = this.unsetCustomDimension.bind(this); this.gaTaskNames.forEach((gaTaskName) => { - this.registry[gaTaskName] = []; + this.registry[gaTaskName] = {}; // Grab a reference to the default function for this task and register it as the first task. this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName)); - // Override the GA Tracker's task with our task manager executor. + // Override the GA Tracker's task with our task manager executor which calls all user tasks added to the registry. this.tracker.set(gaTaskName, (model) => { - this.registry[gaTaskName].forEach((userTask) => { - userTask.func(model); - }); + for (var userTask in this.registry[gaTaskName]) { + if (this.registry[gaTaskName].hasOwnProperty(userTask)) { + this.registry[gaTaskName][userTask](model); + } + } }); }); } @@ -56,7 +58,7 @@ class GaTaskManager { */ addFunctionToTask(gaTaskName, userTaskName, taskFunction) { if (this.registry[gaTaskName]) { - this.registry[gaTaskName].push({name: userTaskName, func: taskFunction}); + this.registry[gaTaskName][userTaskName] = taskFunction; } } @@ -66,13 +68,8 @@ class GaTaskManager { * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask. */ removeFunctionFromTask(gaTaskName, userTaskName) { - if (this.registry[gaTaskName]) { - var userTaskIndex = this.registry[gaTaskName].findIndex(function(userTask){ - return userTask.name === userTaskName; - }); - if (userTaskIndex > -1) { - this.registry[gaTaskName].splice(userTaskIndex, 1); - } + if (this.registry[gaTaskName] && this.registry[gaTaskName][userTaskName]) { + delete this.registry[gaTaskName][userTaskName]; } } From d91a6d8d9d2855b1f6d3b25a30670f90d2fca5d9 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 18:11:34 -0700 Subject: [PATCH 26/30] WEB-1471:CHANGE: Modification notice --- bin/build.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/build.js b/bin/build.js index a6b0bf3..f07fe6d 100644 --- a/bin/build.js +++ b/bin/build.js @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Modifications Copyright (C) 2017 Anki, Inc. + * Modifications Copyright (C) 2018 Anki, Inc. */ From 00f3e458388c304be45fbc87a416cd2f654df762 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 19 Mar 2018 18:17:22 -0700 Subject: [PATCH 27/30] WEB-1471:FIX: indentation --- ga-task-manager.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ga-task-manager.html b/ga-task-manager.html index ac60f1b..36ed00d 100644 --- a/ga-task-manager.html +++ b/ga-task-manager.html @@ -40,7 +40,7 @@ // Trigger a second hit after 5 seconds setTimeout(function () { - ga('send', 'pageview'); + ga('send', 'pageview'); }, 5000); From 235d9d8b68076e68d9e1cebafaeb18df2a823214 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 2 Apr 2018 22:19:41 -0700 Subject: [PATCH 28/30] WEB-1471:CHANGE: plugin name not capitilized --- ga-task-manager.html | 4 ++-- lib/index.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ga-task-manager.html b/ga-task-manager.html index 36ed00d..d703644 100644 --- a/ga-task-manager.html +++ b/ga-task-manager.html @@ -12,7 +12,7 @@ ga('create', 'GA-PROPERTY-ID', 'auto'); // Require the plugin - ga('require', 'GaTaskManager'); + ga('require', 'gaTaskManager'); // Add a function to customTask ga('GaTaskManager:addFunctionToTask', 'customTask', 'logShinyString', function(model){ @@ -48,4 +48,4 @@ - \ No newline at end of file + diff --git a/lib/index.js b/lib/index.js index 9210b26..5fb4451 100644 --- a/lib/index.js +++ b/lib/index.js @@ -125,4 +125,4 @@ class GaTaskManager { } } -provide('GaTaskManager', GaTaskManager); +provide('gaTaskManager', GaTaskManager); From 8ee4fe2ed7b6b80b6bd2f499050083395c45d287 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Mon, 2 Apr 2018 22:20:37 -0700 Subject: [PATCH 29/30] WEB-1471:FIX: remove error --- lib/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/index.js b/lib/index.js index 5fb4451..50cdad7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -117,9 +117,7 @@ class GaTaskManager { */ remove() { this.gaTaskNames.forEach((gaTaskName) => { - const originalTaskFunction = this.registry[gaTaskName].find((element) => { - return element.name == 'original'; - }); + const originalTaskFunction = this.registry[gaTaskName]['original']; this.tracker.set(gaTaskName, originalTaskFunction); }); } From 14c0e4de74c79c3d34051759f2d672312c28f5b1 Mon Sep 17 00:00:00 2001 From: Vinnie Freitas Date: Tue, 3 Apr 2018 22:54:07 -0700 Subject: [PATCH 30/30] WEB-1471:FIX:recompile production versions --- ga-task-manager.js | 8 ++++---- ga-task-manager.js.map | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ga-task-manager.js b/ga-task-manager.js index ca925a0..c829b78 100644 --- a/ga-task-manager.js +++ b/ga-task-manager.js @@ -1,5 +1,5 @@ -(function(){function f(b){var a=this;this.c=b;this.a={};this.b="customTask previewTask checkProtocolTask validationTask checkStorageTask historyImportTask samplerTask buildHitTask sendHitTask timingTask displayFeaturesTask".split(" ");this.addFunctionToTask=this.addFunctionToTask.bind(this);this.removeFunctionFromTask=this.removeFunctionFromTask.bind(this);this.setCustomDimension=this.setCustomDimension.bind(this);this.unsetCustomDimension=this.unsetCustomDimension.bind(this);this.b.forEach(function(c){a.a[c]= -{};a.addFunctionToTask(c,"original",b.get(c));a.c.set(c,function(b){for(var d in a.a[c])if(a.a[c].hasOwnProperty(d))a.a[c][d](b)})})}f.prototype.addFunctionToTask=function(b,a,c){this.a[b]&&(this.a[b][a]=c)};f.prototype.removeFunctionFromTask=function(b,a){this.a[b]&&this.a[b][a]&&delete this.a[b][a]}; -f.prototype.setCustomDimension=function(b,a,c){this.addFunctionToTask(void 0===c?"customTask":c,"customDimension"+b,function(c){var d=a;if("function"==typeof a){var d=a(),e=typeof d;if("string"!=e&&"number"!=e)throw Error("Function "+a.name+" must return a string or number. Got "+e+"instead.");}"number"===typeof d&&(d=d.toString());c.set("dimension"+b,d)})};f.prototype.unsetCustomDimension=function(b,a){this.removeFunctionFromTask(void 0===a?"customTask":a,"customDimension"+b)}; -f.prototype.remove=function(){var b=this;this.b.forEach(function(a){var c=b.a[a].find(function(a){return"original"==a.name});b.c.set(a,c)})};(function(b,a){var c=window.GoogleAnalyticsObject||"ga";window[c]=window[c]||function(a){for(var b=[],e=0;e {\n this.registry[gaTaskName] = {};\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor which calls all user tasks added to the registry.\n this.tracker.set(gaTaskName, (model) => {\n for (var userTask in this.registry[gaTaskName]) {\n if (this.registry[gaTaskName].hasOwnProperty(userTask)) {\n this.registry[gaTaskName][userTask](model);\n }\n }\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName][userTaskName] = taskFunction;\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName] && this.registry[gaTaskName][userTaskName]) {\n delete this.registry[gaTaskName][userTaskName];\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * If a number is given, it will be cast automatically to a string by calling Number.toString() method.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. Defaults to 'customTask'.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n\n if (typeof auxValue === 'number') auxValue = auxValue.toString();\n\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName].find((element) => {\n return element.name == 'original';\n });\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('GaTaskManager', GaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file +{"version":3,"sources":["lib/index.js","lib/provide.js","lib/utilities.js"],"names":["constructor","GaTaskManager","tracker","registry","gaTaskNames","addFunctionToTask","bind","removeFunctionFromTask","setCustomDimension","unsetCustomDimension","forEach","gaTaskName","get","set","model","userTask","hasOwnProperty","userTaskName","taskFunction","index","value","auxValue","auxType","Error","name","toString","remove","originalTaskFunction","provide","pluginName","pluginConstructor","gaAlias","window","GoogleAnalyticsObject","push","q","args","gaplugins","charAt","toUpperCase","slice"],"mappings":"A,YAWEA,QALIC,EAKO,CAACC,CAAD,CAAU,CAAA,IAAA,EAAA,IACnB,KAAAA,EAAA,CAAeA,CACf,KAAAC,EAAA,CAAgB,EAEhB,KAAAC,EAAA,CAAmB,gKAAA,MAAA,CAAA,GAAA,CAenB,KAAAC,kBAAA,CAAyB,IAAAA,kBAAAC,KAAA,CAA4B,IAA5B,CACzB,KAAAC,uBAAA,CAA8B,IAAAA,uBAAAD,KAAA,CAAiC,IAAjC,CAC9B,KAAAE,mBAAA,CAA0B,IAAAA,mBAAAF,KAAA,CAA6B,IAA7B,CAC1B,KAAAG,qBAAA,CAA4B,IAAAA,qBAAAH,KAAA,CAA+B,IAA/B,CAE5B,KAAAF,EAAAM,QAAA,CAAyB,QAAA,CAACC,CAAD,CAAgB,CACvC,CAAAR,EAAA,CAAcQ,CAAd,CAAA;AAA4B,EAE5B,EAAAN,kBAAA,CAAuBM,CAAvB,CAAmC,UAAnC,CAA+CT,CAAAU,IAAA,CAAYD,CAAZ,CAA/C,CAGA,EAAAT,EAAAW,IAAA,CAAiBF,CAAjB,CAA6B,QAAA,CAACG,CAAD,CAAW,CACtC,IAAKC,IAAIA,CAAT,GAAqB,EAAAZ,EAAA,CAAcQ,CAAd,CAArB,CACE,GAAI,CAAAR,EAAA,CAAcQ,CAAd,CAAAK,eAAA,CAAyCD,CAAzC,CAAJ,CACE,CAAAZ,EAAA,CAAcQ,CAAd,CAAA,CAA0BI,CAA1B,CAAA,CAAoCD,CAApC,CAHkC,CAAxC,CANuC,CAAzC,CAxBmB,CA+CrB,CAAA,UAAA,kBAAA,CAAAT,QAAiB,CAACM,CAAD,CAAaM,CAAb,CAA2BC,CAA3B,CAAyC,CACpD,IAAAf,EAAA,CAAcQ,CAAd,CAAJ,GACE,IAAAR,EAAA,CAAcQ,CAAd,CAAA,CAA0BM,CAA1B,CADF,CAC4CC,CAD5C,CADwD,CAW1D,EAAA,UAAA,uBAAA,CAAAX,QAAsB,CAACI,CAAD,CAAaM,CAAb,CAA2B,CAC3C,IAAAd,EAAA,CAAcQ,CAAd,CAAJ,EAAiC,IAAAR,EAAA,CAAcQ,CAAd,CAAA,CAA0BM,CAA1B,CAAjC,EACE,OAAO,IAAAd,EAAA,CAAcQ,CAAd,CAAA,CAA0BM,CAA1B,CAFsC,CAejD;CAAA,UAAA,mBAAA,CAAAT,QAAkB,CAACW,CAAD,CAAQC,CAAR,CAAeT,CAAf,CAA0C,CAE1D,IAAAN,kBAAA,CAF+B,IAAA,EAAAM,GAAAA,CAAAA,CAAa,YAAbA,CAAAA,CAE/B,CADqB,iBACrB,CADyCQ,CACzC,CAAiD,QAAA,CAASL,CAAT,CAAe,CAC5D,IAAIO,EAAWD,CAEf,IAAoB,UAApB,EAAI,MAAOA,EAAX,CAAgC,CAC9B,IAAAC,EAAWD,CAAA,EAAX,CACME,EAAU,MAAOD,EACvB,IAAe,QAAf,EAAIC,CAAJ,EAAsC,QAAtC,EAA2BA,CAA3B,CACE,KAAUC,MAAJ,CAAU,WAAV,CAAwBH,CAAAI,KAAxB,CAAqC,uCAArC,CAA+EF,CAA/E,CAAyF,UAAzF,CAAN,CAJ4B,CAQR,QAAxB,GAAI,MAAOD,EAAX,GAAkCA,CAAlC,CAA6CA,CAAAI,SAAA,EAA7C,CAGAX,EAAAD,IAAA,CAAU,WAAV,CAAwBM,CAAxB,CAA+BE,CAA/B,CAd4D,CAAhE,CAF0D,CAyB5D,EAAA,UAAA,qBAAA,CAAAZ,QAAoB,CAACU,CAAD,CAAQR,CAAR,CAAmC,CAErD,IAAAJ,uBAAA,CAF0B,IAAA,EAAAI,GAAAA,CAAAA,CAAa,YAAbA,CAAAA,CAE1B,CADqB,iBACrB,CADyCQ,CACzC,CAFqD,CAQvD;CAAA,UAAA,OAAA,CAAAO,QAAM,EAAG,CAAA,IAAA,EAAA,IACP,KAAAtB,EAAAM,QAAA,CAAyB,QAAA,CAACC,CAAD,CAAgB,CAEvC,CAAAT,EAAAW,IAAA,CAAiBF,CAAjB,CAD6B,CAAAR,EAAA,CAAcQ,CAAd,CAAAgB,SAC7B,CAFuC,CAAzC,CADO,CCzFXC,UAA+B,CAACC,CAAD,CAAaC,CAAb,CAAgC,CAC7D,IAAMC,EAAUC,MAAAC,sBAAVF,EAA0C,IAChDC,OAAA,CAAOD,CAAP,CAAA,CAAkBC,MAAA,CAAOD,CAAP,CAAlB,EAAqC,QAAA,CAAS,CAAT,CAAkB,CAAT,IAAA,IAAA,EAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,SAAA,OAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,SAAA,CAAA,CAAA,CAC5CG,EAACF,MAAA,CAAOD,CAAP,CAAAI,EAADD,CAAqBF,MAAA,CAAOD,CAAP,CAAAI,EAArBD,EAA0C,EAA1CA,MAAA,CADqDE,CACrD,CADqD,CAKvDJ,OAAA,CAAOD,CAAP,CAAA,CAAgB,SAAhB,CAA2BF,CAA3B,CAAuCC,CAAvC,CAGAE,OAAAK,UAAA,CAAmBL,MAAAK,UAAnB,EAAuC,EACvCL,OAAAK,UAAA,CAA4BR,CCMrBS,OAAA,CAAW,CAAX,CAAAC,YAAA,EDNP,CAA4BV,CCMSW,MAAA,CAAU,CAAV,CDNrC,CAAA,CAA2CV,CAXkB,CAA/DF,CDiGA,CAAQ,eAAR,CAAyB3B,CAAzB","file":"","sourcesContent":["import provide from './provide';\n\n/**\n * Class for the `ga-task-manager` analytics.js plugin.\n * @implements {GaTaskManagerPublicInterface}\n */\nclass GaTaskManager {\n /**\n * Registers declarative event tracking.\n * @param {!Tracker} tracker Passed internally by analytics.js\n */\n constructor(tracker) {\n this.tracker = tracker;\n this.registry = {};\n // @see https://developers.google.com/analytics/devguides/collection/analyticsjs/tasks\n this.gaTaskNames = [\n 'customTask',\n 'previewTask',\n 'checkProtocolTask',\n 'validationTask',\n 'checkStorageTask',\n 'historyImportTask',\n 'samplerTask',\n 'buildHitTask',\n 'sendHitTask',\n 'timingTask',\n 'displayFeaturesTask'\n ];\n\n // Bind methods.\n this.addFunctionToTask = this.addFunctionToTask.bind(this);\n this.removeFunctionFromTask = this.removeFunctionFromTask.bind(this);\n this.setCustomDimension = this.setCustomDimension.bind(this);\n this.unsetCustomDimension = this.unsetCustomDimension.bind(this);\n\n this.gaTaskNames.forEach((gaTaskName) => {\n this.registry[gaTaskName] = {};\n // Grab a reference to the default function for this task and register it as the first task.\n this.addFunctionToTask(gaTaskName, 'original', tracker.get(gaTaskName));\n\n // Override the GA Tracker's task with our task manager executor which calls all user tasks added to the registry.\n this.tracker.set(gaTaskName, (model) => {\n for (var userTask in this.registry[gaTaskName]) {\n if (this.registry[gaTaskName].hasOwnProperty(userTask)) {\n this.registry[gaTaskName][userTask](model);\n }\n }\n });\n });\n }\n\n /**\n * Adds a function to be executed at the specified GA Task.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n * @param {string} userTaskName An arbitrary name for the task performed by the taskFunction.\n * @param {function(!Model)} taskFunction The function to be added to the execution stack of the GA Task specified in gaTaskName.\n * The GA Model Object (https://developers.google.com/analytics/devguides/collection/analyticsjs/model-object-reference) will be passed to it at time of execution.\n */\n addFunctionToTask(gaTaskName, userTaskName, taskFunction) {\n if (this.registry[gaTaskName]) {\n this.registry[gaTaskName][userTaskName] = taskFunction;\n }\n }\n\n /**\n * Removes a function from the specified GA Task by the name given by the user.\n * @param {string} gaTaskName The name of the GA Task to remove the task from.\n * @param {string} userTaskName The arbitrary name for the task given to addFunctionToTask.\n */\n removeFunctionFromTask(gaTaskName, userTaskName) {\n if (this.registry[gaTaskName] && this.registry[gaTaskName][userTaskName]) {\n delete this.registry[gaTaskName][userTaskName];\n }\n }\n\n /**\n * Adds a function which sets a GA Custom Dimension at the specified GA Task execution time. Defaults to execution on the customTask Task.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string|number|function(): string|number} value Arbitrary string, number or function to set value for the dimension.\n * If a function is given, it will be executed every time at the moment of task execution.\n * If a number is given, it will be cast automatically to a string by calling Number.toString() method.\n * Observe size limit for the string value https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#customs\n * @param {string} gaTaskName The name of the GA Task on which to set the Custom Dimension. Defaults to 'customTask'.\n */\n setCustomDimension(index, value, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.addFunctionToTask(gaTaskName, userTaskName, function(model){\n let auxValue = value;\n // If user provided a function to set value at execution time, then type check itsreturn value.\n if (typeof value == 'function') {\n auxValue = value();\n const auxType = typeof auxValue;\n if (auxType != 'string' && auxType != 'number') {\n throw new Error('Function ' + value.name + ' must return a string or number. Got ' + auxType + 'instead.');\n }\n }\n\n if (typeof auxValue === 'number') auxValue = auxValue.toString();\n\n // Set the dimension value to be sent to GA.\n model.set('dimension' + index, auxValue);\n });\n }\n\n /**\n * Removes a function added with setCustomDimension.\n * @param {string} index The index of your dimension as defined in your Google Analytics property settings.\n * @param {string} gaTaskName The name of the GA Task to add the taskFunction to.\n */\n unsetCustomDimension(index, gaTaskName = 'customTask') {\n const userTaskName = 'customDimension' + index;\n this.removeFunctionFromTask(gaTaskName, userTaskName);\n }\n\n /**\n * Resets all Tasks of the Tracker to the original function registered at the moment the plugin was required.\n */\n remove() {\n this.gaTaskNames.forEach((gaTaskName) => {\n const originalTaskFunction = this.registry[gaTaskName]['original'];\n this.tracker.set(gaTaskName, originalTaskFunction);\n });\n }\n}\n\nprovide('gaTaskManager', GaTaskManager);\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2017 Anki, Inc\n */\n\n\nimport {capitalize} from './utilities';\n\n\n/**\n * Provides a plugin for use with analytics.js, accounting for the possibility\n * that the global command queue has been renamed or not yet defined.\n * @param {string} pluginName The plugin name identifier.\n * @param {Function} pluginConstructor The plugin constructor function.\n */\nexport default function provide(pluginName, pluginConstructor) {\n const gaAlias = window.GoogleAnalyticsObject || 'ga';\n window[gaAlias] = window[gaAlias] || function(...args) {\n (window[gaAlias].q = window[gaAlias].q || []).push(args);\n };\n\n // Formally provides the plugin for use with analytics.js.\n window[gaAlias]('provide', pluginName, pluginConstructor);\n\n // Registers the plugin on the global gaplugins object.\n window.gaplugins = window.gaplugins || {};\n window.gaplugins[capitalize(pluginName)] = pluginConstructor;\n}\n","/**\n * Copyright 2016 Google Inc. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Modifications Copyright (C) 2018 Anki, Inc.\n */\n\n/**\n * A small shim of Object.assign that aims for brevity over spec-compliant\n * handling all the edge cases.\n * @param {!Object} target The target object to assign to.\n * @param {...?Object} sources Additional objects who properties should be\n * assigned to target. Non-objects are converted to objects.\n * @return {!Object} The modified target object.\n */\nexport const assign = Object.assign || function(target, ...sources) {\n for (let i = 0, len = sources.length; i < len; i++) {\n const source = Object(sources[i]);\n for (let key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n};\n\n\n/**\n * Capitalizes the first letter of a string.\n * @param {string} str The input string.\n * @return {string} The capitalized string\n */\nexport function capitalize(str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n"]} \ No newline at end of file