true, 'id' => true, 'style' => true, 'title' => true, 'role' => true, 'tabindex' => true, 'hidden' => true, 'lang' => true, 'dir' => true, 'data-*' => true, 'aria-label' => true, 'aria-labelledby' => true, 'aria-describedby' => true, 'aria-hidden' => true, 'aria-expanded' => true, 'aria-controls' => true, 'aria-current' => true, 'aria-selected' => true, 'aria-pressed' => true, 'aria-live' => true, 'aria-busy' => true, 'aria-valuenow' => true, 'aria-valuemin' => true, 'aria-valuemax' => true, ); /** * Markup of the admin screens, the charts included. * * @return array> */ public static function screen() { static $allowed = null; if ( null !== $allowed ) { return $allowed; } $plain = array( 'div', 'span', 'p', 'strong', 'b', 'em', 'i', 'small', 'br', 'hr', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'h2', 'h3', 'h4', 'nav', 'section', 'header', 'footer', 'figure', 'figcaption', 'mark', 'code', 'kbd', 'details', 'summary', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'caption', 'fieldset', 'legend', 'noscript', 'template', ); $allowed = array_fill_keys( $plain, self::COMMON ); $extra = array( 'a' => array( 'href', 'target', 'rel', 'download' ), 'abbr' => array(), 'time' => array( 'datetime' ), 'img' => array( 'src', 'srcset', 'sizes', 'alt', 'width', 'height', 'loading', 'decoding', 'referrerpolicy' ), 'th' => array( 'scope', 'colspan', 'rowspan' ), 'td' => array( 'colspan', 'rowspan' ), 'form' => array( 'method', 'action', 'enctype', 'target', 'novalidate', 'autocomplete' ), 'label' => array( 'for' ), 'input' => array( 'type', 'name', 'value', 'checked', 'disabled', 'readonly', 'required', 'placeholder', 'min', 'max', 'step', 'size', 'maxlength', 'minlength', 'pattern', 'autocomplete', 'list', 'accept', 'multiple', 'form', 'inputmode', 'spellcheck', 'autofocus' ), 'select' => array( 'name', 'disabled', 'required', 'multiple', 'form', 'autocomplete' ), 'option' => array( 'value', 'selected', 'disabled', 'label' ), 'optgroup' => array( 'label', 'disabled' ), 'textarea' => array( 'name', 'rows', 'cols', 'disabled', 'readonly', 'required', 'placeholder', 'maxlength', 'spellcheck', 'form' ), 'button' => array( 'type', 'name', 'value', 'disabled', 'form', 'formaction', 'formmethod', 'formnovalidate' ), 'output' => array( 'for', 'name' ), 'progress' => array( 'value', 'max' ), 'meter' => array( 'value', 'min', 'max', 'low', 'high', 'optimum' ), 'dialog' => array( 'open' ), 'details' => array( 'open', 'name' ), 'ol' => array( 'start', 'reversed' ), 'li' => array( 'value' ), 'colgroup' => array( 'span' ), 'col' => array( 'span' ), ); // The charts and the icons are drawn in SVG. $svg = array( 'svg' => array( 'viewbox', 'width', 'height', 'xmlns', 'fill', 'focusable', 'preserveaspectratio', 'overflow' ), 'g' => array( 'fill', 'stroke', 'transform', 'opacity' ), 'path' => array( 'd', 'fill', 'fill-rule', 'clip-rule', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'stroke-dasharray', 'opacity', 'transform' ), 'rect' => array( 'x', 'y', 'width', 'height', 'rx', 'ry', 'fill', 'stroke', 'stroke-width', 'opacity' ), 'circle' => array( 'cx', 'cy', 'r', 'fill', 'stroke', 'stroke-width', 'opacity' ), 'ellipse' => array( 'cx', 'cy', 'rx', 'ry', 'fill', 'stroke', 'stroke-width' ), 'line' => array( 'x1', 'x2', 'y1', 'y2', 'stroke', 'stroke-width', 'stroke-dasharray', 'stroke-linecap' ), 'polyline' => array( 'points', 'fill', 'stroke', 'stroke-width', 'stroke-linecap', 'stroke-linejoin', 'stroke-dasharray' ), 'polygon' => array( 'points', 'fill', 'stroke', 'stroke-width' ), 'text' => array( 'x', 'y', 'dx', 'dy', 'text-anchor', 'dominant-baseline', 'font-size', 'font-weight', 'fill', 'transform' ), 'tspan' => array( 'x', 'y', 'dx', 'dy', 'fill', 'font-weight' ), 'title' => array(), 'defs' => array(), 'clippath' => array(), 'use' => array( 'href', 'x', 'y', 'width', 'height' ), ); foreach ( array_merge( $extra, $svg ) as $tag => $attributes ) { $allowed[ $tag ] = array_merge( $allowed[ $tag ] ?? self::COMMON, array_fill_keys( $attributes, true ) ); } /** * Filters the markup the Dealroot screens may print, e.g. for an add-on's own elements. * * @param array $allowed Tags and their attributes, as for wp_kses(). */ $allowed = (array) apply_filters( 'dealroot_kses_screen', $allowed ); return $allowed; } /** * Markup of the emails: paragraphs, links and buttons with inline styles. * * @return array> */ public static function mail() { $common = array( 'style' => true, 'class' => true, 'align' => true, 'dir' => true, ); $extra = array( 'a' => array( 'href', 'target', 'rel' ), 'img' => array( 'src', 'alt', 'width', 'height' ), 'table' => array( 'role', 'width', 'cellpadding', 'cellspacing', 'border' ), 'td' => array( 'width', 'bgcolor', 'valign' ), ); $tags = array( 'p', 'div', 'span', 'strong', 'b', 'em', 'i', 'ul', 'ol', 'li', 'a', 'img', 'table', 'tr', 'td' ); $mail = array( 'br' => array() ); foreach ( $tags as $tag ) { $mail[ $tag ] = array_merge( $common, array_fill_keys( $extra[ $tag ] ?? array(), true ) ); } return $mail; } }