From 8134691b3c83bf666c905b13087a240bac3dbe2e Mon Sep 17 00:00:00 2001 From: Alex Li <7alex7li@gmail.com> Date: Fri, 14 Aug 2020 10:12:31 -0400 Subject: [PATCH 1/6] Fix processing order bug with processing past events when more than 1 are on the queue --- dist/data-layer-helper.js | 12 ++--- dist/data-layer-helper.js.map | 4 +- nohup.out | 0 src/helper/data-layer-helper.js | 70 +++++++++++++++++-------- test/integration/process_test.js | 19 ++++++- test/listener_test.js | 90 ++++++++++++++++++++++++++++++++ test/processCommand_test.js | 6 +-- test/processStates_test.js | 3 +- test/process_test.js | 12 +++++ 9 files changed, 181 insertions(+), 35 deletions(-) create mode 100644 nohup.out create mode 100644 test/listener_test.js diff --git a/dist/data-layer-helper.js b/dist/data-layer-helper.js index f69e2ee6..5fb1959f 100644 --- a/dist/data-layer-helper.js +++ b/dist/data-layer-helper.js @@ -7,10 +7,10 @@ jQuery v1.9.1 (c) 2005, 2012 jQuery Foundation, Inc. jquery.org/license. */ -var f=/\[object (Boolean|Number|String|Function|Array|Date|RegExp|Arguments)\]/;function g(a){return null==a?String(a):(a=f.exec(Object.prototype.toString.call(Object(a))))?a[1].toLowerCase():"object"}function k(a,b){return Object.prototype.hasOwnProperty.call(Object(a),b)}function m(a){if(!a||"object"!=g(a)||a.nodeType||a==a.window)return!1;try{if(a.constructor&&!k(a,"constructor")&&!k(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}for(var b in a);return void 0===b||k(a,b)};function p(a,b){var c={},d=c;a=a.split(".");for(var e=0;e} + */ + this.commandQueue_ = []; + + /** + * The internal queue of dataLayer updates that have not yet been processed + * because another command is in the process of running. * @private @const {!Array<*>} */ - this.unprocessed_ = []; + this.processingQueue_ = []; /** * The internal map of processors to run. @@ -162,6 +170,16 @@ class DataLayerHelper { */ this.abstractModelInterface_ = buildAbstractModelInterface_(this); + // Add listener for future state changes. + const oldPush = this.dataLayer_.push; + const that = this; + this.dataLayer_.push = function() { + const states = [].slice.call(arguments, 0); + const result = oldPush.apply(that.dataLayer_, states); + that.processStates_(states); + return result; + }; + if (options['processNow']) { this.process(); } @@ -196,21 +214,15 @@ class DataLayerHelper { } return toMerge; }); - // Process the existing/past states. - this.processStates_(this.dataLayer_, !(this.listenToPast_)); - // Mark helper as having been processed. this.processed_ = true; - // Add listener for future state changes. - const oldPush = this.dataLayer_.push; - const that = this; - this.dataLayer_.push = function() { - const states = [].slice.call(arguments, 0); - const result = oldPush.apply(that.dataLayer_, states); - that.processStates_(states); - return result; - }; + // Process the existing/past states (in the dataLayer) + this.commandQueue_.push.apply(this.commandQueue_, this.dataLayer_); + // Before process() is called, put everything in an external queue. + // This way we can simulate the processingQueue later as being the length + // it would have been at the time that any command is to be processed. + this.processStates_([], !(this.listenToPast_)); } /** @@ -319,25 +331,31 @@ class DataLayerHelper { * * @param {!Array<*>} states The update objects to process, each * representing a change to the state of the page. - * @param {boolean=} skipListener If true, the listener the given states + * @param {boolean=} skipListener If true, the existing states * will be applied to the internal model, but will not cause the listener * to be executed. This is useful for processing past states that the * listener might not care about. * @private */ processStates_(states, skipListener = false) { - this.unprocessed_.push.apply(this.unprocessed_, states); + if (!this.processed_) { + return; + } + this.processingQueue_.push.apply(this.processingQueue_, states); + if (this.executingListener_) { + return; + } // Checking executingListener here protects against multiple levels of // loops trying to process the same queue. This can happen if the listener // itself is causing new states to be pushed onto the dataLayer. - while (this.executingListener_ === false && this.unprocessed_.length > 0) { - const update = this.unprocessed_.shift(); + while (this.processingQueue_.length > 0) { + const update = this.processingQueue_.shift(); if (isArray(update)) { processCommand_(/** @type {!Array<*>} */ (update), this.model_); } else if (isArguments(update)) { const newStates = this.processArguments_( /** @type {!Array<*>} */(update)); - this.unprocessed_.push.apply(this.unprocessed_, newStates); + this.processingQueue_.push.apply(this.processingQueue_, newStates); } else if (typeof update == 'function') { try { update.call(this.abstractModelInterface_); @@ -360,6 +378,14 @@ class DataLayerHelper { this.executingListener_ = false; } } + // If we have processed the whole queue, then look in the commandQueue for + // any additional commands to do. + if (this.processingQueue_.length === 0 && this.commandQueue_.length > 0) { + this.processingQueue_.push(this.commandQueue_.shift()); + } + if (this.processingQueue_.length > 0) { + this.processStates_([], skipListener); + } } } @@ -371,8 +397,8 @@ window['DataLayerHelper'] = DataLayerHelper; * * @param {!DataLayerHelper} dataLayerHelper The helper class to construct the * abstract model interface for. - * @return {!Object} The interface to the abstract data layer model that is - * given to Custom Methods. + * @return {!Object} The interface to the abstract data layer model + * that is given to Custom Methods. * @private */ function buildAbstractModelInterface_(dataLayerHelper) { diff --git a/test/integration/process_test.js b/test/integration/process_test.js index 11ae1128..a4e5f35b 100644 --- a/test/integration/process_test.js +++ b/test/integration/process_test.js @@ -27,7 +27,6 @@ describe('The process function of helper', () => { const spy = jasmine.createSpy('spy'); commandAPI('event'); commandAPI('fireworks'); - const helper = new DataLayerHelper(dataLayer, {processNow: false}); helper.registerProcessor('event', () => { @@ -39,4 +38,22 @@ describe('The process function of helper', () => { expect(spy).toHaveBeenCalledTimes(1); }); + + it('registers set commands pushed before process in other ' + + 'commands pushed before process', () => { + const helper = new DataLayerHelper(dataLayer, + {processNow: false}); + commandAPI('set', 'two', 2); + commandAPI('event'); + commandAPI('eventTwo'); + helper.registerProcessor('event', function() { + return {'two': this.get('two') + 3}; + }); + helper.registerProcessor('eventTwo', function() { + return {'two': this.get('two') * 5}; + }); + helper.process(); + + expect(helper.get('two')).toBe(25); + }); }); diff --git a/test/listener_test.js b/test/listener_test.js new file mode 100644 index 00000000..34f51d3b --- /dev/null +++ b/test/listener_test.js @@ -0,0 +1,90 @@ +goog.module('dataLayerHelper.helper.testing.listener'); +goog.setTestOnly(); + +const DataLayerHelper = goog.require('dataLayerHelper.helper.DataLayerHelper'); + +describe('The helper when listening to the past', () => { + let dataLayer; + let callCount = 0; + // Create a listener expecting certain calls. We can't just use a + // jasmine spy since the first argument is the model, which mutates + // constantly. + const listenerExpecting = (calls, operation = () => {}) => { + function checkArgsAndRun(model, message) { + // objectContaining call ensures that the arguments object + // can match an array. + expect(arguments).toEqual(jasmine.objectContaining(calls[callCount++])); + operation(model, message); + } + return checkArgsAndRun; + }; + beforeEach(() => { + dataLayer = []; + callCount = 0; + }); + + describe('when pushing functions with no model side effects', () => { + it('does not call the listener if nothing is pushed', () => { + new DataLayerHelper(dataLayer, + {listenToPast: true, listener: listenerExpecting([])}); + + expect(dataLayer.length).toBe(0); + }); + + + it('calls the listener with the right model state when pushed after ' + + 'being constructed.', () => { + new DataLayerHelper(dataLayer, {listenToPast: true, + listener: listenerExpecting( + [[{a: 1}, {a: 1}], [{a: 1, b: 1}, {b: 1}]])}); + dataLayer.push({a: 1}); + dataLayer.push({b: 1}); + + expect(dataLayer.length).toBe(2); + }); + + it('calls the listener with the right model state when pushed in ' + + 'the past.', () => { + dataLayer.push({a: 1}); + dataLayer.push({b: 1}); + new DataLayerHelper(dataLayer, {listenToPast: true, + listener: listenerExpecting( + [[{a: 1}, {a: 1}], [{a: 1, b: 1}, {b: 1}]])}); + + expect(dataLayer.length).toBe(2); + }); + }); + + // This test was failing in version 0.4.0 + describe('when pushing functions with model side effects', () => { + it('Can recursively push to the model', () => { + dataLayer.push({a: 1}); + const listenFunction = (model, message) => { + if (model.a < 3) { + dataLayer.push({a: model.a + 1}); + } + }; + new DataLayerHelper(dataLayer, {listenToPast: true, + listener: listenerExpecting( + [[{a: 1}, {a: 1}], [{a: 2}, {a: 2}], [{a: 3}, {a: 3}]], + listenFunction)}); + }); + + it('Can recursively push to the model with more than 1 element on ' + + 'the datalayer queue.', () => { + dataLayer.push({a: 1}); + dataLayer.push({b: 2}); + const listenFunction = (model, message) => { + if (model.a < 3) { + dataLayer.push({a: model.a + 1}); + } + }; + new DataLayerHelper(dataLayer, {listenToPast: true, + listener: listenerExpecting( + [[{a: 1}, {a: 1}], [{a: 2}, {a: 2}], [{a: 3}, {a: 3}], + [{a: 3, b: 2}, {b: 2}]], + listenFunction)}); + }); + }); +}); + diff --git a/test/processCommand_test.js b/test/processCommand_test.js index c673e483..10ef5018 100644 --- a/test/processCommand_test.js +++ b/test/processCommand_test.js @@ -106,9 +106,9 @@ describe('The `processCommand` function of helper', () => { assertCommand(['a.b.sort'], {a: {b: [5, 4, 3, 2, 1]}}, {a: {b: [1, 2, 3, 4, 5]}}); assertCommand([ - 'a.b.sort', function(a, b) { - return b - a; - }], + 'a.b.sort', function(a, b) { + return b - a; + }], {a: {b: [1, 2, 3, 4, 5]}}, {a: {b: [5, 4, 3, 2, 1]}}); assertCommand(['a.b.reverse'], {a: {b: [5, 4, 3, 2, 1]}}, {a: {b: [1, 2, 3, 4, 5]}}); diff --git a/test/processStates_test.js b/test/processStates_test.js index 46f13b50..996ed659 100644 --- a/test/processStates_test.js +++ b/test/processStates_test.js @@ -36,7 +36,8 @@ describe('The `processStates_` function of helper', () => { expect(listenerCalls) .toEqual(skipListener ? [] : expectedListenerCalls); - expect(helper.unprocessed_).toEqual([]); + expect(helper.commandQueue_).toEqual([]); + expect(helper.processingQueue_).toEqual([]); expect(helper.executingListener_).toBeFalse(); }; diff --git a/test/process_test.js b/test/process_test.js index 086289fb..41bd09ad 100644 --- a/test/process_test.js +++ b/test/process_test.js @@ -55,6 +55,18 @@ describe('The `process` function of helper', () => { expect(helper.get('two')).toBe(2); }); + it('registers set commands pushed before process in other ' + + 'commands pushed before process', () => { + commandAPI('set', 'two', 2); + commandAPI('event'); + helper.registerProcessor('event', function() { + return {'two': this.get('two') + 3}; + }); + helper.process(); + + expect(helper.get('two')).toBe(5); + }); + it('registers set commands pushed after process', () => { helper.process(); commandAPI('set', 'two', 2); From c6e53e050d79ca7b7c4d5ce2f779b21d3173227a Mon Sep 17 00:00:00 2001 From: Alex Li <7alex7li@gmail.com> Date: Mon, 17 Aug 2020 11:38:00 -0400 Subject: [PATCH 2/6] Remove external queue, instead just use for loop --- dist/data-layer-helper.js | 12 +++++----- dist/data-layer-helper.js.map | 4 ++-- nohup.out | 0 src/helper/data-layer-helper.js | 41 +++++++++++---------------------- test/processStates_test.js | 3 +-- 5 files changed, 23 insertions(+), 37 deletions(-) delete mode 100644 nohup.out diff --git a/dist/data-layer-helper.js b/dist/data-layer-helper.js index 5fb1959f..b94ad53e 100644 --- a/dist/data-layer-helper.js +++ b/dist/data-layer-helper.js @@ -7,10 +7,10 @@ jQuery v1.9.1 (c) 2005, 2012 jQuery Foundation, Inc. jquery.org/license. */ -var f=/\[object (Boolean|Number|String|Function|Array|Date|RegExp|Arguments)\]/;function g(a){return null==a?String(a):(a=f.exec(Object.prototype.toString.call(Object(a))))?a[1].toLowerCase():"object"}function m(a,b){return Object.prototype.hasOwnProperty.call(Object(a),b)}function n(a){if(!a||"object"!=g(a)||a.nodeType||a==a.window)return!1;try{if(a.constructor&&!m(a,"constructor")&&!m(a.constructor.prototype,"isPrototypeOf"))return!1}catch(d){return!1}for(var b in a);return void 0===b||m(a,b)};function p(a,b){var d={},c=d;a=a.split(".");for(var e=0;e} - */ - this.commandQueue_ = []; - /** * The internal queue of dataLayer updates that have not yet been processed * because another command is in the process of running. * @private @const {!Array<*>} */ - this.processingQueue_ = []; + this.unprocessed_ = []; /** * The internal map of processors to run. @@ -217,12 +210,12 @@ class DataLayerHelper { // Mark helper as having been processed. this.processed_ = true; - // Process the existing/past states (in the dataLayer) - this.commandQueue_.push.apply(this.commandQueue_, this.dataLayer_); - // Before process() is called, put everything in an external queue. - // This way we can simulate the processingQueue later as being the length - // it would have been at the time that any command is to be processed. - this.processStates_([], !(this.listenToPast_)); + const curLength = this.dataLayer_.length; + for (let i = 0; i < curLength; i++) { + // Run the commands one at a time to maintain the correct + // length of the queue on each command. + this.processStates_([this.dataLayer_[i]], !(this.listenToPast_)); + } } /** @@ -248,6 +241,8 @@ class DataLayerHelper { * Flattens the dataLayer's history into a single object that represents the * current state. This is useful for long running apps, where the dataLayer's * history may get very large. + * Use of this method with a command API is not supported and may break + * something. * @export */ flatten() { @@ -341,21 +336,21 @@ class DataLayerHelper { if (!this.processed_) { return; } - this.processingQueue_.push.apply(this.processingQueue_, states); + this.unprocessed_.push.apply(this.unprocessed_, states); if (this.executingListener_) { return; } // Checking executingListener here protects against multiple levels of // loops trying to process the same queue. This can happen if the listener // itself is causing new states to be pushed onto the dataLayer. - while (this.processingQueue_.length > 0) { - const update = this.processingQueue_.shift(); + while (this.unprocessed_.length > 0) { + const update = this.unprocessed_.shift(); if (isArray(update)) { processCommand_(/** @type {!Array<*>} */ (update), this.model_); } else if (isArguments(update)) { const newStates = this.processArguments_( /** @type {!Array<*>} */(update)); - this.processingQueue_.push.apply(this.processingQueue_, newStates); + this.unprocessed_.push.apply(this.unprocessed_, newStates); } else if (typeof update == 'function') { try { update.call(this.abstractModelInterface_); @@ -378,14 +373,6 @@ class DataLayerHelper { this.executingListener_ = false; } } - // If we have processed the whole queue, then look in the commandQueue for - // any additional commands to do. - if (this.processingQueue_.length === 0 && this.commandQueue_.length > 0) { - this.processingQueue_.push(this.commandQueue_.shift()); - } - if (this.processingQueue_.length > 0) { - this.processStates_([], skipListener); - } } } diff --git a/test/processStates_test.js b/test/processStates_test.js index 996ed659..46f13b50 100644 --- a/test/processStates_test.js +++ b/test/processStates_test.js @@ -36,8 +36,7 @@ describe('The `processStates_` function of helper', () => { expect(listenerCalls) .toEqual(skipListener ? [] : expectedListenerCalls); - expect(helper.commandQueue_).toEqual([]); - expect(helper.processingQueue_).toEqual([]); + expect(helper.unprocessed_).toEqual([]); expect(helper.executingListener_).toBeFalse(); }; From 9e00d5623529d5584c1082a76f17d03cb7f0a48c Mon Sep 17 00:00:00 2001 From: Alex Li <7alex7li@gmail.com> Date: Mon, 17 Aug 2020 11:38:47 -0400 Subject: [PATCH 3/6] Update dist --- dist/data-layer-helper.js | 10 +++++----- dist/data-layer-helper.js.map | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dist/data-layer-helper.js b/dist/data-layer-helper.js index b94ad53e..15870a33 100644 --- a/dist/data-layer-helper.js +++ b/dist/data-layer-helper.js @@ -7,10 +7,10 @@ jQuery v1.9.1 (c) 2005, 2012 jQuery Foundation, Inc. jquery.org/license. */ -var f=/\[object (Boolean|Number|String|Function|Array|Date|RegExp|Arguments)\]/;function g(a){return null==a?String(a):(a=f.exec(Object.prototype.toString.call(Object(a))))?a[1].toLowerCase():"object"}function m(a,b){return Object.prototype.hasOwnProperty.call(Object(a),b)}function n(a){if(!a||"object"!=g(a)||a.nodeType||a==a.window)return!1;try{if(a.constructor&&!m(a,"constructor")&&!m(a.constructor.prototype,"isPrototypeOf"))return!1}catch(e){return!1}for(var b in a);return void 0===b||m(a,b)};function p(a,b){var e={},c=e;a=a.split(".");for(var d=0;d Date: Thu, 20 Aug 2020 11:53:59 -0400 Subject: [PATCH 4/6] Add comments about not pushing to the data layer from within a listener --- README.md | 24 ++++++++++++++++-------- test/listener_test.js | 9 ++++++++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f02d6c42..d43ed7dd 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,10 @@ This library provides the ability to process messages passed onto a data layer q - [Custom Methods](#custom-methods) - [The Abstract Data Model Interface](#the-abstract-data-model-interface) - [Listening for Messages](#listening-for-messages) - - [Listening to the Past](#listening-to-the-past) - - [Registering Processors](#registering-processors) - - [Delaying Processing](#delaying-processing) + - [With a Listener Function](#with-a-listener-function) + - [Listening to the Past](#listening-to-the-past) + - [By Registering Processors](#by-registering-processors) + - [Delaying Processing](#delaying-processing) - [Summary](#summary) - [Build and Test](#build-and-test) - [License](#license) @@ -424,8 +425,15 @@ The following example demonstrates overwriting a value: When creating a `DataLayerHelper` object, you can also specify a callback function to be called whenever a message is pushed onto the given dataLayer. This allows your code to be notified immediately whenever the dataLayer has been updated, which is a key advantage of the message -queue approach. To do so, add the function under the `listener` attribute in an options object for -the second parameter of the `DataLayerHelper` constructor. +queue approach. + +Listener functions are attached to a data layer helper, not the data layer itself. +As such, they should **not** modify the dataLayer (e.g. call dataLayer.push()), as this +may cause other helpers listening to the data layer to see conflicting history. + +### With a Listener Function +To add a callback that listens to every push to the data layer, +Add a function under the `listener` attribute in the second parameter of the `DataLayerHelper` constructor. ```js function listener(model, message) { @@ -436,7 +444,7 @@ function listener(model, message) { const helper = new DataLayerHelper(dataLayer, {listener: listener}); ``` -### Listening to the Past +#### Listening to the Past Tools that are loaded onto the page asynchronously or lazily will appreciate that you can also opt to listen to message that were pushed onto the dataLayer in the past. To do so, mark the `listenToPast` attribute as true in an options object for the second parameter of the `DataLayerHelper` @@ -458,7 +466,7 @@ Using this option means that your listener callback will be called once for ever has ever been pushed onto the given data layer. And on each call to the callback, the model will represent the abstract model at the time of the message. -### Registering Processors +### By Registering Processors If you are using a command API to bring messages to the data layer, you may want to run different processors to respond to different commands pushed to the data layer instead of just having one global listener for all commands. You can register a function to run whenever commands @@ -531,7 +539,7 @@ const helper = new DataLayerHelper(dataLayer, { Similar to the `registerProcessor` method, the `add` command will invoke the two functions passed in to the `add` attribute in order. -### Delaying Processing +#### Delaying Processing Tools that are loaded onto the page asynchronously or lazily will appreciate that you can also opt to delay the processing the dataLayer until all command API processors are registered. Since diff --git a/test/listener_test.js b/test/listener_test.js index 34f51d3b..358552ad 100644 --- a/test/listener_test.js +++ b/test/listener_test.js @@ -55,8 +55,10 @@ describe('The helper when listening to the past', () => { }); }); - // This test was failing in version 0.4.0 describe('when pushing functions with model side effects', () => { + // It's not recommended to push to the model inside of a listener + // function since it can mess up public history, but ideally it should not + // break anything if you are using a single data layer helper. it('Can recursively push to the model', () => { dataLayer.push({a: 1}); const listenFunction = (model, message) => { @@ -84,6 +86,11 @@ describe('The helper when listening to the past', () => { [[{a: 1}, {a: 1}], [{a: 2}, {a: 2}], [{a: 3}, {a: 3}], [{a: 3, b: 2}, {b: 2}]], listenFunction)}); + // Public history is broken now - this helper sees {a: 1}, {a: 2}, {a: 3} + // {b: 2}, but the data layer sees {a: 1}, {b:2}, {a: 2}, {a: 3}. This + // can't be resolved. https://github.com/google/data-layer-helper/pull/59 + expect(dataLayer).toEqual( + jasmine.objectContaining([{a: 1}, {b: 2}, {a: 2}, {a: 3}])); }); }); }); From 0bd355505150d9886e6dfca1c8f951e618d537aa Mon Sep 17 00:00:00 2001 From: Alex Li <7alex7li@gmail.com> Date: Thu, 20 Aug 2020 14:38:05 -0400 Subject: [PATCH 5/6] No short names! --- dist/data-layer-helper.js.map | 4 ++-- src/helper/data-layer-helper.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/data-layer-helper.js.map b/dist/data-layer-helper.js.map index a0b26ec8..7c17fc4c 100644 --- a/dist/data-layer-helper.js.map +++ b/dist/data-layer-helper.js.map @@ -2,7 +2,7 @@ "version":3, "file":"dist/data-layer-helper.js", "lineCount":16, -"mappings":"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", +"mappings":"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", "sources":["src/plain/plain.js","src/helper/utils.js","src/helper/data-layer-helper.js","node_modules/google-closure-library/closure/goog/base.js"], -"names":["TYPE_RE_","type","value","String","match","exec","Object","prototype","toString","call","toLowerCase","hasOwn","key","hasOwnProperty","isPlainObject","nodeType","window","constructor","e","undefined","expandKeyValue","result","target","split","i","length","merge","from","to","allowMerge","property","fromProperty","DataLayerHelper","dataLayer","options","listenToPast","dataLayer_","listener_","listenToPast_","executingListener_","processed_","model_","unprocessed_","commandProcessors_","abstractModelInterface_","buildAbstractModelInterface_","oldPush","push","that","this.dataLayer_.push","states","slice","arguments","apply","processStates_","process","registerProcessor","toMerge","curLength","get","flatten","splice","name","processor","skipListener","update","shift","path","method","pop","args","processArguments_","callback","goog.exportProperty","publicName","dataLayerHelper","set"] +"names":["TYPE_RE_","type","value","String","match","exec","Object","prototype","toString","call","toLowerCase","hasOwn","key","hasOwnProperty","isPlainObject","nodeType","window","constructor","e","undefined","expandKeyValue","result","target","split","i","length","merge","from","to","allowMerge","property","fromProperty","DataLayerHelper","dataLayer","options","listenToPast","dataLayer_","listener_","listenToPast_","executingListener_","processed_","model_","unprocessed_","commandProcessors_","abstractModelInterface_","buildAbstractModelInterface_","oldPush","push","that","this.dataLayer_.push","states","slice","arguments","apply","processStates_","process","registerProcessor","toMerge","startingLength","get","flatten","splice","name","processor","skipListener","update","shift","path","method","pop","args","processArguments_","callback","goog.exportProperty","publicName","dataLayerHelper","set"] } diff --git a/src/helper/data-layer-helper.js b/src/helper/data-layer-helper.js index 01415f5f..ca4b6f59 100755 --- a/src/helper/data-layer-helper.js +++ b/src/helper/data-layer-helper.js @@ -210,8 +210,8 @@ class DataLayerHelper { // Mark helper as having been processed. this.processed_ = true; - const curLength = this.dataLayer_.length; - for (let i = 0; i < curLength; i++) { + const startingLength = this.dataLayer_.length; + for (let i = 0; i < startingLength; i++) { // Run the commands one at a time to maintain the correct // length of the queue on each command. this.processStates_([this.dataLayer_[i]], !(this.listenToPast_)); From e8076b89bc1bb08b017537d7400b36409479daf5 Mon Sep 17 00:00:00 2001 From: Alex Li <7alex7li@gmail.com> Date: Thu, 20 Aug 2020 14:40:56 -0400 Subject: [PATCH 6/6] Update debug build too --- dist/data-layer-helper-debug.js | 28 +++++++++------------------- dist/data-layer-helper-debug.js.map | 6 +++--- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/dist/data-layer-helper-debug.js b/dist/data-layer-helper-debug.js index 3c4f0f23..566aa073 100644 --- a/dist/data-layer-helper-debug.js +++ b/dist/data-layer-helper-debug.js @@ -3,26 +3,16 @@ Copyright The Closure Library Authors. SPDX-License-Identifier: Apache-2.0 */ -'use strict';/* +'use strict';function f(b,a){switch(a){case 1:console.log(b);break;case 2:console.warn(b);break;case 3:console.error(b)}};/* jQuery v1.9.1 (c) 2005, 2012 jQuery Foundation, Inc. jquery.org/license. */ -<<<<<<< HEAD -var g=/\[object (Boolean|Number|String|Function|Array|Date|RegExp|Arguments)\]/;function k(a){return null==a?String(a):(a=g.exec(Object.prototype.toString.call(Object(a))))?a[1].toLowerCase():"object"}function m(a,b){return Object.prototype.hasOwnProperty.call(Object(a),b)}function n(a){if(!a||"object"!=k(a)||a.nodeType||a==a.window)return!1;try{if(a.constructor&&!m(a,"constructor")&&!m(a.constructor.prototype,"isPrototypeOf"))return!1}catch(e){return!1}for(var b in a);return void 0===b||m(a,b)};function p(a,b){var e={},c=e;a=a.split(".");for(var d=0;d>>>>>> cde3d2ace111d477d15e0d2fb0ab2ffe248ead2f +function t(b,a,c){a=void 0===a?{}:a;c=void 0===c?!1:c;"function"===typeof a?(f("Legacy constructor was used. See README for latest usage.",2),a={listener:a,listenToPast:c,processNow:!0,commandProcessors:{}}):a={listener:a.listener||function(){},listenToPast:a.listenToPast||!1,processNow:void 0===a.processNow?!0:a.processNow,commandProcessors:a.commandProcessors||{}};this.a=b;this.l=a.listener;this.j=a.listenToPast;this.g=this.h=!1;this.c={};this.f=[];this.b=a.commandProcessors;this.i=w(this);var d= +this.a.push,e=this;this.a.push=function(){var h=[].slice.call(arguments,0),m=d.apply(e.a,h);x(e,h);return m};a.processNow&&this.process()} +t.prototype.process=function(){this.h&&f("Process has already been run. This method should only run a single time to prepare the helper.",3);this.registerProcessor("set",function(){var c={};1===arguments.length&&"object"===l(arguments[0])?c=arguments[0]:2===arguments.length&&"string"===l(arguments[0])&&(c=q(arguments[0],arguments[1]));return c});this.h=!0;for(var b=this.a.length,a=0;a