Ubuntu
(function () {
/*!
* secure-filters 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
* */
function convertControlCharacters(str) {
return String(str).replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/g, ' ');
};
var secureFilters = {};
secureFilters.css = function(val) {
var str = String(val);
str = convertControlCharacters(str);
return str.replace(/[^a-zA-Z0-9\uD800-\uDFFF]/g, function(match) {
var code = match.charCodeAt(0);
if (code === 0) {
return '\\fffd '; // REPLACEMENT CHARACTER U+FFFD
} else {
var hex = code.toString(16).toLowerCase();
return '\\'+hex+' ';
}
});
};
secureFilters.html = function(val) {
var str = String(val);
str = convertControlCharacters(str);
return str.replace(/[^\t\n\v\f\r ,\.0-9A-Z_a-z\-\u00A0-\uFFFF]/g, function(match) {
var code = match.charCodeAt(0);
switch(code) {
// folks expect these "nice" entities:
case 0x22:
return '"';
case 0x26:
return '&';
case 0x3C:
return '<';
case 0x3E:
return '>';
default:
// optimize for size:
if (code < 100) {
var dec = code.toString(10);
return ''+dec+';';
} else {
// XXX: this doesn't produce strictly valid entities for code-points
// requiring a UTF-16 surrogate pair. However, browsers are generally
// tolerant of this. Surrogate pairs are currently in the whitelist
// defined via HTML_NOT_WHITELISTED.
var hex = code.toString(16).toUpperCase();
return ''+hex+';';
}
}
});
};
secureFilters.style = function(val) {
return secureFilters.html(secureFilters.css(val));
};
secureFilters.uri = function(val) {
// encodeURIComponent() is well-standardized across browsers and it handles
// UTF-8 natively. It will not encode "~!*()'", so need to replace those here.
// encodeURIComponent also won't encode ".-_", but those are known-safe.
//
// IE does not always encode '"' to '%27':
// http://blog.imperva.com/2012/01/ie-bug-exposes-its-users-to-xss-attacks-.html
var QUOT = /\x22/g; // "
var APOS = /\x27/g; // '
var AST = /\*/g;
var TILDE = /~/g;
var BANG = /!/g;
var LPAREN = /\(/g;
var RPAREN = /\)/g;
var encode = encodeURI(String(val));
// modification by matomo: we use encodeURI instead of encodeURIComponent as we are currently not detecting
// whether we are escaping a variable as part of a uri or the full uri
return encode
.replace(BANG, '%21')
.replace(QUOT, '%27')
.replace(APOS, '%27')
.replace(LPAREN, '%28')
.replace(RPAREN, '%29')
.replace(AST, '%2A')
.replace(TILDE, '%7E');
};
/*! end secure filters */
return function (parameters, TagManager) {
function moveChildrenToArray(element)
{
var children = [];
var j = 0;
while (j in element.childNodes && element.childNodes.length) {
children.push(element.removeChild(element.childNodes[j]));
}
return children;
}
function cloneScript(element) {
var newScript = parameters.document.createElement('script');
var src = TagManager.dom.getElementAttribute(element, 'src');
if (src) {
newScript.setAttribute('src', src);
} else {
newScript.text = element.text || element.textContent || element.innerHTML || '';
}
if (element.hasAttribute('id')) {
newScript.setAttribute('id', element.getAttribute('id'));
}
if (element.hasAttribute('charset')) {
newScript.setAttribute('charset', element.getAttribute('charset'));
}
if (element.hasAttribute('defer')) {
newScript.setAttribute('defer', element.getAttribute('defer'));
}
if (element.hasAttribute('async')) {
newScript.setAttribute('async',element.getAttribute('async'));
}
if (element.hasAttribute('onload')) {
newScript.setAttribute('onload', element.getAttribute('onload'));
}
if (element.hasAttribute('type')) {
newScript.setAttribute('type', element.getAttribute('type'));
}
// If this script is executing using a nonce, set the nonce on its children too.
var scriptWithNonce = TagManager.dom.bySelector('script[nonce]');
if (scriptWithNonce.length && scriptWithNonce[0]) {
scriptWithNonce = scriptWithNonce[0]; // Grab the first element.
// Try using the attribute first for compatibility, then go to the property.
var nonceAttr = TagManager.dom.getElementAttribute(scriptWithNonce, 'nonce');
nonceAttr = nonceAttr ? nonceAttr : scriptWithNonce.nonce;
newScript.setAttribute('nonce', nonceAttr);
}
return newScript;
}
function isJavaScriptElement(element)
{
if (element && element.nodeName && element.nodeName.toLowerCase() === 'script') {
// we have to re-create the element, otherwise wouldn't be executed
var type = TagManager.dom.getElementAttribute(element, 'type');
if (!type || String(type).toLowerCase() === 'text/javascript') {
return true;
}
}
return false;
}
function doChildrenContainJavaScript(element)
{
return element && element.innerHTML && element.innerHTML.toLowerCase().indexOf("