Skip to content

Commit 4a909af

Browse files
committed
refactor to make the kses filter idempotent and a single instance of
$allowed_html
1 parent b811666 commit 4a909af

File tree

3 files changed

+190
-155
lines changed

3 files changed

+190
-155
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
<?php
2+
3+
namespace FortAwesome;
4+
5+
if ( ! defined( 'ABSPATH' ) ) {
6+
exit; // Exit if accessed directly.
7+
}
8+
9+
class FontAwesome_Allowed_HTML {
10+
/**
11+
* @internal
12+
* @ignore
13+
*/
14+
protected static $instance = null;
15+
16+
protected static $allowed_html = null;
17+
18+
private function __construct() {
19+
if ( is_null( self::$allowed_html ) ) {
20+
self::$allowed_html = self::build_allowed_html();
21+
}
22+
}
23+
24+
public static function instance()
25+
{
26+
if (is_null(self::$instance)) {
27+
self::$instance = new self();
28+
}
29+
return self::$instance;
30+
}
31+
32+
public function get_allowed_html() {
33+
return self::$allowed_html;
34+
}
35+
36+
public static function build_allowed_html() {
37+
/**
38+
* This is based on an analysis of the code in `@fortawesome/fontawesome-svg-core` that is responsible
39+
* for building the SVG elements. It may need to be updated if that code changes.
40+
*/
41+
return self::add_lowercase_attributes( array(
42+
'div' => array(
43+
'class' => true,
44+
'style' => true,
45+
),
46+
'svg' => array(
47+
'xmlns' => true,
48+
'viewBox' => true,
49+
'width' => true,
50+
'height' => true,
51+
'class' => true,
52+
'color' => true,
53+
'role' => true,
54+
'aria-hidden' => true,
55+
'aria-label' => true,
56+
'aria-labelledby' => true,
57+
'data-prefix' => true,
58+
'data-icon' => true,
59+
'data-fa-i2svg' => true,
60+
'data-fa-pseudo-element' => true,
61+
'focusable' => true,
62+
'style' => true,
63+
'transform-origin' => true,
64+
),
65+
'path' => array(
66+
'fill' => true,
67+
'opacity' => true,
68+
'd' => true,
69+
'class' => true,
70+
'transform' => true,
71+
),
72+
'span' => array(
73+
'class' => true,
74+
'style' => true,
75+
'aria-label' => true,
76+
'data-fa-i2svg' => true,
77+
),
78+
'g' => array(
79+
'class' => true,
80+
'transform' => true,
81+
),
82+
'symbol' => array(
83+
'id' => true,
84+
'viewBox' => true,
85+
'class' => true,
86+
'role' => true,
87+
'aria-hidden' => true,
88+
'aria-label' => true,
89+
'aria-labelledby' => true,
90+
'data-prefix' => true,
91+
'data-icon' => true,
92+
),
93+
'rect' => array(
94+
'x' => true,
95+
'y' => true,
96+
'width' => true,
97+
'height' => true,
98+
'fill' => true,
99+
'clip-path' => true,
100+
'mask' => true,
101+
),
102+
'circle' => array(
103+
'cx' => true,
104+
'cy' => true,
105+
'r' => true,
106+
'fill' => true,
107+
),
108+
'mask' => array(
109+
'x' => true,
110+
'y' => true,
111+
'width' => true,
112+
'height' => true,
113+
'id' => true,
114+
'maskUnits' => true,
115+
'maskContentUnits' => true,
116+
),
117+
'defs' => array(),
118+
'clipPath' => array(
119+
'id' => true,
120+
),
121+
'animate' => array(
122+
'attributeType' => true,
123+
'repeatCount' => true,
124+
'dur' => true,
125+
'attributeName' => true,
126+
'values' => true,
127+
),
128+
) );
129+
}
130+
131+
/**
132+
* Add lowercase versions of all attributes to the allowed HTML.
133+
*
134+
* This is necessary because some attribute names like `viewBox` will not be
135+
* matched by the KSES filter, which seems to lowercase attributes when filtering.
136+
*
137+
* So this will add `viewbox` as an allowed attribute alongside `viewBox`,
138+
* and will do the same for all other mixed-case attributes.
139+
*
140+
* @param array $allowed_html The original allowed HTML tags and attributes.
141+
* @return array The modified allowed HTML tags and attributes with lowercase attributes added.
142+
*/
143+
public static function add_lowercase_attributes( $allowed_html ) {
144+
foreach ( $allowed_html as $tag => $attributes ) {
145+
$additional_attributes = array();
146+
147+
if ( is_array( $attributes ) ) {
148+
foreach ( $attributes as $name => $value ) {
149+
$lowercase_name = strtolower( $name );
150+
if ( $lowercase_name !== $name ) {
151+
$additional_attributes[ $lowercase_name ] = $value;
152+
}
153+
}
154+
}
155+
156+
if ( ! empty( $additional_attributes ) ) {
157+
$allowed_html[ $tag ] = array_merge( $attributes, $additional_attributes );
158+
}
159+
}
160+
161+
return $allowed_html;
162+
}
163+
}

block-editor/font-awesome-allowed-html.php

Lines changed: 0 additions & 153 deletions
This file was deleted.

block-editor/font-awesome-icon-block-init.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
}
88

99
require_once trailingslashit( FONTAWESOME_DIR_PATH ) . 'includes/class-fontawesome-svg-styles-manager.php';
10-
require_once trailingslashit( FONTAWESOME_DIR_PATH ) . 'block-editor/font-awesome-allowed-html.php';
10+
require_once trailingslashit( FONTAWESOME_DIR_PATH ) . 'block-editor/class-fontawesome-allowed-html.php';
1111

1212
/**
1313
* We need to register the block-editor script explicitly, instead of
@@ -108,7 +108,32 @@ function block_init() {
108108
add_action( 'enqueue_block_editor_assets', 'FortAwesome\enqueue_font_awesome_block_editor_assets' );
109109
}
110110

111+
allow_font_awesome_html();
112+
111113
register_block_type( __DIR__ . '/build' );
114+
}
115+
116+
function allow_font_awesome_html() {
117+
if ( ! has_filter( 'wp_kses_allowed_html', __NAMESPACE__ . '\\fontawesome_extend_kses' ) ) {
118+
add_filter( 'wp_kses_allowed_html', __NAMESPACE__ . '\\fontawesome_extend_kses', 10, 2 );
119+
}
120+
}
121+
122+
function fontawesome_extend_kses( $tags, $context ) {
123+
$allowed_html = FontAwesome_Allowed_HTML::instance()->get_allowed_html();
124+
125+
$contexts = array( 'post', 'data', 'widget_text' );
126+
127+
if (in_array($context, $contexts, true)) {
128+
foreach ( $allowed_html as $tag => $attributes ) {
129+
if (isset($tags[$tag]) && is_array($tags[$tag])) {
130+
// Merge with existing attributes
131+
$tags[$tag] = array_merge($tags[$tag], $attributes);
132+
} else {
133+
$tags[$tag] = $attributes;
134+
}
135+
}
136+
}
112137

113-
allow_font_awesome_html( allowed_html() );
138+
return $tags;
114139
}

0 commit comments

Comments
 (0)