diff --git a/Template/Tag/CustomHtmlTag.web.js b/Template/Tag/CustomHtmlTag.web.js
index e515c52..817771b 100644
--- a/Template/Tag/CustomHtmlTag.web.js
+++ b/Template/Tag/CustomHtmlTag.web.js
@@ -30,9 +30,11 @@
             if (element.defer) {
                 newScript.defer = element.defer;
             }
+            if (element.async) {
+                newScript.async = element.async;
+            }
 
             newScript.type = "text/javascript";
-            newScript.async = true;
 
             return newScript;
         }
@@ -90,9 +92,68 @@
         }
 
         this.fire = function () {
-            var html = parameters.get('customHtml');
+            var html = parameters.customHtml;
+            if (html && html.type === 'JoinedVariable') {
+                var variables = html.getDefinition();
+                var value = '', varReturn, theVarValue, isVariable;
+                for (var i = 0; i < variables.length; i++) {
+                    varReturn = parameters.buildVariable(variables[i]);
+                    isVariable = TagManager.utils.isObject(variables[i]);
+                    theVarValue = varReturn.get();
+                    if (TagManager.utils.isObject(theVarValue) && TagManager.dom.isJsContext(value)) {
+                        // instead of serializing the object, we make it accessbile through a method so users can reference
+                        // an object using eg "var mytest = {{myObj}}"
+                        if (!TagManager.utils.isDefined(TagManager.customHtmlDataStore)) {
+                            TagManager.customHtmlDataStore = [];
+                        }
+                        TagManager.customHtmlDataStore.push((function (variable) {
+                            return function(){
+                                return varReturn.get();
+                            }
+                        })(varReturn));
+                        value += 'window.MatomoTagManager.customHtmlDataStore[' + (TagManager.customHtmlDataStore.length - 1) +']()';
+                    } else if (theVarValue !== false && theVarValue !== null && TagManager.utils.isDefined(theVarValue)) {
+                       if (isVariable && TagManager.utils.isString(theVarValue) && TagManager.dom.isJsContext(value)) {
+                            // we only escape it when the string is a result of a variable, not when it was actually entered
+                            // by a user
+                            value += theVarValue.replace(/[^,\-\.0-9A-Z_a-z]/g, function (charStr) {
+                                // from https://github.com/salesforce/secure-filters/blob/master/lib/secure-filters.js
+                                // license: BSD-3-Clause https://github.com/salesforce/secure-filters/blob/master/LICENSE.txt
+                                var code = charStr.charCodeAt(0);
+                                var hex = code.toString(16).toUpperCase();
+                                if (code < 0x80) { // ASCII
+                                    if (hex.length === 1) {
+                                        return '\\x0'+hex;
+                                    } else {
+                                        return '\\x'+hex;
+                                    }
+                                } else { // Unicode
+                                    switch(hex.length) {
+                                        case 2:
+                                            return '\\u00'+hex;
+                                        case 3:
+                                            return '\\u0'+hex;
+                                        case 4:
+                                            return '\\u'+hex;
+                                        default:
+                                            // charCodeAt() JS shouldn't return code > 0xFFFF, and only four hex
+                                            // digits can be encoded via `\u`-encoding, so return REPLACEMENT
+                                            // CHARACTER U+FFFD.
+                                            return '\\uFFFD';
+                                    }
+                                }
+
+                            });
+                        } else {
+                            value += theVarValue;
+                        }
+                    }
+                }
+                html = value;
+            } else {
+                html = html.get();
+            }
             if (html) {
-
                 var div = parameters.document.createElement('div');
                 div.innerHTML = html;
                 if (div.childNodes) {
diff --git a/javascripts/tagmanager.js b/javascripts/tagmanager.js
index e92518a..c8e96d5 100644
--- a/javascripts/tagmanager.js
+++ b/javascripts/tagmanager.js
@@ -794,6 +794,21 @@
                     }
                     return [];
                 },
+                /** @ignore **/
+                isJsContext: function (htmlString) {
+                    //  not part of API at this moment
+                    if (!htmlString) {
+                        return false;
+                    }
+                    htmlString = String(htmlString).toLowerCase();
+                    var lastScriptPos = htmlString.lastIndexOf('<script');
+                    if (lastScriptPos === -1) {
+                        return false;
+                    }
+                    var lastPiece = htmlString.substring(lastScriptPos);
+
+                    return !lastPiece.match(new RegExp('<\\s*/\\s*script>'));
+                },
                 onLoad: function (callback) {
                     if (documentAlias.readyState === 'complete') {
                         callback();
@@ -914,6 +929,10 @@
             {
                 this.name = '';
                 this.type = 'JoinedVariable';
+
+                this.getDefinition = function () {
+                    return variables;
+                };
                 this.get = function () {
                     var value = '', varReturn;
                     for (var i = 0; i < variables.length; i++) {
@@ -942,6 +961,10 @@
                 this.name = '';
                 this.type = 'ConstantVariable';
 
+                this.getDefinition = function () {
+                    return value;
+                };
+
                 function isVariableDefinition(value) {
                     return value && utils.isObject(value) && !utils.isArray(value) && (utils.hasProperty(value, 'type') || utils.hasProperty(value, 'joinedVariable'));
                 }
@@ -1012,6 +1035,9 @@
                 this.defaultValue = undefined;
                 this.parameters = variable.parameters || {};
 
+                this.getDefinition = function () {
+                    return variable;
+                };
                 this.get = function () {
                     var value;
                     try {
diff --git a/javascripts/tagmanager.min.js b/javascripts/tagmanager.min.js
index ef5bba5..da04268 100644
--- a/javascripts/tagmanager.min.js
+++ b/javascripts/tagmanager.min.js
@@ -20,17 +20,17 @@ K.href=i;var G=K.href;K=document.createElement("a");K.href=G;if(J&&J in K){if("h
 }c=setTimeout(function(){c=null;var G;for(G=0;G<D.scrollCallbacks.length;G++){if(D.scrollCallbacks[G]){D.scrollCallbacks[G](i)}}},120)},onScroll:function(G){this.scrollCallbacks.push(G);if(!this.hasSetupScroll){this.hasSetupScroll=true;var i=0;for(i=0;i<this.scrollListenEvents.length;i++){if(b.addEventListener){a.addEventListener(this.scrollListenEvents[i],this.didScroll,true)}else{a.attachEvent("on"+this.scrollListenEvents[i],this.didScroll)}}}return this.scrollCallbacks.length-1},getScreenHeight:function(){return a.screen.height},getScreenWidth:function(){return a.screen.width},getViewportWidth:function(){var i=a.innerWidth||b.documentElement.clientWidth||b.body.clientWidth;if(!i){return 0}return i},getViewportHeight:function(){var i=a.innerHeight||b.documentElement.clientHeight||b.body.clientHeight;if(!i){return 0}return i},getPerformanceTiming:function(i){if("performance" in a&&B.isObject(a.performance)&&B.isObject(a.performance.timing)&&i in a.performance.timing){return a.performance.timing[i]
 }return 0}};var A={loadScriptUrl:function(H,G){if(!G){G={}}if(!B.isDefined(G.defer)){G.defer=true}if(!B.isDefined(G.async)){G.async=true}if(!B.isDefined(G.type)){G.type="text/javascript"}var i=document.createElement("script");i.src=H;i.type=G.type;i.defer=!!G.defer;i.async=!!G.async;if(B.isFunction(G.onload)){i.onload=G.onload}if(B.isFunction(G.onerror)){i.onerror=G.onerror}if(B.isDefined(G.charset)){i.charset=G.charset}if(B.isDefined(G.id)){i.id=G.id}b.head.appendChild(i)},getScrollLeft:function(){return a.document.body.scrollLeft||a.document.documentElement.scrollLeft},getScrollTop:function(){return a.document.body.scrollTop||a.document.documentElement.scrollTop},getDocumentHeight:function(){return Math.max(b.body.offsetHeight,b.body.scrollHeight,b.documentElement.offsetHeight,b.documentElement.clientHeight,b.documentElement.scrollHeight,1)},getDocumentWidth:function(){return Math.max(b.body.offsetWidth,b.body.scrollWidth,b.documentElement.offsetWidth,b.documentElement.clientWidth,b.documentElement.scrollWidth,1)
 },addEventListener:function(I,H,G,i){if(I.addEventListener){i=i||false;I.addEventListener(H,G,i);return true}if(I.attachEvent){return I.attachEvent("on"+H,G)}I["on"+H]=G},getElementText:function(G){if(!G){return}var i=G.innerText||G.textContent||"";i=i.replace(/([\s\uFEFF\xA0])+/g," ");i=i.replace(/(\s)+/g," ");return B.trim(i)},getElementClassNames:function(i){if(i&&i.className){return B.trim(String(i.className).replace(/\s{2,}/g," "))}return""},getElementAttribute:function(H,i){if(H&&H.getAttribute){return H.getAttribute(i)}if(!H||!H.attributes){return}var G=(typeof H.attributes[i]);if("undefined"===G){return null}if(H.attributes[i].value){return H.attributes[i].value}if(H.attributes[i].nodeValue){return H.attributes[i].nodeValue}return null},_htmlCollectionToArray:function(H){var i=[];if(!H||!H.length){return i}var G;for(G=0;G<H.length;G++){i.push(H[G])}return i},byId:function(i){if(B.isString(i)&&i.substr(0,1)==="#"){i=i.substr(1)}return b.getElementById(i)},byClassName:function(i){if(i&&"getElementsByClassName" in b){return this._htmlCollectionToArray(b.getElementsByClassName(i))
-}return[]},byTagName:function(i){if(i&&"getElementsByTagName" in b){return this._htmlCollectionToArray(b.getElementsByTagName(i))}return[]},bySelector:function(i){if(i&&"querySelectorAll" in b){return this._htmlCollectionToArray(b.querySelectorAll(i))}return[]},onLoad:function(i){if(b.readyState==="complete"){i()}else{if(a.addEventListener){a.addEventListener("load",i)}else{if(a.attachEvent){a.attachEvent("onload",i)}}}},onReady:function(H){var i=false;if(b.attachEvent){i=b.readyState==="complete"}else{i=b.readyState!=="loading"}if(i){H();return}if(b.addEventListener){this.addEventListener(b,"DOMContentLoaded",function G(){b.removeEventListener("DOMContentLoaded",G,false);if(!i){i=true;H()}})}else{if(b.attachEvent){b.attachEvent("onreadystatechange",function G(){if(b.readyState==="complete"){b.detachEvent("onreadystatechange",G);if(!i){i=true;H()}}})}}this.onLoad(function(){if(!i){i=true;H()}})}};function w(H){this.window=a;this.document=b;this.set=function(i,I){this[i]=I};this.get=function(I,i){if(I===null||I===false||!B.isDefined(I)){return i
-}if(I in this){if(B.isObject(this[I])&&"get" in this[I]&&B.isFunction(this[I].get)){return this[I].get()}return this[I]}var J=u(I,this);if(B.isDefined(J)){return J}return i};this.buildVariable=function(i){return o(i,this.get("container"))};if(B.isObject(H)){for(var G in H){if(B.hasProperty(H,G)){this.set(G,H[G])}}}}function z(G,i){this.isValid=function(){var I=o(G.actual,i).get();var H=o(G.expected,i).get();return B.compare(I,H,G.comparison)}}function o(G,i){if(B.isObject(G)&&G.joinedVariable&&B.isArray(G.joinedVariable)){return new q(G.joinedVariable,i)}else{if(B.isObject(G)&&G.type){return new s(G,i)}}return new l(G,i)}function q(G,i){this.name="";this.type="JoinedVariable";this.get=function(){var I="",J;for(var H=0;H<G.length;H++){J=o(G[H],i).toString();if(J!==false&&J!==null&&B.isDefined(J)){I+=J}}return I};this.toString=function(){return this.get()};this.addDebugValues=function(H){H.push({name:null,type:"_joined",value:this.get()})}}function l(I,G){this.name="";this.type="ConstantVariable";
-function H(K){return K&&B.isObject(K)&&!B.isArray(K)&&(B.hasProperty(K,"type")||B.hasProperty(K,"joinedVariable"))}function J(M){if(M==null||typeof M!=="object"){return M}var K=new M.constructor();var L;for(L in M){if(B.hasProperty(M,L)){K[L]=J(M[L])}}return K}function i(L){var K;if(H(L)){L=o(L,G).get()}else{if(L&&B.isArray(L)){for(K=0;K<L.length;K++){L[K]=i(L[K])}}else{if(L&&B.isObject(L)){for(K in L){if(B.hasProperty(L,K)){L[K]=i(L[K])}}}}}return L}this.get=function(){if(B.isObject(I)){I=J(I);I=i(I)}return I};this.toString=function(){return I};this.addDebugValues=function(K){K.push({name:null,type:"_constant",value:this.get()})}}function s(I,H){this.type=I.type;this.name=I.name;this.lookUpTable=I.lookUpTable||[];this.defaultValue=undefined;this.parameters=I.parameters||{};this.get=function(){var M;try{M=this.theVariable.get()}catch(N){y.error("Failed to get value of variable",N,this);M=undefined}if((!B.isDefined(M)||M===null||M===false)&&B.isDefined(this.defaultValue)){M=this.defaultValue
-}var L;for(L=0;L<this.lookUpTable.length;L++){var O=this.lookUpTable[L];if(B.compare(M,O.matchValue,O.comparison)){return O.outValue}}return M};this.toString=function(){if(this.theVariable&&B.hasProperty(this.theVariable,"toString")&&B.isFunction(this.theVariable.toString)){try{return this.theVariable.toString()}catch(i){y.error("Failed to get toString of variable",i,this);return}}return this.get()};this.addDebugValues=function(i){i.push({name:this.name,type:this.type,value:this.get()})};if("undefined"!==typeof I.defaultValue){this.defaultValue=I.defaultValue}if(!B.isDefined(I.Variable)||!I.Variable){y.log("no template defined for variable ",I);return}var J,K=new w({variable:this,container:H});if(B.isObject(I.parameters)){for(J in I.parameters){if(B.hasProperty(I.parameters,J)){K.set(J,o(I.parameters[J],H))}}}if(B.isFunction(I.Variable)){this.theVariable=new I.Variable(K,k)}else{if(B.isObject(I.Variable)){this.theVariable=I.Variable}else{if(I.Variable in H.templates){var G=H.templates[I.Variable]();
-this.theVariable=new G(K,k)}else{C("No matching variable template found")}}}}function f(J,H){this.referencedTags=[];this.id=J.id;this.type=J.type;this.name=J.name;this.conditions=[];this.parameters=J.parameters||{};var I=this;this.getId=function(){return this.id};this.setUp=function(){if(this.theTrigger&&this.theTrigger.setUp&&B.isFunction(this.theTrigger.setUp)){this.theTrigger.setUp(function(Q){p.push(Q);if(!("event" in Q)){return}var M={tags:[],variables:[],metTrigger:null,name:Q.event,eventData:Q,container:{}};var P,O;if(I.meetsConditions()){y.log("The condition is met for trigger "+I.name,I);M.metTrigger={name:I.name,type:I.type};var N=I.getReferencedTags();for(O=0;O<N.length;O++){if(N[O].hasBlockTrigger(I)){N[O].block();N[O].addDebugValues(M.tags,"Block")}else{if(N[O].hasFireTrigger(I)){N[O].fire();N[O].addDebugValues(M.tags,"Fire")}}}}if(window.mtmPreviewWindow||y.enabled){H.addDebugValues(M.container);d(M);if(y.enabled){y.log("event: ",M)}}})}};this.addReferencedTag=function(i){this.referencedTags.push(i)
-};this.getReferencedTags=function(){return this.referencedTags};this.meetsConditions=function(){var M,N;for(M=0;M<this.conditions.length;M++){N=new z(this.conditions[M],H);if(!N.isValid()){return false}}return true};if(J.conditions&&B.isArray(J.conditions)){this.conditions=J.conditions}var K,L=new w({trigger:this,container:H});if(B.isObject(J.parameters)){for(K in J.parameters){if(B.hasProperty(J.parameters,K)){L.set(K,o(J.parameters[K],H))}}}if(!B.isDefined(J.Trigger)||!J.Trigger){y.error("no template defined for trigger ",J);return}if(B.isFunction(J.Trigger)){this.theTrigger=new J.Trigger(L,k)}else{if(B.isObject(J.Trigger)){this.theTrigger=J.Trigger}else{var G=H.templates[J.Trigger]();this.theTrigger=new G(L,k)}}L=null}function g(G,H){this.type=G.type;this.name=G.name;this.fireTriggerIds=G.fireTriggerIds?G.fireTriggerIds:[];this.blockTriggerIds=G.blockTriggerIds?G.blockTriggerIds:[];this.fireLimit=G.fireLimit?G.fireLimit:g.FIRE_LIMIT_UNLIMITED;this.fireDelay=G.fireDelay?parseInt(G.fireDelay,10):0;
-this.startDate=G.startDate?G.startDate:null;this.endDate=G.endDate?G.endDate:null;this.numExecuted=0;this.blocked=false;this.parameters=G.parameters||{};var I=this;this.addDebugValues=function(i,M){i.push({action:M,type:this.type,name:this.name,numExecuted:this.numExecuted})};this._doFire=function(){if(this.blocked){y.log("not firing as this tag is blocked",this);return"tag is blocked"}if(this.fireLimit!==g.FIRE_LIMIT_UNLIMITED&&this.numExecuted){y.log("not firing as this tag has limit reached",this);return"fire limit is restricted"}var M="tag";if(H.id){M+="_"+H.id}if(this.fireLimit===g.FIRE_LIMIT_ONCE_24HOURS&&!window.mtmPreviewWindow){if(x.get(M,this.name)){y.log("not firing as this tag has 24hours limit reached",this);return"fire limit 24hours is restricted"}}if(this.fireLimit===g.FIRE_LIMIT_ONCE_LIFETIME&&!window.mtmPreviewWindow){if(x.get(M,this.name)){y.log("not firing as this tag has limit reached",this);return"fire limit lifetime is restricted"}}if(!E.matchesDateRange(new Date(),this.startDate,this.endDate)){y.log("not firing as this tag does not match date",this);
-return"date range does not match"}y.log("firing this tag",this);this.numExecuted++;if(this.fireLimit===g.FIRE_LIMIT_ONCE_24HOURS){var i=24*60*60;x.set(M,this.name,"1",i)}if(this.fireLimit===g.FIRE_LIMIT_ONCE_LIFETIME){x.set(M,this.name,"1")}this.theTag.fire();y.log("fired this tag",this)};this.fire=function(){if(this.fireDelay){setTimeout(function(){I._doFire()},this.fireDelay)}else{return this._doFire()}};this.block=function(){this.blocked=true};this.hasFireTrigger=function(i){if(!this.fireTriggerIds||!this.fireTriggerIds.length){return false}if(!i){return false}var M=i.getId();return B.indexOfArray(this.fireTriggerIds,M)!==-1};this.hasBlockTrigger=function(i){if(!this.blockTriggerIds||!this.blockTriggerIds.length){return false}if(!i){return false}var M=i.getId();return B.indexOfArray(this.blockTriggerIds,M)!==-1};if(!B.isDefined(G.Tag)||!G.Tag){y.error("no template defined for tag ",G);return}var K,L=new w({tag:this,container:H});if(B.isObject(G.parameters)){for(K in G.parameters){if(B.hasProperty(G.parameters,K)){L.set(K,o(G.parameters[K],H))
-}}}if(B.isFunction(G.Tag)){this.theTag=new G.Tag(L,k)}else{if(B.isObject(G.Tag)){this.theTag=G.Tag}else{var J=H.templates[G.Tag]();this.theTag=new J(L,k)}}}g.FIRE_LIMIT_ONCE_PAGE="once_page";g.FIRE_LIMIT_ONCE_24HOURS="once_24hours";g.FIRE_LIMIT_ONCE_LIFETIME="once_lifetime";g.FIRE_LIMIT_UNLIMITED="unlimited";function n(H,M){var I=this;this.id=H.id;this.idsite=H.idsite||null;this.versionName=H.versionName||null;this.revision=H.revision||null;this.environment=H.environment||null;this.templates=M||{};this.dataLayer=new t();this.variables=[];this.triggers=[];this.tags=[];this.onNewGlobalDataLayerValue=function(i){this.dataLayer.push(i)};p.on(function(i){I.onNewGlobalDataLayerValue(i)});this.addDebugValues=function(O){O.variables=[];var P;for(P=0;P<this.variables.length;P++){this.variables[P].addDebugValues(O.variables)}O.tags=[];for(P=0;P<this.tags.length;P++){this.tags[P].addDebugValues(O.tags,"Not Fired Yet")}O.id=this.id;O.versionName=this.versionName;O.dataLayer=JSON.parse(JSON.stringify(this.dataLayer.values))
-};this.getTriggerById=function(O){if(!O){return}var P;for(P=0;P<this.triggers.length;P++){if(this.triggers[P].getId()===O){return this.triggers[P]}}};this.addTrigger=function(i){if(!i){return}var O=this.getTriggerById(i.id);if(!O){O=new f(i,this);this.triggers.push(O)}return O};var L,K,G,N,J;if(H.variables&&B.isArray(H.variables)){for(L=0;L<H.variables.length;L++){this.variables.push(o(H.variables[L],this))}}if(H.triggers&&B.isArray(H.triggers)){for(L=0;L<H.triggers.length;L++){this.addTrigger(H.triggers[L])}}if(H.tags&&B.isArray(H.tags)){for(L=0;L<H.tags.length;L++){N=H.tags[L];G=new g(N,this);this.tags.push(G);if(N.blockTriggerIds&&B.isArray(N.blockTriggerIds)){for(K=0;K<N.blockTriggerIds.length;K++){J=this.getTriggerById(N.blockTriggerIds[K]);if(J){J.addReferencedTag(G)}}}if(N.fireTriggerIds&&B.isArray(N.fireTriggerIds)){for(K=0;K<N.fireTriggerIds.length;K++){J=this.getTriggerById(N.fireTriggerIds[K]);if(J){J.addReferencedTag(G)}}}}}this.run=function(){var P=p.getAllEvents();var O;for(O=0;
-O<P.length;O++){this.onNewGlobalDataLayerValue(P[O])}for(O=0;O<this.triggers.length;O++){this.triggers[O].setUp()}}}var k={THROW_ERRORS:true,dataLayer:p,containers:[],url:r,date:E,utils:B,debug:y,dom:A,window:D,Variable:s,storage:{local:x,session:e},_buildVariable:o,Condition:z,TemplateParameters:w,Trigger:f,Tag:g,throwError:C,Container:n,addContainer:function(I,G){if(!window.mtmPreviewWindow){var H=b.getElementById("mtmDebugFrame");if(H&&H.contentWindow){window.mtmPreviewWindow=H.contentWindow}}y.log("creating container");var i=new n(I,G);this.containers.push(i);i.dataLayer.push({"mtm.containerId":i.id});y.log("running container");i.run();return i},enableDebugMode:function(){y.enabled=true}};if("matomoTagManagerAsyncInit" in a&&B.isFunction(a.matomoTagManagerAsyncInit)){a.matomoTagManagerAsyncInit()}var m=a._mtm;a._mtm={push:function(){var K,I,H,M,N;for(K=0;K<arguments.length;K+=1){N=null;if(arguments[K]&&arguments[K].slice){N=arguments[K].slice()}M=arguments[K];if(B.isObject(M)&&!B.isArray(M)){p.push(M);
-continue}H=M.shift();var L=B.isString(H)&&H.indexOf("::")>0;if(L){var G,J;G=H.split("::");J=G[0];H=G[1];if("object"===typeof k[J]&&B.isFunction(k[J][H])){k[J][H].apply(k[J],M)}}else{if(H&&H in k&&B.isFunction(k[H])){k[H].apply(k,M)}else{y.error("method "+H+" is not valid")}}}}};var v;for(v=0;v<m.length;v++){a._mtm.push(m[v])}p.push({"mtm.mtmScriptLoadedTime":j});if("undefined"!==typeof a.dataLayer&&B.isArray(a.dataLayer)){for(v=0;v<a.dataLayer.length;v++){if(B.isObject(a.dataLayer[v])){p.push(a.dataLayer[v])}}}return k})()}
+}return[]},byTagName:function(i){if(i&&"getElementsByTagName" in b){return this._htmlCollectionToArray(b.getElementsByTagName(i))}return[]},bySelector:function(i){if(i&&"querySelectorAll" in b){return this._htmlCollectionToArray(b.querySelectorAll(i))}return[]},isJsContext:function(H){if(!H){return false}H=String(H).toLowerCase();var G=H.lastIndexOf("<script");if(G===-1){return false}var i=H.substring(G);return !i.match(new RegExp("<\\s*/\\s*script>"))},onLoad:function(i){if(b.readyState==="complete"){i()}else{if(a.addEventListener){a.addEventListener("load",i)}else{if(a.attachEvent){a.attachEvent("onload",i)}}}},onReady:function(H){var i=false;if(b.attachEvent){i=b.readyState==="complete"}else{i=b.readyState!=="loading"}if(i){H();return}if(b.addEventListener){this.addEventListener(b,"DOMContentLoaded",function G(){b.removeEventListener("DOMContentLoaded",G,false);if(!i){i=true;H()}})}else{if(b.attachEvent){b.attachEvent("onreadystatechange",function G(){if(b.readyState==="complete"){b.detachEvent("onreadystatechange",G);
+if(!i){i=true;H()}}})}}this.onLoad(function(){if(!i){i=true;H()}})}};function w(H){this.window=a;this.document=b;this.set=function(i,I){this[i]=I};this.get=function(I,i){if(I===null||I===false||!B.isDefined(I)){return i}if(I in this){if(B.isObject(this[I])&&"get" in this[I]&&B.isFunction(this[I].get)){return this[I].get()}return this[I]}var J=u(I,this);if(B.isDefined(J)){return J}return i};this.buildVariable=function(i){return o(i,this.get("container"))};if(B.isObject(H)){for(var G in H){if(B.hasProperty(H,G)){this.set(G,H[G])}}}}function z(G,i){this.isValid=function(){var I=o(G.actual,i).get();var H=o(G.expected,i).get();return B.compare(I,H,G.comparison)}}function o(G,i){if(B.isObject(G)&&G.joinedVariable&&B.isArray(G.joinedVariable)){return new q(G.joinedVariable,i)}else{if(B.isObject(G)&&G.type){return new s(G,i)}}return new l(G,i)}function q(G,i){this.name="";this.type="JoinedVariable";this.getDefinition=function(){return G};this.get=function(){var I="",J;for(var H=0;H<G.length;H++){J=o(G[H],i).toString();
+if(J!==false&&J!==null&&B.isDefined(J)){I+=J}}return I};this.toString=function(){return this.get()};this.addDebugValues=function(H){H.push({name:null,type:"_joined",value:this.get()})}}function l(I,G){this.name="";this.type="ConstantVariable";this.getDefinition=function(){return I};function H(K){return K&&B.isObject(K)&&!B.isArray(K)&&(B.hasProperty(K,"type")||B.hasProperty(K,"joinedVariable"))}function J(M){if(M==null||typeof M!=="object"){return M}var K=new M.constructor();var L;for(L in M){if(B.hasProperty(M,L)){K[L]=J(M[L])}}return K}function i(L){var K;if(H(L)){L=o(L,G).get()}else{if(L&&B.isArray(L)){for(K=0;K<L.length;K++){L[K]=i(L[K])}}else{if(L&&B.isObject(L)){for(K in L){if(B.hasProperty(L,K)){L[K]=i(L[K])}}}}}return L}this.get=function(){if(B.isObject(I)){I=J(I);I=i(I)}return I};this.toString=function(){return I};this.addDebugValues=function(K){K.push({name:null,type:"_constant",value:this.get()})}}function s(I,H){this.type=I.type;this.name=I.name;this.lookUpTable=I.lookUpTable||[];
+this.defaultValue=undefined;this.parameters=I.parameters||{};this.getDefinition=function(){return I};this.get=function(){var M;try{M=this.theVariable.get()}catch(N){y.error("Failed to get value of variable",N,this);M=undefined}if((!B.isDefined(M)||M===null||M===false)&&B.isDefined(this.defaultValue)){M=this.defaultValue}var L;for(L=0;L<this.lookUpTable.length;L++){var O=this.lookUpTable[L];if(B.compare(M,O.matchValue,O.comparison)){return O.outValue}}return M};this.toString=function(){if(this.theVariable&&B.hasProperty(this.theVariable,"toString")&&B.isFunction(this.theVariable.toString)){try{return this.theVariable.toString()}catch(i){y.error("Failed to get toString of variable",i,this);return}}return this.get()};this.addDebugValues=function(i){i.push({name:this.name,type:this.type,value:this.get()})};if("undefined"!==typeof I.defaultValue){this.defaultValue=I.defaultValue}if(!B.isDefined(I.Variable)||!I.Variable){y.log("no template defined for variable ",I);return}var J,K=new w({variable:this,container:H});
+if(B.isObject(I.parameters)){for(J in I.parameters){if(B.hasProperty(I.parameters,J)){K.set(J,o(I.parameters[J],H))}}}if(B.isFunction(I.Variable)){this.theVariable=new I.Variable(K,k)}else{if(B.isObject(I.Variable)){this.theVariable=I.Variable}else{if(I.Variable in H.templates){var G=H.templates[I.Variable]();this.theVariable=new G(K,k)}else{C("No matching variable template found")}}}}function f(J,H){this.referencedTags=[];this.id=J.id;this.type=J.type;this.name=J.name;this.conditions=[];this.parameters=J.parameters||{};var I=this;this.getId=function(){return this.id};this.setUp=function(){if(this.theTrigger&&this.theTrigger.setUp&&B.isFunction(this.theTrigger.setUp)){this.theTrigger.setUp(function(Q){p.push(Q);if(!("event" in Q)){return}var M={tags:[],variables:[],metTrigger:null,name:Q.event,eventData:Q,container:{}};var P,O;if(I.meetsConditions()){y.log("The condition is met for trigger "+I.name,I);M.metTrigger={name:I.name,type:I.type};var N=I.getReferencedTags();for(O=0;O<N.length;
+O++){if(N[O].hasBlockTrigger(I)){N[O].block();N[O].addDebugValues(M.tags,"Block")}else{if(N[O].hasFireTrigger(I)){N[O].fire();N[O].addDebugValues(M.tags,"Fire")}}}}if(window.mtmPreviewWindow||y.enabled){H.addDebugValues(M.container);d(M);if(y.enabled){y.log("event: ",M)}}})}};this.addReferencedTag=function(i){this.referencedTags.push(i)};this.getReferencedTags=function(){return this.referencedTags};this.meetsConditions=function(){var M,N;for(M=0;M<this.conditions.length;M++){N=new z(this.conditions[M],H);if(!N.isValid()){return false}}return true};if(J.conditions&&B.isArray(J.conditions)){this.conditions=J.conditions}var K,L=new w({trigger:this,container:H});if(B.isObject(J.parameters)){for(K in J.parameters){if(B.hasProperty(J.parameters,K)){L.set(K,o(J.parameters[K],H))}}}if(!B.isDefined(J.Trigger)||!J.Trigger){y.error("no template defined for trigger ",J);return}if(B.isFunction(J.Trigger)){this.theTrigger=new J.Trigger(L,k)}else{if(B.isObject(J.Trigger)){this.theTrigger=J.Trigger}else{var G=H.templates[J.Trigger]();
+this.theTrigger=new G(L,k)}}L=null}function g(G,H){this.type=G.type;this.name=G.name;this.fireTriggerIds=G.fireTriggerIds?G.fireTriggerIds:[];this.blockTriggerIds=G.blockTriggerIds?G.blockTriggerIds:[];this.fireLimit=G.fireLimit?G.fireLimit:g.FIRE_LIMIT_UNLIMITED;this.fireDelay=G.fireDelay?parseInt(G.fireDelay,10):0;this.startDate=G.startDate?G.startDate:null;this.endDate=G.endDate?G.endDate:null;this.numExecuted=0;this.blocked=false;this.parameters=G.parameters||{};var I=this;this.addDebugValues=function(i,M){i.push({action:M,type:this.type,name:this.name,numExecuted:this.numExecuted})};this._doFire=function(){if(this.blocked){y.log("not firing as this tag is blocked",this);return"tag is blocked"}if(this.fireLimit!==g.FIRE_LIMIT_UNLIMITED&&this.numExecuted){y.log("not firing as this tag has limit reached",this);return"fire limit is restricted"}var M="tag";if(H.id){M+="_"+H.id}if(this.fireLimit===g.FIRE_LIMIT_ONCE_24HOURS&&!window.mtmPreviewWindow){if(x.get(M,this.name)){y.log("not firing as this tag has 24hours limit reached",this);
+return"fire limit 24hours is restricted"}}if(this.fireLimit===g.FIRE_LIMIT_ONCE_LIFETIME&&!window.mtmPreviewWindow){if(x.get(M,this.name)){y.log("not firing as this tag has limit reached",this);return"fire limit lifetime is restricted"}}if(!E.matchesDateRange(new Date(),this.startDate,this.endDate)){y.log("not firing as this tag does not match date",this);return"date range does not match"}y.log("firing this tag",this);this.numExecuted++;if(this.fireLimit===g.FIRE_LIMIT_ONCE_24HOURS){var i=24*60*60;x.set(M,this.name,"1",i)}if(this.fireLimit===g.FIRE_LIMIT_ONCE_LIFETIME){x.set(M,this.name,"1")}this.theTag.fire();y.log("fired this tag",this)};this.fire=function(){if(this.fireDelay){setTimeout(function(){I._doFire()},this.fireDelay)}else{return this._doFire()}};this.block=function(){this.blocked=true};this.hasFireTrigger=function(i){if(!this.fireTriggerIds||!this.fireTriggerIds.length){return false}if(!i){return false}var M=i.getId();return B.indexOfArray(this.fireTriggerIds,M)!==-1};this.hasBlockTrigger=function(i){if(!this.blockTriggerIds||!this.blockTriggerIds.length){return false
+}if(!i){return false}var M=i.getId();return B.indexOfArray(this.blockTriggerIds,M)!==-1};if(!B.isDefined(G.Tag)||!G.Tag){y.error("no template defined for tag ",G);return}var K,L=new w({tag:this,container:H});if(B.isObject(G.parameters)){for(K in G.parameters){if(B.hasProperty(G.parameters,K)){L.set(K,o(G.parameters[K],H))}}}if(B.isFunction(G.Tag)){this.theTag=new G.Tag(L,k)}else{if(B.isObject(G.Tag)){this.theTag=G.Tag}else{var J=H.templates[G.Tag]();this.theTag=new J(L,k)}}}g.FIRE_LIMIT_ONCE_PAGE="once_page";g.FIRE_LIMIT_ONCE_24HOURS="once_24hours";g.FIRE_LIMIT_ONCE_LIFETIME="once_lifetime";g.FIRE_LIMIT_UNLIMITED="unlimited";function n(H,M){var I=this;this.id=H.id;this.idsite=H.idsite||null;this.versionName=H.versionName||null;this.revision=H.revision||null;this.environment=H.environment||null;this.templates=M||{};this.dataLayer=new t();this.variables=[];this.triggers=[];this.tags=[];this.onNewGlobalDataLayerValue=function(i){this.dataLayer.push(i)};p.on(function(i){I.onNewGlobalDataLayerValue(i)
+});this.addDebugValues=function(O){O.variables=[];var P;for(P=0;P<this.variables.length;P++){this.variables[P].addDebugValues(O.variables)}O.tags=[];for(P=0;P<this.tags.length;P++){this.tags[P].addDebugValues(O.tags,"Not Fired Yet")}O.id=this.id;O.versionName=this.versionName;O.dataLayer=JSON.parse(JSON.stringify(this.dataLayer.values))};this.getTriggerById=function(O){if(!O){return}var P;for(P=0;P<this.triggers.length;P++){if(this.triggers[P].getId()===O){return this.triggers[P]}}};this.addTrigger=function(i){if(!i){return}var O=this.getTriggerById(i.id);if(!O){O=new f(i,this);this.triggers.push(O)}return O};var L,K,G,N,J;if(H.variables&&B.isArray(H.variables)){for(L=0;L<H.variables.length;L++){this.variables.push(o(H.variables[L],this))}}if(H.triggers&&B.isArray(H.triggers)){for(L=0;L<H.triggers.length;L++){this.addTrigger(H.triggers[L])}}if(H.tags&&B.isArray(H.tags)){for(L=0;L<H.tags.length;L++){N=H.tags[L];G=new g(N,this);this.tags.push(G);if(N.blockTriggerIds&&B.isArray(N.blockTriggerIds)){for(K=0;
+K<N.blockTriggerIds.length;K++){J=this.getTriggerById(N.blockTriggerIds[K]);if(J){J.addReferencedTag(G)}}}if(N.fireTriggerIds&&B.isArray(N.fireTriggerIds)){for(K=0;K<N.fireTriggerIds.length;K++){J=this.getTriggerById(N.fireTriggerIds[K]);if(J){J.addReferencedTag(G)}}}}}this.run=function(){var P=p.getAllEvents();var O;for(O=0;O<P.length;O++){this.onNewGlobalDataLayerValue(P[O])}for(O=0;O<this.triggers.length;O++){this.triggers[O].setUp()}}}var k={THROW_ERRORS:true,dataLayer:p,containers:[],url:r,date:E,utils:B,debug:y,dom:A,window:D,Variable:s,storage:{local:x,session:e},_buildVariable:o,Condition:z,TemplateParameters:w,Trigger:f,Tag:g,throwError:C,Container:n,addContainer:function(I,G){if(!window.mtmPreviewWindow){var H=b.getElementById("mtmDebugFrame");if(H&&H.contentWindow){window.mtmPreviewWindow=H.contentWindow}}y.log("creating container");var i=new n(I,G);this.containers.push(i);i.dataLayer.push({"mtm.containerId":i.id});y.log("running container");i.run();return i},enableDebugMode:function(){y.enabled=true
+}};if("matomoTagManagerAsyncInit" in a&&B.isFunction(a.matomoTagManagerAsyncInit)){a.matomoTagManagerAsyncInit()}var m=a._mtm;a._mtm={push:function(){var K,I,H,M,N;for(K=0;K<arguments.length;K+=1){N=null;if(arguments[K]&&arguments[K].slice){N=arguments[K].slice()}M=arguments[K];if(B.isObject(M)&&!B.isArray(M)){p.push(M);continue}H=M.shift();var L=B.isString(H)&&H.indexOf("::")>0;if(L){var G,J;G=H.split("::");J=G[0];H=G[1];if("object"===typeof k[J]&&B.isFunction(k[J][H])){k[J][H].apply(k[J],M)}}else{if(H&&H in k&&B.isFunction(k[H])){k[H].apply(k,M)}else{y.error("method "+H+" is not valid")}}}}};var v;for(v=0;v<m.length;v++){a._mtm.push(m[v])}p.push({"mtm.mtmScriptLoadedTime":j});if("undefined"!==typeof a.dataLayer&&B.isArray(a.dataLayer)){for(v=0;v<a.dataLayer.length;v++){if(B.isObject(a.dataLayer[v])){p.push(a.dataLayer[v])}}}return k})()}
 /*!!! initContainerHook */
