1 ckeditor5.module | _ckeditor5_get_generic_html_settings($format) |
Builds the ACF part of the CKEditor JS settings.
This ensures that CKEditor obeys the HTML restrictions defined by Backdrop's filter system, by enabling CKEditor's Advanced Content Filter (ACF) functionality: http://ckeditor5.com/blog/CKEditor-4.1-RC-Released.
Parameters
object $format: The text format object.
Return value
array: An array with two values:
- Configuration array of allowed content rules used by the editor's General HTML Support "allow" setting.
- Configuration array of disallowed content rules used by the editor's General HTML Support "disallow" setting.
File
- core/
modules/ ckeditor5/ ckeditor5.module, line 1141 - Provides integration with the CKEditor WYSIWYG editor.
Code
function _ckeditor5_get_generic_html_settings($format) {
$html_restrictions = filter_format_allowed_html($format);
// When all HTML is allowed, we return empty arrays. This case gets handled in
// js/ckeditor5.js.
if ($html_restrictions === TRUE) {
return array(array(), array());
}
// Converts Backdrop-stored attribute values to CKEditor attribute lists.
$get_attribute_values = function($attribute_values, $allowed_values) {
$values = array_keys(array_filter($attribute_values, function($value) use ($allowed_values) {
if ($allowed_values) {
return $value !== FALSE;
}
else {
return $value === FALSE;
}
}));
if (count($values)) {
return $values;
}
else {
return NULL;
}
};
$allowed = array();
$disallowed = array();
if (isset($html_restrictions['forbidden'])) {
foreach ($html_restrictions['forbidden'] as $tag) {
$disallowed[$tag] = array(
'name' => $tag,
);
}
}
foreach ($html_restrictions['allowed'] as $tag => $attributes) {
// Tell CKEditor the tag is allowed, but no attributes.
if ($attributes === FALSE) {
$allowed[$tag] = array(
'name' => $tag,
'attributes' => FALSE,
'styles' => FALSE,
'classes' => FALSE,
);
}
// Tell CKEditor the tag is allowed, as well as any attribute on it. The
// "style" and "class" attributes are handled separately by CKEditor:
// they are disallowed even if you specify it in the list of allowed
// attributes, unless you state specific values for them that are
// allowed. Or, in this case: any value for them is allowed.
elseif ($attributes === TRUE) {
$allowed[$tag] = array(
'name' => $tag,
'attributes' => TRUE,
'styles' => TRUE,
'classes' => TRUE,
);
// We've just marked that any value for the "style" and "class"
// attributes is allowed. However, that may not be the case: the "*"
// tag may still apply restrictions.
// Since CKEditor's ACF follows the following principle:
// Once validated, an element or its property cannot be invalidated
// by another rule.
// That means that the most permissive setting wins. Which means that
// it will still be allowed by CKEditor to e.g. define any style, no
// matter what the "*" tag's restrictions may be. If there's a setting
// for either the "style" or "class" attribute, it cannot possibly be
// more permissive than what was set above. Hence: inherit from the
// "*" tag where possible.
if (isset($html_restrictions['allowed']['*'])) {
$wildcard = $html_restrictions['allowed']['*'];
if (isset($wildcard['style'])) {
if (!is_array($wildcard['style'])) {
$allowed[$tag]['styles'] = $wildcard['style'];
}
else {
$allowed_styles = $get_attribute_values($wildcard['style'], TRUE);
if (isset($allowed_styles)) {
$allowed[$tag]['styles'] = $allowed_styles;
}
else {
unset($allowed[$tag]['styles']);
}
}
}
if (isset($wildcard['class'])) {
if (!is_array($wildcard['class'])) {
$allowed[$tag]['classes'] = $wildcard['class'];
}
else {
$allowed_classes = $get_attribute_values($wildcard['class'], TRUE);
if (isset($allowed_classes)) {
$allowed[$tag]['classes'] = $allowed_classes;
}
else {
unset($allowed[$tag]['classes']);
}
}
}
}
}
// Tell CKEditor the tag is allowed, along with some tags.
elseif (is_array($attributes)) {
// Configure allowed attributes, allowed "style" attribute values and
// allowed "class" attribute values.
// CKEditor only allows specific values for the "class" and "style"
// attributes; so ignore restrictions on other attributes, which
// Drupal filters may provide.
// NOTE: A Drupal contrib module can subclass this class, override the
// getConfig() method, and override the JavaScript at
// Drupal.editors.ckeditor5 to somehow make validation of values for
// attributes other than "class" and "style" work.
$allowed_attributes = array_filter($attributes, function($value) {
return $value !== FALSE;
});
if (count($allowed_attributes)) {
$allowed[$tag]['name'] = $tag;
if (isset($allowed[$tag]['attributes'])) {
$allowed[$tag]['attributes'] = $allowed_attributes['attributes'];
}
if (isset($allowed_attributes['style']) && is_array($allowed_attributes['style'])) {
$allowed[$tag]['styles'] = $allowed_attributes['style'];
}
if (isset($allowed_attributes['class']) && is_array($allowed_attributes['class'])) {
$allowed[$tag]['classes'] = $allowed_attributes['class'];
}
}
// Handle disallowed attributes analogously. However, to handle *dis-
// allowed* attribute values, we must look at *allowed* attributes'
// disallowed attribute values! After all, a disallowed attribute
// implies that all of its possible attribute values are disallowed,
// thus we must look at the disallowed attribute values on allowed
// attributes.
$disallowed_attributes = array_filter($attributes, function($value) {
return $value === FALSE;
});
if (count($disallowed_attributes)) {
// A simple "*" placeholder has no meaning for CKEditor5, we catch that
// in js/ckeditor5.js by using proper RegExp.
// @see https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_matcher-MatcherPattern.html
if ($tag == '*') {
continue;
}
$disallowed[$tag]['name'] = $tag;
// No need to disallow the 'class' or 'style' attributes; CKEditor
// handles them separately (if no specific class or style attribute
// values are allowed, then those attributes are disallowed).
if (isset($disallowed_attributes['class'])) {
unset($disallowed_attributes['class']);
}
if (isset($disallowed_attributes['style'])) {
unset($disallowed_attributes['style']);
}
$disallowed[$tag]['attributes'] = $disallowed_attributes;
}
if (isset($allowed_attributes['style']) && is_array($allowed_attributes['style'])) {
$disallowed_styles = $get_attribute_values($allowed_attributes['style'], FALSE);
if (isset($disallowed_styles)) {
$disallowed[$tag]['styles'] = $disallowed_styles;
}
}
if (isset($allowed_attributes['class']) && is_array($allowed_attributes['class'])) {
$disallowed_classes = $get_attribute_values($allowed_attributes['class'], FALSE);
if (isset($disallowed_classes)) {
$disallowed[$tag]['classes'] = $disallowed_classes;
}
}
}
}
// CKEditor htmlSupport arrays are not supposed to be keyed.
$allowed = array_values($allowed);
$disallowed = array_values($disallowed);
return array($allowed, $disallowed);
}