A:2VpPIQ7A:2V@?Iv:2VPITA:2V `Ls4>:2V``L+4A:2VBMv:2VMTA:2VPs4>:2V`P+4A:2VDQv:2VQTA:2VUs3>:2VU4>:2VU+A:2V0VQ>:2VVM,?:2V`VN A:2VJVp=:2VW=aA:2VPWu=:2VW< A:2VLWp=:2VPPY=`=:2V@PYAA:2V0 YRd>:2V `YAaA:2VpYuA:2V0YQd>:2V0YA=:2V@Y<3>:2V@PY4>:2VP`Y+@:2VP`Z`X@:2V`ZK=:2VV*@Z>:2VVTA:2Vp`s3>:2Vp`9>:2V`.A:2V`Q?:2V`>>:2V`44>:2V `+4A:2V0Vav:2V ap=:2V b=A:2VbQd>:2VPbAA:2V bQd>:2V`bAA:2V bQd>:2VpbAA:2V bQd>:2VbAA:2VP bQd>:2VbA=:2V b<`;A:2V Wbv:2V bp=:2V f=Љ=:2V^f<p=:2V  h=`=:2V PhA=:2Vp @hP>:2V@` PhQ?:2VPP `hGd>:2V``hA=:2Vph< A:2Vpch=:2V jP>:2V jQ ?:2V j4>:2V`j+0=:2V j=:2V@j*0=:2V` j A:2VPhj`2A:2V0 ilp=:2V m=A:2V mR>:2V mRd>:2VPmA=:2Vm<4>:2Vm+p=:2V 0n==:2V nP>:2V p 0nQd>:2V0PnA=:2V@n<@:2V@PnG A:2V PqnA:2V  poQ>:2Vp 8oR A:2V0to=:2Vq*p=:2V Pr=aA:2V0Pru=:2Vr< A:2V@vrA:2V@ XsR A:2V0xs@:2Vyt"=:2V0q"p6>:2Vq,0MA:2Vpxpp=:2Vx==:2V xP>:2V p xQd>:2V PxA=:2V x<@:2V 0 xG>:2V0 PxtA:2V`xBЉ=:2Vx<p=:2Vz=Љ=:2Vz<pJ=:2Vp{>PANA1,1,AжAAжAAAAжAAۉADA,APAAA8>AuA,A(AAAully on the back-end. * * @since 5.0.0 * * @param array $attributes { * Associative array of tag names and tag values. * * @type string $value The attributes's value, keyed by name. * } * @param string $tag The element's tag-name. * @param ?string|array $content The tag's content. Leave null to not render content. * It will create a content-wrapping element when filled. * When array, accepts keys 'content' and Boolean 'escape'. */ public static function render( $attributes = self::DATA_DEFAULTS['attributes'], $tag = self::DATA_DEFAULTS['tag'], $content = self::DATA_DEFAULTS['content'] // php 8.0+, add trailing comma ) { $attr = ''; foreach ( $attributes as $name => $value ) { $name = trim( $name ); // Test lowercase for sanitization, but don't confuse devs in outputting it lowercase. switch ( strtolower( $name ) ) { case 'href': case 'xlink:href': case 'src': // Perform discrete URL-encoding on resources that could bypass attributes, without mangling the URL. // Ampersand is missing because that doesn't affect HTML attributes; plus, it's a struct for query parameters. $_secure_attr_value = strtr( \sanitize_url( $value ), [ '"' => '%22', "'" => '%27', '<' => '%3C', '>' => '%3E', ], ); break; default: if ( /** @link */ 0 === stripos( $name, 'on' ) ) { // phpcs:disable -- hint for when we need to get more specific. // \in_array( // $name, // [ 'onabort', 'onblur', 'oncanplay', 'oncanplaythrough', 'onchange', 'onclick', 'oncontextmenu', 'oncuechange', 'ondblclick', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'ondurationchange', 'onemptied', 'onended', 'onerror', 'onfocus', 'oninput', 'oninvalid', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onreadystatechange', 'onreset', 'onscroll', 'onseeked', 'onseeking', 'onselect', 'onshow', 'onstalled', 'onsubmit', 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting' ], // true // ) // phpcs:enable // Nope. Not this function. Skip writing on-stuff. continue 2; } // This replaces more than necessary -- may we wish to exchange it. $_secure_attr_value = \esc_attr( $value ); } $attr .= \sprintf( ' %s="%s"', /** * This will also strip "safe" characters outside of the alphabet, 0-9, and :_-. * I don't want angry parents ringing me at home for their site didn't * support proper UTF. We can afford empty tags in rare situations -- not here. * So, we'll only allow ASCII 45~95 except 46, 47, 59~64, and 91~94. * * @link */ preg_replace( '/[^a-z\d:_-]+/i', '', $name ), $_secure_attr_value, ); } // phpcs:disable WordPress.Security.EscapeOutput -- already escaped. if ( isset( $content ) ) { vprintf( '<%1$s%2$s>%3$s', [ /** @link */ preg_replace( '/[^a-z\d]+/i', '', $tag ), // phpcs:ignore WordPress.Security.EscapeOutput -- this escapes. $attr, \is_array( $content ) ? ( ( $content['escape'] ?? true ) ? \esc_html( $content['content'] ) // Yes, we're filling the content with content. : $content['content'] ) : \esc_html( $content ), ], ); } else { printf( '<%s%s />', // XHTML compatible. /** @link */ preg_replace( '/[^0-9a-zA-Z]+/', '', $tag ), $attr, ); } // phpcs:enable WordPress.Security.EscapeOutput echo "\n"; } }