diff --git a/core/modules/ckeditor5/src/Plugin/Editor/CKEditor5.php b/core/modules/ckeditor5/src/Plugin/Editor/CKEditor5.php index 87d46bcc5e32b4ae039cde51f5c1616af1dcd50a..9cdd6f9b46efbce5855cd0922afa8b3a06bf4ecf 100644 --- a/core/modules/ckeditor5/src/Plugin/Editor/CKEditor5.php +++ b/core/modules/ckeditor5/src/Plugin/Editor/CKEditor5.php @@ -20,9 +20,11 @@ use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\ckeditor5\SmartDefaultSettings; +use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Validation\Plugin\Validation\Constraint\PrimitiveTypeConstraint; +use Drupal\editor\Attribute\Editor; use Drupal\editor\EditorInterface; -use Drupal\editor\Entity\Editor; +use Drupal\editor\Entity\Editor as EditorEntity; use Drupal\editor\Plugin\EditorBase; use Drupal\filter\FilterFormatInterface; use Psr\Log\LoggerInterface; @@ -33,20 +35,19 @@ /** * Defines a CKEditor 5-based text editor for Drupal. * - * @Editor( - * id = "ckeditor5", - * label = @Translation("CKEditor 5"), - * supports_content_filtering = TRUE, - * supports_inline_editing = TRUE, - * is_xss_safe = FALSE, - * supported_element_types = { - * "textarea" - * } - * ) - * * @internal * Plugin classes are internal. */ +#[Editor( + id: 'ckeditor5', + label: new TranslatableMarkup('CKEditor 5'), + supports_content_filtering: TRUE, + supports_inline_editing: TRUE, + is_xss_safe: FALSE, + supported_element_types: [ + 'textarea', + ] +)] class CKEditor5 extends EditorBase implements ContainerFactoryPluginInterface { /** @@ -532,7 +533,7 @@ public static function assessActiveTextEditorAfterBuild(array $element, FormStat */ public static function validateSwitchingToCKEditor5(array $form, FormStateInterface $form_state): void { if (!$form_state->get('ckeditor5_is_active') && $form_state->get('ckeditor5_is_selected')) { - $minimal_ckeditor5_editor = Editor::create([ + $minimal_ckeditor5_editor = EditorEntity::create([ 'format' => NULL, 'editor' => 'ckeditor5', ]); @@ -943,7 +944,7 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s /** * {@inheritdoc} */ - public function getJSSettings(Editor $editor) { + public function getJSSettings(EditorEntity $editor) { $toolbar_items = $editor->getSettings()['toolbar']['items']; $plugin_config = $this->ckeditor5PluginManager->getCKEditor5PluginConfig($editor); @@ -965,7 +966,7 @@ public function getJSSettings(Editor $editor) { /** * {@inheritdoc} */ - public function getLibraries(Editor $editor) { + public function getLibraries(EditorEntity $editor) { $plugin_libraries = $this->ckeditor5PluginManager->getEnabledLibraries($editor); if ($this->moduleHandler->moduleExists('locale')) { diff --git a/core/modules/editor/src/Attribute/Editor.php b/core/modules/editor/src/Attribute/Editor.php new file mode 100644 index 0000000000000000000000000000000000000000..d9aedf5631ab00de96bc0ab2ab92139a84d18a3a --- /dev/null +++ b/core/modules/editor/src/Attribute/Editor.php @@ -0,0 +1,53 @@ +<?php + +namespace Drupal\editor\Attribute; + +use Drupal\Component\Plugin\Attribute\Plugin; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Defines an Editor attribute object. + * + * Plugin Namespace: Plugin\Editor + * + * For a working example, see \Drupal\ckeditor5\Plugin\Editor\CKEditor5 + * + * @see \Drupal\editor\Plugin\EditorPluginInterface + * @see \Drupal\editor\Plugin\EditorBase + * @see \Drupal\editor\Plugin\EditorManager + * @see hook_editor_info_alter() + * @see plugin_api + */ +#[\Attribute(\Attribute::TARGET_CLASS)] +class Editor extends Plugin { + + /** + * Constructs an Editor object. + * + * @param string $id + * The plugin ID. + * @param \Drupal\Core\StringTranslation\TranslatableMarkup $label + * The human-readable name of the text editor, translated + * @param bool $supports_content_filtering + * Whether the editor supports "allowed content only" filtering. + * @param bool $supports_inline_editing + * Whether the editor supports the inline editing provided by the Edit + * module. + * @param bool $is_xss_safe + * Whether this text editor is not vulnerable to XSS attacks. + * @param string[] $supported_element_types + * On which form element #types this text editor is capable of working. + * @param class-string|null $deriver + * (optional) The deriver class. + */ + public function __construct( + public readonly string $id, + public readonly TranslatableMarkup $label, + public readonly bool $supports_content_filtering, + public readonly bool $supports_inline_editing, + public readonly bool $is_xss_safe, + public readonly array $supported_element_types, + public readonly ?string $deriver = NULL, + ) {} + +} diff --git a/core/modules/editor/src/Plugin/EditorManager.php b/core/modules/editor/src/Plugin/EditorManager.php index 4585da7e721a54a84b3054edf97e3e53ee5f2b49..82388b0e83abce179d5ef3ba577f838a4726a1be 100644 --- a/core/modules/editor/src/Plugin/EditorManager.php +++ b/core/modules/editor/src/Plugin/EditorManager.php @@ -5,6 +5,7 @@ use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\editor\Attribute\Editor; /** * Configurable text editor manager. @@ -28,7 +29,7 @@ class EditorManager extends DefaultPluginManager { * The module handler to invoke the alter hook with. */ public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) { - parent::__construct('Plugin/Editor', $namespaces, $module_handler, 'Drupal\editor\Plugin\EditorPluginInterface', 'Drupal\editor\Annotation\Editor'); + parent::__construct('Plugin/Editor', $namespaces, $module_handler, 'Drupal\editor\Plugin\EditorPluginInterface', Editor::class, 'Drupal\editor\Annotation\Editor'); $this->alterInfo('editor_info'); $this->setCacheBackend($cache_backend, 'editor_plugins'); } diff --git a/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/TRexEditor.php b/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/TRexEditor.php index 70af7d822df80cea568a18209a5caba033385c69..aa620ad8050f1684ff706856e8a93da2ac62fc83 100644 --- a/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/TRexEditor.php +++ b/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/TRexEditor.php @@ -3,23 +3,24 @@ namespace Drupal\editor_test\Plugin\Editor; use Drupal\Core\Form\FormStateInterface; -use Drupal\editor\Entity\Editor; +use Drupal\editor\Attribute\Editor; +use Drupal\editor\Entity\Editor as EditorEntity; use Drupal\editor\Plugin\EditorBase; +use Drupal\Core\StringTranslation\TranslatableMarkup; /** * Defines a Tyrannosaurus-Rex powered text editor for testing purposes. - * - * @Editor( - * id = "trex", - * label = @Translation("TRex Editor"), - * supports_content_filtering = TRUE, - * supports_inline_editing = TRUE, - * is_xss_safe = FALSE, - * supported_element_types = { - * "textarea", - * } - * ) */ +#[Editor( + id: 'trex', + label: new TranslatableMarkup('TRex Editor'), + supports_content_filtering: TRUE, + supports_inline_editing: TRUE, + is_xss_safe: FALSE, + supported_element_types: [ + 'textarea', + ] +)] class TRexEditor extends EditorBase { /** @@ -44,7 +45,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta /** * {@inheritdoc} */ - public function getJSSettings(Editor $editor) { + public function getJSSettings(EditorEntity $editor) { $js_settings = []; $settings = $editor->getSettings(); if ($settings['stumpy_arms']) { @@ -56,7 +57,7 @@ public function getJSSettings(Editor $editor) { /** * {@inheritdoc} */ - public function getLibraries(Editor $editor) { + public function getLibraries(EditorEntity $editor) { return [ 'editor_test/trex', ]; diff --git a/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php b/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php index fc7e4f4544ef3bcca506c364061b2b770e614d72..b924db08b66292a8a4e35aa24ddf6839746b55c6 100644 --- a/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php +++ b/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php @@ -3,24 +3,25 @@ namespace Drupal\editor_test\Plugin\Editor; use Drupal\Core\Form\FormStateInterface; -use Drupal\editor\Entity\Editor; +use Drupal\editor\Attribute\Editor; +use Drupal\editor\Entity\Editor as EditorEntity; use Drupal\editor\Plugin\EditorBase; +use Drupal\Core\StringTranslation\TranslatableMarkup; /** * Defines a Unicorn-powered text editor for Drupal (for testing purposes). - * - * @Editor( - * id = "unicorn", - * label = @Translation("Unicorn Editor"), - * supports_content_filtering = TRUE, - * supports_inline_editing = TRUE, - * is_xss_safe = FALSE, - * supported_element_types = { - * "textarea", - * "textfield", - * } - * ) */ +#[Editor( + id: 'unicorn', + label: new TranslatableMarkup('Unicorn Editor'), + supports_content_filtering: TRUE, + supports_inline_editing: TRUE, + is_xss_safe: FALSE, + supported_element_types: [ + 'textarea', + 'textfield', + ] +)] class UnicornEditor extends EditorBase { /** @@ -61,7 +62,7 @@ public function validateImageUploadSettings(array $element, FormStateInterface $ /** * {@inheritdoc} */ - public function getJSSettings(Editor $editor) { + public function getJSSettings(EditorEntity $editor) { $js_settings = []; $settings = $editor->getSettings(); if ($settings['ponies_too']) { @@ -73,7 +74,7 @@ public function getJSSettings(Editor $editor) { /** * {@inheritdoc} */ - public function getLibraries(Editor $editor) { + public function getLibraries(EditorEntity $editor) { return [ 'editor_test/unicorn', ];