| @@ -96,4 +96,66 @@ | ||
| 96 | 96 | |
| 97 | 97 | return array_unique( array_merge( $attr, $svg_properties ) ); |
| 98 | 98 | } |
| 99 | 99 | add_filter( 'safe_style_css', 'gutenberg_add_svg_to_safe_style_css' ); |
| 100 | + | |
| 101 | +/** | |
| 102 | + * Allow gradient background-image values, including gradients combined with a | |
| 103 | + * url() image, in inline styles. | |
| 104 | + * | |
| 105 | + * Without this, {@see safecss_filter_attr()} strips gradients that use functions | |
| 106 | + * beyond rgb()/rgba(), or that are combined with a url() image. This removes each | |
| 107 | + * gradient from the test string and re-checks the remainder, so those values | |
| 108 | + * survive sanitization. | |
| 109 | + * | |
| 110 | + * @param bool $allow_css Whether the CSS is allowed. | |
| 111 | + * @param string $css_test_string The CSS declaration to test. | |
| 112 | + * @return bool Whether the CSS is allowed. | |
| 113 | + */ | |
| 114 | +function gutenberg_allow_extended_gradient_backgrounds( $allow_css, $css_test_string ) { | |
| 115 | + if ( $allow_css ) { | |
| 116 | + return $allow_css; | |
| 117 | + } | |
| 118 | + | |
| 119 | + if ( ! preg_match( '/^background-image\s*:/', $css_test_string ) ) { | |
| 120 | + return $allow_css; | |
| 121 | + } | |
| 122 | + | |
| 123 | + /* | |
| 124 | + * Remove each gradient (allowing one level of nested functions such as | |
| 125 | + * rgb(), hsl(), or calc()) and re-test. Any url() has already been removed | |
| 126 | + * and protocol-checked by safecss_filter_attr() before this filter runs. | |
| 127 | + */ | |
| 128 | + $stripped = preg_replace( '/(?:repeating-)?(?:linear|radial|conic)-gradient\((?:[^()]|\([^()]*\))*\)/', '', $css_test_string ); | |
| 129 | + | |
| 130 | + if ( ! preg_match( '%[\\\(&=}]|/\*%', $stripped ) ) { | |
| 131 | + return true; | |
| 132 | + } | |
| 133 | + | |
| 134 | + return $allow_css; | |
| 135 | +} | |
| 136 | + | |
| 137 | +add_filter( 'safecss_filter_attr_allow_css', 'gutenberg_allow_extended_gradient_backgrounds', 10, 2 ); | |
| 138 | + | |
| 139 | +/** | |
| 140 | + * Allows the `tabindex` attribute on elements that support global attributes. | |
| 141 | + * | |
| 142 | + * `tabindex` is a global HTML attribute, but KSES strips it from post content. | |
| 143 | + * The Tab Panel block saves it to keep the panel focusable. | |
| 144 | + * | |
| 145 | + * @param array[] $tags Array of allowed HTML tags and their allowed attributes. | |
| 146 | + * @return array[] Modified array of allowed HTML tags. | |
| 147 | + */ | |
| 148 | +function gutenberg_add_tabindex_to_kses_allowed_html( $tags ) { | |
| 149 | + if ( ! is_array( $tags ) ) { | |
| 150 | + return $tags; | |
| 151 | + } | |
| 152 | + | |
| 153 | + foreach ( $tags as $tag => $attributes ) { | |
| 154 | + if ( is_array( $attributes ) ) { | |
| 155 | + $tags[ $tag ]['tabindex'] = true; | |
| 156 | + } | |
| 157 | + } | |
| 158 | + | |
| 159 | + return $tags; | |
| 160 | +} | |
| 161 | +add_filter( 'wp_kses_allowed_html', 'gutenberg_add_tabindex_to_kses_allowed_html' ); | |