_sanitizeAttributes = function _sanitizeAttributes(currentNode) {
		let attr;
		let value;
		let lcName;
		let l;
		/* Execute a hook if present */

		_executeHook('beforeSanitizeAttributes', currentNode, null);

		const {
			attributes
		} = currentNode;
		/* Check if we have attributes; if not we might have a text node */

		if (!attributes) {
			return;
		}

		const hookEvent = {
			attrName: '',
			attrValue: '',
			keepAttr: true,
			allowedAttributes: ALLOWED_ATTR
		};
		l = attributes.length;
		/* Go backwards over all attributes; safely remove bad ones */

		while (l--) {
			attr = attributes[l];
			const {
				name,
				namespaceURI
			} = attr;
			value = name === 'value' ? attr.value : stringTrim(attr.value);
			lcName = transformCaseFunc(name);
			/* Execute a hook if present */

			hookEvent.attrName = lcName;
			hookEvent.attrValue = value;
			hookEvent.keepAttr = true;
			hookEvent.forceKeepAttr = undefined; // Allows developers to see this is a property they can set

			_executeHook('uponSanitizeAttribute', currentNode, hookEvent);

			value = hookEvent.attrValue;
			/* Did the hooks approve of the attribute? */

			if (hookEvent.forceKeepAttr) {
				continue;
			}
			/* Remove attribute */


			_removeAttribute(name, currentNode);
			/* Did the hooks approve of the attribute? */


			if (!hookEvent.keepAttr) {
				continue;
			}
			/* Work around a security issue in jQuery 3.0 */


			if (!ALLOW_SELF_CLOSE_IN_ATTR && regExpTest(/\/>/i, value)) {
				_removeAttribute(name, currentNode);

				continue;
			}
			/* Sanitize attribute content to be template-safe */


			if (SAFE_FOR_TEMPLATES) {
				value = stringReplace(value, MUSTACHE_EXPR, ' ');
				value = stringReplace(value, ERB_EXPR, ' ');
				value = stringReplace(value, TMPLIT_EXPR, ' ');
			}
			/* Is `value` valid for this attribute? */


			const lcTag = transformCaseFunc(currentNode.nodeName);

			if (!_isValidAttribute(lcTag, lcName, value)) {
				continue;
			}
			/* Full DOM Clobbering protection via namespace isolation,
			 * Prefix id and name attributes with `user-content-`
			 */


			if (SANITIZE_NAMED_PROPS && (lcName === 'id' || lcName === 'name')) {
				// Remove the attribute with this value
				_removeAttribute(name, currentNode); // Prefix the value and later re-create the attribute with the sanitized value


				value = SANITIZE_NAMED_PROPS_PREFIX + value;
			}
			/* Handle attributes that require Trusted Types */


			if (trustedTypesPolicy && typeof trustedTypes === 'object' && typeof trustedTypes.getAttributeType === 'function') {
				if (namespaceURI); else {
					switch (trustedTypes.getAttributeType(lcTag, lcName)) {
						case 'TrustedHTML':
							{
								value = trustedTypesPolicy.createHTML(value);
								break;
							}

						case 'TrustedScriptURL':
							{
								value = trustedTypesPolicy.createScriptURL(value);
								break;
							}
					}
				}
			}
			/* Handle invalid data-* attribute set by try-catching it */


			try {
				if (namespaceURI) {
					currentNode.setAttributeNS(namespaceURI, name, value);
				} else {
					/* Fallback to setAttribute() for browser-unrecognized namespaces e.g. "x-schema". */
					currentNode.setAttribute(name, value);
				}

				arrayPop(DOMPurify.removed);
			} catch (_) { }
		}
		/* Execute a hook if present */


		_executeHook('afterSanitizeAttributes', currentNode, null);
	}
_sanitizeAttributes

@protect attributes
@protect nodeName
@protect removeAttribute
@protect setAttribute

@param  {Node} currentNode to sanitize