-})();
\ No newline at end of file
+})();
diff --git a/lang/en.json b/lang/en.json
index 9a675af..ade58e3 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -188,7 +188,7 @@
       "ErrorContainerVersionImportWrongContext": "The context of the current container is \"%s\" but the imported content is of context \"%s\". Cannot import this version.",
       "ErrorEndDateBeforeStartDate": "The start date needs to be earlier than the end date.",
       "ErrorEnvironmentDoesNotExist": "The environment \"%s\" does not exist.",
-      "ErrorEnvironmentInvalidLength": "The environment \"%1$s\" does not have a valid length. Please use between %2$s and %3$s characters.",
+      "ErrorEnvironmentInvalidLength": "The environment \"%1$s\" is not a valid. Please use between %2$s and %3$s characters.",
       "ErrorEnvironmentInvalidName": "The environment \"%s\" is not a valid name. Please use only letters, numbers, and underscores.",
       "ErrorInnerIsNotAnArray": "Each \"%1$s\" within \"%2$s\" has to be an array.",
       "ErrorInvalidContainerImportFormat": "Invalid format for exportedContainerVersion. Value needs to be a valid JSON.",
diff --git a/stylesheets/manageEdit.less b/stylesheets/manageEdit.less
index 76f380f..aaa1289 100644
--- a/stylesheets/manageEdit.less
+++ b/stylesheets/manageEdit.less
@@ -39,9 +39,9 @@
       margin-right: 8px;
     }
 
