Fix and escape script attributes

@param mixed $src  script source
@param array $attr additional attributes

@return string

@access protected
170774
protected function attr($src = null, array $attr = array())
    {
        if (null !== $src) {
            $attr['src'] = $src;
        }
        $attr['type'] = 'text/javascript';
        return $this->escaper->attr($attr);
    }
139395
function resolveAttr(array $attr) {
		$out = '';
		foreach ($attr as $key => $value) {
			// build dynamic tokens
			if (preg_match('/{{(.+?)}}/s', $value))
				$value = $this->template->build($value);
			if (preg_match('/{{(.+?)}}/s', $key))
				$key = $this->template->build($key);
			// inline token
			if (is_numeric($key))
				$out .= ' '.$value;
			// value-less parameter
			elseif($value==NULL)
				$out .= ' '.$key;
			// key-value parameter
			else
				$out .= ' '.$key.'="'.$value.'"';
		}
		return $out;
	}
382777
public function inline($style, array $attr = null)
    {
        $attr = $this->escaper->attr(
            $this->fixInlineAttr($attr)
        );
        return "<style {$attr}>{$style}</style>";
    }
693493
protected function add_autovalues(&$attrs)
    {
        if (empty($this->prop['autovalues'])) {
            return;
        }

        $attrvals = array();
        foreach ($attrs as $k => $v) {
            $attrvals['{'.$k.'}'] = is_array($v) ? $v[0] : $v;
        }

        foreach ((array)$this->prop['autovalues'] as $lf => $templ) {
            if (empty($attrs[$lf])) {
                if (strpos($templ, '(') !== false) {
                    // replace {attr} placeholders with (escaped!) attribute values to be safely eval'd
                    $code = preg_replace('/\{\w+\}/', '', strtr($templ, array_map('addslashes', $attrvals)));
                    $res  = false;

                    try {
                        $res = eval("return ($code);");
                    }
                    catch (ParseError $e) {
                        // ignore
                    }

                    if ($res === false) {
                        rcube::raise_error(array(
                            'code' => 505, 'file' => __FILE__, 'line' => __LINE__,
                            'message' => "Expression parse error on: ($code)"), true, false);
                        continue;
                    }

                    $attrs[$lf] = $res;
                }
                else {
                    // replace {attr} placeholders with concrete attribute values
                    $attrs[$lf] = preg_replace('/\{\w+\}/', '', strtr($templ, $attrvals));
                }
            }
        }
    }
290435
public function image($src, $attr = array())
    {
        $src = $this->Assets->getImage($src);
        $attr['src'] = $src;
        return $this->tag('img', $attr);
    }
588922
protected function _renderScript($script, $link, $attribs = array())
    {
        $attribs = AnHelperArray::toString($attribs);

        if (!$link) {
            $html  = '<script type="text/javascript" '.$attribs.'>'."\n";
            $html .= trim($script);
            $html .= '</script>'."\n";
        } else {
            $html = '<script type="text/javascript" src="'.$script.'" '.$attribs.'></script>'."\n";
        }

        return $html;
    }
59273
protected function getAttributesInput(array $attr)
    {
        $output = [];
        foreach ($attr as $key => $values) {
            if (empty($values)) {
                continue;
            }
            if (in_array($key, $this->attributesUnique)) {
                $output[] = $key;
            } elseif (!in_array($key, $this->attributesCss) && $key !== 'selected') {
                $output[] = $key . '="' . $values . '"';
            }
        }
        $implode = implode(' ', $output);

        return $implode
            ? " $implode"
            : '';
    }
549643
protected function style($css, array $attr = null)
    {
        $attr = $this->fixInternalAttr($attr);
        $attr = $this->escaper->attr($attr);
        return "<style $attr>$css</style>";
    }
52813
private function _changedAttribute($attr) 
    {
        preg_match('/(\w+)_(change|changed|was)$/', $attr, $matches);
        if (sizeof($matches) < 1) {
            return null;
        }

        $attr = $matches[1];
        $meth = $matches[2];
        $cur  = $this->get($attr);
        $old  = $this->get($attr, false);

        if ($meth == "was") {
            return $old;
        }
        if ($meth == "changed") {
            return $cur!=$old;
        }
        if ($meth == "change") {
            return array($old, $cur);
        }
        return null;
    }
843797
function attribute( $attr )
    {
        switch( $attr )
        {
            case "uri":
                return $this->uri();
                break;
            case "functions":
                return $this->Functions;
            case "views":
                return $this->Functions;
            case "name":
                return $this->Name;
            case "path":
                return $this->Path;
            case "info":
                return $this->Module;
            case 'aviable_functions':
            case 'available_functions':
                return $this->FunctionList;
            default:
            {
                eZDebug::writeError( "Attribute '$attr' does not exist", __METHOD__ );
                return null;
            }
            break;
        }
    }
316720
private function parse_attributes($attr)
    {
        $html = '';

        if (!empty($attr)) {
            $html = '';

            foreach ($attr as $key => $value) {
                $html .= \sprintf('%s="%s" ', $key, \esc_attr($value));
            }
        }

        return \trim($html);
    }
647436
protected function _buildAttribute($attr)
    {
        $string = array();

        foreach ($attr as $key => $value) {
            if (is_array($value)) {
                $value = implode(' ', $value);
            }

            $string[] = $key.'="'.$value.'"';
        }

        return implode(' ', $string);
    }
674631
public function stylesheet($src, $attributes = [])
    {
        $attributes['rel'] = 'stylesheet';
        $attributes['href'] = $src;
        $tag = new Tag('link', $attributes);
        return $tag;
    }
693531
public function removeAttr($css, $attr = null)
    {
        if ($attr) {
            $attr = (array)preg_split('#[\s,]+#', $attr, -1, PREG_SPLIT_NO_EMPTY);
        }

        /**
         * @var \DOMElement $node
         */
        $query = $this->_document->getQuery();
        foreach ($this->_nodes as $node_0) {
            foreach ($query->css($css, $node_0) as $node) {
                foreach ($node->attributes as $attribute) {
                    if (!$attr || in_array($attribute->name, $attr, true)) {
                        $node->removeAttribute($attribute->name);
                    }
                }
            }
        }

        return $this;
    }
818742
public static function attr( $attr = array() ) {
		$buffer = " ";
		foreach( $attr as $key => $value ) {
		
			switch( $key ) {
		
				case 'class':
				if ( is_array( $value ) ) { $value = implode( ' ', $value ); }
				break;
		
				case 'style':
				if ( is_array( $value ) ) {
					$style = $value; $value = "";
					foreach( $style as $k => $v ) {
						$value .= $k.':'.$v.';';
					}
				}
				break;
			}
		
			$buffer .= $key.'="'.$value.'" ';
		}
		
		return substr( $buffer, 0, -1 );
	}
972335
protected function getAttributesCSS(array $attr)
    {
        $output = [];
        foreach ($attr as $key => $values) {
            if (in_array($key, $this->attributesCss) && $values !== '') {
                $output[] = $key . '="' . $values . '"';
            }
        }
        $implode = implode(' ', $output);

        return $implode
            ? " $implode"
            : '';
    }
365073
public function removeAttribute( string $attr ): Tag
    {
        if ( isset( $this->attributes[$attr] ) ) {
            unset( $this->attributes[$attr] );
        }

        return $this;
    }