Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • issue/ckeditor5_plugin_pack-3446546
  • project/ckeditor5_plugin_pack
  • issue/ckeditor5_plugin_pack-3443601
  • issue/ckeditor5_plugin_pack-3447365
  • issue/ckeditor5_plugin_pack-3459095
  • issue/ckeditor5_plugin_pack-3449245
  • issue/ckeditor5_plugin_pack-3453170
  • issue/ckeditor5_plugin_pack-3459285
  • issue/ckeditor5_plugin_pack-3461841
  • issue/ckeditor5_plugin_pack-3456402
  • issue/ckeditor5_plugin_pack-3457362
  • issue/ckeditor5_plugin_pack-3469035
  • issue/ckeditor5_plugin_pack-3468926
  • issue/ckeditor5_plugin_pack-3476936
  • issue/ckeditor5_plugin_pack-3478108
  • issue/ckeditor5_plugin_pack-3469207
  • issue/ckeditor5_plugin_pack-3472777
  • issue/ckeditor5_plugin_pack-3484613
  • issue/ckeditor5_plugin_pack-3477626
  • issue/ckeditor5_plugin_pack-3491958
  • issue/ckeditor5_plugin_pack-3472711
  • issue/ckeditor5_plugin_pack-3494274
22 results
Show changes
Commits on Source (12)
Showing
with 389 additions and 5 deletions
......@@ -5,6 +5,7 @@ ckeditor5_plugin_pack_find_and_replace__find_and_replace:
drupal:
label: Find and replace
elements: false
class: Drupal\ckeditor5_plugin_pack_find_and_replace\Plugin\CKEditor5Plugin\FindAndReplace
library: ckeditor5_plugin_pack_find_and_replace/find-and-replace
admin_library: ckeditor5_plugin_pack_find_and_replace/admin.find_and_replace
toolbar_items:
......
ckeditor5.plugin.ckeditor5_plugin_pack_find_and_replace__find_and_replace:
type: mapping
label: 'Find And Replace'
mapping:
ui_type:
type: string
label: 'UI type'
<?php
/*
* Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see https://ckeditor.com/legal/ckeditor-oss-license
*/
declare(strict_types=1);
namespace Drupal\ckeditor5_plugin_pack_find_and_replace\Plugin\CKEditor5Plugin;
use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface;
use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableTrait;
use Drupal\ckeditor5\Plugin\CKEditor5PluginDefault;
use Drupal\Core\Form\FormStateInterface;
use Drupal\editor\EditorInterface;
/**
* CKEditor 5 Find and replace Plugin.
*
* @internal
* Plugin classes are internal.
*/
class FindAndReplace extends CKEditor5PluginDefault implements CKEditor5PluginConfigurableInterface {
use CKEditor5PluginConfigurableTrait;
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'ui_type' => 'dialog',
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form['ui_type'] = [
'#type' => 'select',
'#title' => $this->t('UI type'),
'#options' => [
'dialog' => $this->t('Dialog'),
'dropdown' => $this->t('Dropdown'),
],
'#default_value' => $this->configuration['ui_type'] ?? 'dialog',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->cleanValues()->getValues();
$this->configuration['ui_type'] = $values['ui_type'];
}
/**
* {@inheritdoc}
*/
public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array {
$uiType = $this->configuration['ui_type'] ?? 'dialog';
$static_plugin_config['findAndReplace']['uiType'] = $uiType;
return $static_plugin_config;
}
}
......@@ -22,3 +22,6 @@ ckeditor5.plugin.ckeditor5_plugin_pack_font__font_color:
use_default_colors:
type: boolean
label: Use default colors
use_colorpicker:
type: boolean
label: Use colorpickers
......@@ -32,6 +32,7 @@ class FontColor extends CKEditor5PluginDefault implements CKEditor5PluginConfigu
return [
'colors' => [],
'use_default_colors' => TRUE,
'use_colorpicker' => TRUE,
];
}
......@@ -46,6 +47,14 @@ class FontColor extends CKEditor5PluginDefault implements CKEditor5PluginConfigu
'#description' => $this->t('Default CKEditor5 colors will be available with custom added colors.'),
'#default_value' => $this->configuration['use_default_colors'] ?? TRUE,
];
$form['use_colorpicker'] = [
'#type' => 'checkbox',
'#title' => $this->t('Use CKEditor5 color picker'),
'#description' => $this->t('Allow editors to define their own colors'),
'#default_value' => $this->configuration['use_colorpicker'] ?? TRUE,
];
$form['custom_colors_wrapper'] = [
'#type' => 'fieldset',
'#id' => 'custom-colors-wrapper',
......@@ -80,7 +89,7 @@ class FontColor extends CKEditor5PluginDefault implements CKEditor5PluginConfigu
'font' => $this->t('Font Color'),
'background' => $this->t('Background Color'),
],
'#default_value' => $option['type'],
'#default_value' => $option['type'] ?? [],
'#ajax' => FALSE,
];
$form['custom_colors_wrapper'][$colorId]['delete'] = [
......@@ -176,6 +185,11 @@ class FontColor extends CKEditor5PluginDefault implements CKEditor5PluginConfigu
}
}
if (empty($customColors) && empty($values['use_default_colors'])) {
$element = $form['use_colorpicker'];
$form_state->setError($element, $this->t('Use CKEditor5 default colors or add custom colors to disable the color picker'));
}
}
/**
......@@ -185,6 +199,7 @@ class FontColor extends CKEditor5PluginDefault implements CKEditor5PluginConfigu
$values = $form_state->cleanValues()->getValues();
$this->configuration['colors'] = $values['custom_colors_wrapper'] ?? [];
$this->configuration['use_default_colors'] = (bool) $values['use_default_colors'];
$this->configuration['use_colorpicker'] = (bool) $values['use_colorpicker'];
}
/**
......@@ -192,6 +207,7 @@ class FontColor extends CKEditor5PluginDefault implements CKEditor5PluginConfigu
*/
public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array {
$colors = $this->configuration['colors'];
$use_colorpicker = $this->configuration['use_colorpicker'];
$fontColors = array_filter($colors, fn($color) => !empty($color['type']['font']));
$backgroundColors = array_filter($colors, fn($color) => !empty($color['type']['background']));
......@@ -210,7 +226,13 @@ class FontColor extends CKEditor5PluginDefault implements CKEditor5PluginConfigu
$static_plugin_config['fontBackgroundColor']['colors'] = array_values($backgroundColors);
}
$static_plugin_config['fontColor']['colorPicker']['format'] = 'hex';
if ($use_colorpicker) {
$static_plugin_config['fontColor']['colorPicker']['format'] = 'hex';
}
else {
$static_plugin_config['fontColor']['colorPicker'] = FALSE;
$static_plugin_config['fontBackgroundColor']['colorPicker'] = FALSE;
}
return $static_plugin_config;
}
......
......@@ -79,7 +79,8 @@ class FontSize extends CKEditor5PluginDefault implements CKEditor5PluginConfigur
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['options'] = $form_state->getValue('options');
[$options] = $this->getParsedOptions($form_state->getValue('options'));
$this->configuration['options'] = implode("\n", $options);
}
/**
......@@ -104,7 +105,7 @@ class FontSize extends CKEditor5PluginDefault implements CKEditor5PluginConfigur
if (!is_numeric($trimmedOption) && $trimmedOption !== 'default') {
$wrongValues[] = $trimmedOption;
}
$returnOptions[] = $trimmedOption;
$returnOptions[] = is_numeric($trimmedOption) ? abs($trimmedOption + 0) : $trimmedOption;
}
}
return [$returnOptions, $wrongValues];
......
# CKEditor 5 Plugin Pack - Link Attributes
This module is a part of CKEditor 5 Plugin Pack. It integrates the Link Attributes (decorators) with CKEditor 5 for Drupal 9 and 10.
By default, all links created in the editor have the href="..." attribute in the editor data. If you want your links to have additional link attributes, link decorators provide an easy way to configure and manage them.
More info and demo available at https://ckeditor.com/docs/ckeditor5/latest/features/link.html#custom-link-attributes-decorators
## Installation and configuration
- Install CKEditor 5 Plugin Pack `composer require "drupal/ckeditor5_plugin_pack"`
- Enable `CKEditor 5` and `CKEditor 5 Link Attributes`
- Create or edit existing rich text format that uses CKEditor 5 as editor: `/admin/config/content/formats`
- In the settings of the CKEditor 5 plugin, you can configure the link attributes that you want to use in the editor.
No external dependencies required, the plugin is integrated directly via DLL Builds.
ckeditor5_plugin_pack_link_attributes__link_attributes:
ckeditor5:
plugins: []
drupal:
label: Link Attributes
class: Drupal\ckeditor5_plugin_pack_link_attributes\Plugin\CKEditor5Plugin\LinkAttributes
elements:
- <a href target rel title id class download hreflang type data-*>
name: CKEditor 5 Link Attributes
type: module
description: "Provides the CKEditor 5 Link Attributes."
package: CKEditor 5 Plugin Pack
core_version_requirement: ^9.4 || ^10 || ^11
dependencies:
- ckeditor5_plugin_pack:ckeditor5_plugin_pack
ckeditor5.plugin.ckeditor5_plugin_pack_link_attributes__link_attributes:
type: mapping
label: 'Link attributes'
mapping:
attributes:
type: sequence
label: 'Attributes'
<?php
/*
* Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved.
* For licensing, see https://ckeditor.com/legal/ckeditor-oss-license
*/
declare(strict_types=1);
namespace Drupal\ckeditor5_plugin_pack_link_attributes\Plugin\CKEditor5Plugin;
use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface;
use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableTrait;
use Drupal\ckeditor5\Plugin\CKEditor5PluginDefault;
use Drupal\Core\Form\FormStateInterface;
use Drupal\editor\EditorInterface;
/**
* CKEditor 5 Link Attributes.
*
* @internal
* Plugin classes are internal.
*/
class LinkAttributes extends CKEditor5PluginDefault implements CKEditor5PluginConfigurableInterface {
use CKEditor5PluginConfigurableTrait;
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [
'attributes' => [],
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
$form['attributes_wrapper'] = [
'#type' => 'fieldset',
'#id' => 'attributes-wrapper',
];
$attributes = $this->configuration['attributes'];
if ($form_state->isRebuilding()) {
$userInput = $form_state->getUserInput();
$attributes = $userInput['editor']['settings']['plugins']['ckeditor5_plugin_pack_link_attributes__link_attributes']['attributes_wrapper'] ?? [];
}
foreach ($attributes as $attributeId => $attribute) {
$form['attributes_wrapper'][$attributeId] = [
'#type' => 'fieldset',
'#id' => 'attributes-container',
];
$form['attributes_wrapper'][$attributeId]['label'] = [
'#type' => 'textfield',
'#title' => $this->t('Group label'),
'#description' => $this->t('Label that will be displayed next to the group switch in the dropdown'),
'#maxlength' => 255,
'#default_value' => $attribute['label'] ?? '',
];
$form['attributes_wrapper'][$attributeId]['attributes'] = [
'#type' => 'textarea',
'#title' => $this->t('Attributes'),
'#description' => $this->t('Enter one or more attributes on each line in the format: attribute|value. Example: target|_blank <br /><br />
When filter "Limit allowed HTML tags and correct faulty HTML" is enabled, make sure the attribute you want to add is present in the allowed list.<br />
Allowed attributes list: href, target, rel, title, id, class, download, hreflang, type, data-*
'),
'#default_value' => $attribute['attributes'] ?? '',
'#ajax' => FALSE,
];
$form['attributes_wrapper'][$attributeId]['delete'] = [
'#type' => 'submit',
'#value' => $this->t('Remove'),
'#name' => 'attribute-' . $attributeId . '-delete',
'#button_type' => 'danger',
'#submit' => [[$this, 'removeAttribute']],
'#ajax' => [
'callback' => [$this, 'refreshAttributesCallback'],
'wrapper' => 'attributes-wrapper',
],
'#attributes' => [
'data-attribute-id' => $attributeId,
],
];
}
$form['attributes_wrapper']['add_group'] = [
'#type' => 'submit',
'#value' => $this->t('Add group'),
'#submit' => [[$this, 'addAttribute']],
'#ajax' => [
'callback' => [$this, 'refreshAttributesCallback'],
'wrapper' => 'attributes-wrapper',
],
];
return $form;
}
/**
* Add new attribute handler.
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*/
public function addAttribute(array &$form, FormStateInterface $form_state): void {
$userInput = $form_state->getUserInput();
$userInput['editor']['settings']['plugins']['ckeditor5_plugin_pack_link_attributes__link_attributes']['attributes_wrapper'][] = [];
$form_state->setUserInput($userInput);
$form_state->setRebuild();
}
/**
* Remove handler.
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*/
public function removeAttribute(array &$form, FormStateInterface $form_state): void {
$trigger = $form_state->getTriggeringElement();
$id = $trigger['#attributes']['data-attribute-id'];
$userInput = $form_state->getUserInput();
$plugin = $userInput['editor']['settings']['plugins']['ckeditor5_plugin_pack_link_attributes__link_attributes']['attributes_wrapper'];
if (isset($plugin[$id])) {
unset($plugin[$id]);
}
$userInput['editor']['settings']['plugins']['ckeditor5_plugin_pack_link_attributes__link_attributes']['attributes_wrapper'] = $plugin;
$form_state->setUserInput($userInput);
$form_state->setRebuild();
}
/**
* Refresh attributes wrapper callback.
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return array
*/
public function refreshAttributesCallback(array &$form, FormStateInterface $form_state): array {
$settings_element = $form['editor']['settings']['subform']['plugins']['ckeditor5_plugin_pack_link_attributes__link_attributes'] ?? $form;
return $settings_element['attributes_wrapper'] ?? $settings_element;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state): void {
$trigger = $form_state->getTriggeringElement();
if (str_contains($trigger['#id'], 'plugins-ckeditor5-plugin-pack-link-attributes-link-attributes')) {
return;
}
$values = $form_state->getValues();
$customMarkers = $values['attributes_wrapper'];
// Remove add button from array.
unset($customMarkers['add_group']);
foreach ($customMarkers as $key => $marker) {
$element = $form['attributes_wrapper'][$key];
if (empty($marker['label'])) {
$form_state->setError($element['label'], $this->t('Link attributes: Group label is required.'));
}
}
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
$values = $form_state->cleanValues()->getValues();
$this->configuration['attributes'] = $values['attributes_wrapper'] ?? [];
}
/**
* {@inheritdoc}
*/
public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array {
$attributes = $this->configuration['attributes'];
foreach ($attributes as $attribute) {
$decoratorTitle = $this->convertToCamelCase($attribute['label']);
$attributeValues = $this->getParsedAttributes($attribute['attributes']);
$static_plugin_config['link']['decorators'][$decoratorTitle] = [
'mode' => 'manual',
'label' => $attribute['label'],
'attributes' => $attributeValues,
];
}
return $static_plugin_config;
}
/**
* @param string $input
*
* @return string
*/
private function convertToCamelCase(string $text): string {
$text = strtolower($text);
$words = explode(' ', $text);
$words = array_map(function ($word, $index) {
return $index === 0 ? $word : ucfirst($word);
}, $words, array_keys($words));
return implode('', $words);
}
/**
* @param string $attributes
*
* @return array
*/
private function getParsedAttributes(string $attributes): array {
$values = explode("\n", $attributes);
$attributes = [];
foreach ($values as $value) {
$trimmedValue = trim($value);
if (empty($trimmedValue)) {
continue;
}
$attributeValue = explode('|', $trimmedValue);
if (count($attributeValue) !== 2) {
continue;
}
else {
$attributes[$attributeValue[0]] = $attributeValue[1];
}
}
return $attributes;
}
}
......@@ -7,6 +7,7 @@ ckeditor5_plugin_pack_page_break__page_break:
elements:
- <div>
- <div class>
- <span>
library: ckeditor5_plugin_pack_page_break/page-break
admin_library: ckeditor5_plugin_pack_page_break/admin.page_break
toolbar_items:
......
......@@ -10,8 +10,10 @@
padding: var(--ck-spacing-small) var(--ck-spacing-standard);
border: 1px solid var(--ck-color-toolbar-border);
border-top-width: 0;
border-radius: 0 0 var(--ck-border-radius);
border-radius: 0 0 var(--ck-border-radius) var(--ck-border-radius);
font-size: var(--font-size-s);
margin-top: -5px;
padding-top: 10px;
}
.ck.ck-word-count .ck-word-count__words {
......