-    .icon-plus, .icon-minus {
+    .icon-edit, .icon-plus, .icon-minus {
       position: relative;
-      cursor: pointer;
+      cursor: pointer !important;
     }
 
   }
diff --git a/tests/Integration/Model/EnvironmentTest.php b/tests/Integration/Model/EnvironmentTest.php
index f4e6d9b..161b0b5 100644
--- a/tests/Integration/Model/EnvironmentTest.php
+++ b/tests/Integration/Model/EnvironmentTest.php
@@ -64,7 +64,7 @@ class EnvironmentTest extends IntegrationTestCase
 
     /**
      * @expectedException \Exception
-     * @expectedExceptionMessage The environment "fooffffffffffffffffffffffffffffffffffffff" does not have a valid length. Please use between 2 and 40 characters.
+     * @expectedExceptionMessage The environment "fooffffffffffffffffffffffffffffffffffffff" is not a valid. Please use between 2 and 40 characters.
      */
     public function test_checkEnvironmentNameFormat_tooLong()
     {
diff --git a/tests/Integration/SystemSettingTest.php b/tests/Integration/SystemSettingTest.php
index 1e0647f..0c27df5 100644
--- a/tests/Integration/SystemSettingTest.php
+++ b/tests/Integration/SystemSettingTest.php
@@ -127,7 +127,7 @@ class SystemSettingTest extends IntegrationTestCase
 
     /**
      * @expectedException \Exception
-     * @expectedExceptionMessage does not have a valid length
+     * @expectedExceptionMessage is not a valid
      */
     public function test_getEnvironments_validatesTheName()
     {
diff --git a/tests/javascript/index.php b/tests/javascript/index.php
index 63ef29c..841d027 100644
--- a/tests/javascript/index.php
+++ b/tests/javascript/index.php
@@ -558,11 +558,10 @@
                 result = utils.compare(atest.actualValue, atest.expectedValue, 'not_' + atest.type);
                 strictEqual(!atest.expected, result, '_compare: ' + JSON.stringify(atest));
             }
-
         });
 
         test("Matomo TagManager dom", function() {
-            expect(45);
+            expect(55);
 
             var dom = window.MatomoTagManager.dom;
 
@@ -581,6 +580,7 @@
             equal(typeof dom.bySelector, 'function', 'dom.bySelector');
             equal(typeof dom.onLoad, 'function', 'dom.onLoad');
             equal(typeof dom.onReady, 'function', 'dom.onReady');
+            equal(typeof dom.isJsContext, 'function', 'dom.isJsContext');
 
             var scrollLeft = dom.getScrollLeft();
             var scrollTop = dom.getScrollTop();
@@ -639,6 +639,16 @@
             strictEqual('myTagTest myTagFoo myTagTest4', dom.getElementClassNames(dom.byId('TagManager')), 'getElementClassNames, when has classes');
             strictEqual('', dom.getElementClassNames(dom.byId('customTag3')), 'getElementClassNames, when has no classes');
 
+            strictEqual(false, dom.isJsContext(null), 'isJsContext, no value given');
+            strictEqual(false, dom.isJsContext('<div>var foo ="'), 'isJsContext, not a script element');
+            strictEqual(false, dom.isJsContext('<div>var foo =""</div>'), 'isJsContext, not a closing script element');
+            strictEqual(true, dom.isJsContext('<script>var foo ="'), 'isJsContext, in the middle of a script element');
+            strictEqual(true, dom.isJsContext('<scRipT>var foo ="'), 'isJsContext, in the middle of a script element case insensitive');
+            strictEqual(false, dom.isJsContext('<div>var foo < /script>'), 'isJsContext, not an opening script element');
+            strictEqual(true, dom.isJsContext('<script>var foo ="</ div>'), 'isJsContext, not a closing script element');
+            strictEqual(false, dom.isJsContext('<script>var foo =""< / script>'), 'isJsContext, not in a script element');
+            strictEqual(false, dom.isJsContext('<script>var foo =""</'+ 'scrIpT>'), 'isJsContext, not in a script element');
+
             var div = document.createElement('div');
             div.className = '   fo   otest  hello world         ';
             strictEqual('fo otest hello world', dom.getElementClassNames(div), 'getElementClassNames, trims and removes whitespace');
@@ -721,9 +731,11 @@
         });
 
         test("Matomo TagManager Template Variable", function() {
-            expect(42);
+            expect(46);
 
             strictEqual('ConstantVariable', getConstructorName(buildVariable('footest')), 'buildVariable, makes a constant variable');
+            strictEqual('footest', buildVariable('footest').getDefinition(), 'ConstantVariable, getDefinition returns string');
+            strictEqual(false, buildVariable(false).getDefinition(), 'ConstantVariable, getDefinition returns other input');
             strictEqual('footest', buildVariable('footest').get(), 'ConstantVariable, makes a constant variable when a string given');
             strictEqual('footest6', buildVariable('footest6').toString(), 'ConstantVariable, has a toString method');
             strictEqual(5, buildVariable(5).get(), 'ConstantVariable, makes a constant variable when a number given');
@@ -751,6 +763,7 @@
             strictEqual('test14', buildVariable(varWithObjectTemplate).get(), 'Variable, can work with a template object');
             strictEqual('test12', buildVariable(varWithStringTemplate, {myTemplate: function () { return varWithFunctionTemplate.Variable; }}).get(), 'Variable, can resolve a string container template');
             strictEqual('test12', buildVariable(varWithFunctionTemplate).toString(), 'Variable, has a toString method');
+            deepEqual(varWithStringTemplate, buildVariable(varWithStringTemplate, {myTemplate: function () { return varWithFunctionTemplate.Variable; }}).getDefinition(), 'Variable, getDefinition');
 
             try {
                 strictEqual('test12', buildVariable(varWithStringTemplate).get(), 'Variable, triggers an error when string template not found');
@@ -778,6 +791,7 @@
             strictEqual('footest12bartest145', buildVariable({joinedVariable:['foo', varWithFunctionTemplate, 'bar', varWithObjectTemplate, 5]}).get(), 'JoinedVariable, combines the value of multiple variables');
             strictEqual('footest1205', buildVariable({joinedVariable:['foo', varWithFunctionTemplate, false, 0, null, undefined, 5]}).get(), 'JoinedVariable, does not have a problem with empty values');
             strictEqual('footest12', buildVariable({joinedVariable:['foo', varWithFunctionTemplate]}).toString(), 'JoinedVariable, has a toString()');
+            deepEqual(['foo', varWithFunctionTemplate], buildVariable({joinedVariable:['foo', varWithFunctionTemplate]}).getDefinition(), 'JoinedVariable getDefinition');
 
             deepEqual(['foo', 'bar'], buildVariable(['foo', 'bar']).get(), 'treats a regular array as an array and not any kind of variable');
             strictEqual('ConstantVariable', getConstructorName(buildVariable(['foo', 'bar'])), 'uses a constant variable for a regular array');
@@ -2246,7 +2260,7 @@
         });
 
         test("Matomo TagManager Template CustomHtmlTag", function() {
-            expect(3);
+            expect(8);
             var templateToTest = 'CustomHtmlTag';
             var params = {document: document, customHtml: buildVariable('<div id="customHtmlTag1">my foo bar baz test</div><div id="customHtmlTag2">my test</div>')};
 
@@ -2262,8 +2276,45 @@
             fireTemplateTag(templateToTest, params);
             var addedStyle1 = document.getElementById('customStyleTag');
 
-            strictEqual('.test{}', addedStyle1.innerText, 'should have added element to start of head');
+            strictEqual('.test{}', addedStyle1.innerText, 'should have added element to start of head style1');
             document.head.removeChild(addedStyle1);
+
+            // testing joined
+            params.customHtml = buildVariable({joinedVariable:['<div id="customStyleTag3">', '.test{}', '</div>']});
+            fireTemplateTag(templateToTest, params);
+            var addedStyle3 = document.getElementById('customStyleTag3');
+            strictEqual('.test{}', addedStyle3.innerText, 'should have added element to start of head style3');
+            document.head.removeChild(addedStyle3);
+
+            // does not escape hardcoded string
+            params.customHtml = buildVariable({joinedVariable:['<script id="customStyleTag4">', 'var x = {};', '</' + 'script>']});
+            fireTemplateTag(templateToTest, params);
+            var addedStyle4 = document.getElementById('customStyleTag4');
+            strictEqual('var x = {};', addedStyle4.innerText, 'should have added element to start of head');
+            document.head.removeChild(addedStyle4);
+
+            // auto escapes JS when through variable
+            params.customHtml = buildVariable({joinedVariable:['<script id="customStyleTag4">var x = "', {type: 'mytype2', name: 'myname2', Variable: {get: function (){ return '{}'; }}}, '"</' + 'script>']});
+
+            fireTemplateTag(templateToTest, params);
+            var addedStyle4 = document.getElementById('customStyleTag4');
+            strictEqual('var x = "\\x7B\\x7D"', addedStyle4.innerText, 'should have added element to start of head');
+            document.head.removeChild(addedStyle4);
+
+            // no auto escape for regular div when through variable
+            params.customHtml = buildVariable({joinedVariable:['<div id="customStyleTag4">var x = "', {type: 'mytype2', name: 'myname2', Variable: {get: function (){ return '{}'; }}}, '"</' + 'div>']});
+
+            fireTemplateTag(templateToTest, params);
+            var addedStyle4 = document.getElementById('customStyleTag4');
+            strictEqual('var x = "{}"', addedStyle4.innerText, 'should have added element to start of head');
+            document.head.removeChild(addedStyle4);
+
+            // auto resolves objects
+            params.customHtml = buildVariable({joinedVariable:['<script id="customStyleTag4">', {mytest: 'mytype2', myfoo: 'myname2'}, '</' + 'script>']});
+            fireTemplateTag(templateToTest, params);
+            var addedStyle4 = document.getElementById('customStyleTag4');
+            strictEqual('window.MatomoTagManager.customHtmlDataStore[0]()', addedStyle4.innerText, 'should have added element to start of head');
+            document.head.removeChild(addedStyle4);
         });
 
         test("Matomo TagManager Template MatomoTag", function() {
