Updated to Drupal 8.6.4, which is PHP 7.3 friendly. Also updated HTMLaw library....
[yaffs-website] / web / core / modules / ckeditor / src / Plugin / CKEditorPlugin / StylesCombo.php
1 <?php
2
3 namespace Drupal\ckeditor\Plugin\CKEditorPlugin;
4
5 use Drupal\ckeditor\CKEditorPluginBase;
6 use Drupal\ckeditor\CKEditorPluginConfigurableInterface;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\editor\Entity\Editor;
9
10 /**
11  * Defines the "stylescombo" plugin.
12  *
13  * @CKEditorPlugin(
14  *   id = "stylescombo",
15  *   label = @Translation("Styles dropdown")
16  * )
17  */
18 class StylesCombo extends CKEditorPluginBase implements CKEditorPluginConfigurableInterface {
19
20   /**
21    * {@inheritdoc}
22    */
23   public function isInternal() {
24     return TRUE;
25   }
26
27   /**
28    * {@inheritdoc}
29    */
30   public function getFile() {
31     // This plugin is already part of Drupal core's CKEditor build.
32     return FALSE;
33   }
34
35   /**
36    * {@inheritdoc}
37    */
38   public function getConfig(Editor $editor) {
39     $config = [];
40     $settings = $editor->getSettings();
41     if (!isset($settings['plugins']['stylescombo']['styles'])) {
42       return $config;
43     }
44     $styles = $settings['plugins']['stylescombo']['styles'];
45     $config['stylesSet'] = $this->generateStylesSetSetting($styles);
46     return $config;
47   }
48
49   /**
50    * {@inheritdoc}
51    */
52   public function getButtons() {
53     return [
54       'Styles' => [
55         'label' => $this->t('Font style'),
56         'image_alternative' => [
57           '#type' => 'inline_template',
58           '#template' => '<a href="#" role="button" aria-label="{{ styles_text }}"><span class="ckeditor-button-dropdown">{{ styles_text }}<span class="ckeditor-button-arrow"></span></span></a>',
59           '#context' => [
60             'styles_text' => $this->t('Styles'),
61           ],
62         ],
63       ],
64     ];
65   }
66
67   /**
68    * {@inheritdoc}
69    */
70   public function settingsForm(array $form, FormStateInterface $form_state, Editor $editor) {
71     // Defaults.
72     $config = ['styles' => ''];
73     $settings = $editor->getSettings();
74     if (isset($settings['plugins']['stylescombo'])) {
75       $config = $settings['plugins']['stylescombo'];
76     }
77
78     $form['styles'] = [
79       '#title' => $this->t('Styles'),
80       '#title_display' => 'invisible',
81       '#type' => 'textarea',
82       '#default_value' => $config['styles'],
83       '#description' => $this->t('A list of classes that will be provided in the "Styles" dropdown. Enter one or more classes on each line in the format: element.classA.classB|Label. Example: h1.title|Title. Advanced example: h1.fancy.title|Fancy title.<br />These styles should be available in your theme\'s CSS file.'),
84       '#attached' => [
85         'library' => ['ckeditor/drupal.ckeditor.stylescombo.admin'],
86       ],
87       '#element_validate' => [
88         [$this, 'validateStylesValue'],
89       ],
90     ];
91
92     return $form;
93   }
94
95   /**
96    * #element_validate handler for the "styles" element in settingsForm().
97    */
98   public function validateStylesValue(array $element, FormStateInterface $form_state) {
99     $styles_setting = $this->generateStylesSetSetting($element['#value']);
100     if ($styles_setting === FALSE) {
101       $form_state->setError($element, $this->t('The provided list of styles is syntactically incorrect.'));
102     }
103     else {
104       $style_names = array_map(function ($style) {
105         return $style['name'];
106       }, $styles_setting);
107       if (count($style_names) !== count(array_unique($style_names))) {
108         $form_state->setError($element, $this->t('Each style must have a unique label.'));
109       }
110     }
111   }
112
113   /**
114    * Builds the "stylesSet" configuration part of the CKEditor JS settings.
115    *
116    * @see getConfig()
117    *
118    * @param string $styles
119    *   The "styles" setting.
120    * @return array|false
121    *   An array containing the "stylesSet" configuration, or FALSE when the
122    *   syntax is invalid.
123    */
124   protected function generateStylesSetSetting($styles) {
125     $styles_set = [];
126
127     // Early-return when empty.
128     $styles = trim($styles);
129     if (empty($styles)) {
130       return $styles_set;
131     }
132
133     $styles = str_replace(["\r\n", "\r"], "\n", $styles);
134     foreach (explode("\n", $styles) as $style) {
135       $style = trim($style);
136
137       // Ignore empty lines in between non-empty lines.
138       if (empty($style)) {
139         continue;
140       }
141
142       // Validate syntax: element[.class...]|label pattern expected.
143       if (!preg_match('@^ *[a-zA-Z0-9]+ *(\\.[a-zA-Z0-9_-]+ *)*\\| *.+ *$@', $style)) {
144         return FALSE;
145       }
146
147       // Parse.
148       list($selector, $label) = explode('|', $style);
149       $classes = explode('.', $selector);
150       $element = array_shift($classes);
151
152       // Build the data structure CKEditor's stylescombo plugin expects.
153       // @see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Styles
154       $configured_style = [
155         'name' => trim($label),
156         'element' => trim($element),
157       ];
158       if (!empty($classes)) {
159         $configured_style['attributes'] = [
160           'class' => implode(' ', array_map('trim', $classes)),
161         ];
162       }
163       $styles_set[] = $configured_style;
164     }
165     return $styles_set;
166   }
167
168 }