Issue #3247683 by Wim Leers, lauriii, bnjmnm, Reinmar: Disable CKEditor 5's automatic link decorators (in Drupal filters should be used instead)

merge-requests/2405/head
bnjmnm 2022-06-06 12:36:55 -04:00
parent 5dc0ff5cec
commit ccd4b6456f
8 changed files with 95 additions and 1 deletions

File diff suppressed because one or more lines are too long

View File

@ -352,6 +352,13 @@ export default class DrupalLinkMediaEditing extends Plugin {
editor.conversion.for('dataDowncast').add(dataDowncastMediaLink());
this._enableManualDecorators();
const linkCommand = editor.commands.get('link');
if (linkCommand.automaticDecorators.length > 0) {
throw new Error(
'The Drupal Media plugin is not compatible with automatic link decorators. To use Drupal Media, disable any plugins providing automatic link decorators.',
);
}
}
/**

View File

@ -90,6 +90,27 @@ final class CKEditor5PluginDefinition extends PluginDefinition implements Plugin
if (!isset($definition['ckeditor5']['plugins'])) {
throw new InvalidPluginDefinitionException($id, sprintf('The "%s" CKEditor 5 plugin definition must contain a "ckeditor5.plugins" key.', $id));
}
// Automatic link decorators make sense in CKEditor 5, where the generated
// HTML must be assumed to be served as-is. But it does not make sense in
// in Drupal, where we prefer not storing (hardcoding) such decisions in the
// database. Drupal instead filters it on output, using the filter system.
if (isset($definition['ckeditor5']['config']['link'])) {
// @see https://ckeditor.com/docs/ckeditor5/latest/api/module_link_link-LinkDecoratorAutomaticDefinition.html
if (isset($definition['ckeditor5']['config']['link']['decorators']) && is_array($definition['ckeditor5']['config']['link']['decorators'])) {
foreach ($definition['ckeditor5']['config']['link']['decorators'] as $decorator) {
if ($decorator['mode'] === 'automatic') {
throw new InvalidPluginDefinitionException($id, sprintf('The "%s" CKEditor 5 plugin definition specifies an automatic decorator, this is not supported. Use the Drupal filter system instead.', $id));
}
}
}
// CKEditor 5 offers one preconfigured automatic link decorator under a
// special config flag.
// @see https://ckeditor.com/docs/ckeditor5/latest/api/module_link_link-LinkConfig.html#member-addTargetToExternalLinks
if (isset($definition['ckeditor5']['config']['link']['addTargetToExternalLinks']) && $definition['ckeditor5']['config']['link']['addTargetToExternalLinks']) {
throw new InvalidPluginDefinitionException($id, sprintf('The "%s" CKEditor 5 plugin definition specifies an automatic decorator, this is not supported. Use the Drupal filter system instead.', $id));
}
}
}
/**

View File

@ -0,0 +1,17 @@
ckeditor5_automatic_link_decorator_test_llamaClass:
ckeditor5:
plugins: []
config:
link:
decorators:
pinkColor:
mode: 'automatic'
attributes:
class: 'llama'
drupal:
label: Links must have 'llama' class!
elements:
- <a class>
conditions:
plugins:
- ckeditor5_link

View File

@ -0,0 +1,6 @@
name: CKEditor 5 Automatic Link Decorator Test
type: module
description: "Provides infrastructure for testing CKEditor 5 automatic link decorators."
package: Testing
dependencies:
- ckeditor5:ckeditor5

View File

@ -0,0 +1,13 @@
ckeditor5_automatic_link_decorator_test_2_addTargetToExternalLinks:
ckeditor5:
plugins: []
config:
link:
addTargetToExternalLinks: true
drupal:
label: Open external links in a new tab
elements:
- <a target="_blank" rel="noopener noreferrer">
conditions:
plugins:
- ckeditor5_link

View File

@ -0,0 +1,6 @@
name: CKEditor 5 Automatic Link Decorator Test (External links)
type: module
description: "Provides infrastructure for testing CKEditor 5 external links automatic link decorator."
package: Testing
dependencies:
- ckeditor5:ckeditor5

View File

@ -1466,4 +1466,28 @@ PHP,
];
}
/**
* @covers \Drupal\ckeditor5\Plugin\CKEditor5PluginDefinition::validateCKEditor5Aspects()
*/
public function testAutomaticLinkDecoratorsDisallowed(): void {
$this->expectException(InvalidPluginDefinitionException::class);
$this->expectExceptionMessage('The "ckeditor5_automatic_link_decorator_test_llamaClass" CKEditor 5 plugin definition specifies an automatic decorator, this is not supported. Use the Drupal filter system instead.');
$this->enableModules(['ckeditor5_automatic_link_decorator_test']);
$this->manager->getDefinitions();
}
/**
* @covers \Drupal\ckeditor5\Plugin\CKEditor5PluginDefinition::validateCKEditor5Aspects()
*/
public function testExternalLinkAutomaticLinkDecoratorDisallowed(): void {
$this->expectException(InvalidPluginDefinitionException::class);
$this->expectExceptionMessage('The "ckeditor5_automatic_link_decorator_test_2_addTargetToExternalLinks" CKEditor 5 plugin definition specifies an automatic decorator, this is not supported. Use the Drupal filter system instead.');
$this->enableModules(['ckeditor5_automatic_link_decorator_test_2']);
$this->manager->getDefinitions();
}
}