Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
DesignTokensPanel
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 10
420
0.00% covered (danger)
0.00%
0 / 1
 create
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 buildForm
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
42
 validateForm
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 alterElement
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 onAttachToRoot
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onAttachToSlot
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onActive
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 onDelete
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isApplicable
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 filterValues
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Plugin\display_builder\Island;
6
7use Drupal\Core\Extension\ModuleHandlerInterface;
8use Drupal\Core\Form\FormStateInterface;
9use Drupal\Core\StringTranslation\TranslatableMarkup;
10use Drupal\display_builder\Attribute\Island;
11use Drupal\display_builder\InstanceInterface;
12use Drupal\display_builder\Island\IslandPluginBase;
13use Drupal\display_builder\Island\IslandType;
14use Drupal\display_builder\Island\IslandWithFormInterface;
15use Drupal\display_builder\Island\IslandWithFormTrait;
16use Drupal\display_builder\Island\RenderableAltererInterface;
17use Drupal\ui_skins\CssVariable\CssVariablePluginManagerInterface;
18use Drupal\ui_skins\UiSkinsUtility;
19use Symfony\Component\DependencyInjection\ContainerInterface;
20
21/**
22 * Skins island plugin implementation.
23 *
24 * @todo must move to UI Styles module.
25 */
26#[Island(
27  id: 'tokens',
28  label: new TranslatableMarkup('Design tokens (CSS variables)'),
29  description: new TranslatableMarkup('Override CSS variables for the active component or block.'),
30  type: IslandType::Contextual,
31  modules: ['ui_skins'],
32)]
33class DesignTokensPanel extends IslandPluginBase implements IslandWithFormInterface, RenderableAltererInterface {
34
35  use IslandWithFormTrait;
36
37  /**
38   * The UI Skins CSS variables manager.
39   */
40  protected CssVariablePluginManagerInterface $cssVariablePluginManager;
41
42  /**
43   * The module handler.
44   */
45  protected ModuleHandlerInterface $moduleHandler;
46
47  /**
48   * {@inheritdoc}
49   */
50  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
51    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
52    $instance->cssVariablePluginManager = $container->get('plugin.manager.ui_skins.css_variable');
53    $instance->moduleHandler = $container->get('module_handler');
54
55    return $instance;
56  }
57
58  /**
59   * {@inheritdoc}
60   */
61  public function buildForm(array &$form, FormStateInterface $form_state): void {
62    $data = $form_state->getBuildInfo()['args'][0];
63    $instance = $data['instance'] ?? [];
64    $grouped_plugin_definitions = $this->cssVariablePluginManager->getGroupedDefinitions();
65
66    if (empty($grouped_plugin_definitions)) {
67      return;
68    }
69
70    foreach ($grouped_plugin_definitions as $group => $definitions) {
71      $variables = [];
72
73      foreach ($definitions as $definition_id => $definition) {
74        $default = $definition->getDefaultValues();
75
76        if (!isset($default[':root'])) {
77          continue;
78        }
79        $variables[$definition_id] = [
80          '#type' => $definition->getType(),
81          '#title' => $definition->getLabel(),
82          '#default_value' => $instance[$definition_id] ?? $default[':root'] ?? '',
83        ];
84      }
85
86      if (!empty($variables)) {
87        $variables['#type'] = 'details';
88        $variables['#title'] = $group;
89        $form[$group] = $variables;
90      }
91    }
92  }
93
94  /**
95   * {@inheritdoc}
96   */
97  public function validateForm(array &$form, FormStateInterface $form_state): void {
98    $variables = $form_state->getValues();
99    $variables = $this->filterValues($variables);
100    $variables = $form_state->setValues($variables);
101    // Those two lines are necessary to prevent the form from being rebuilt.
102    // if rebuilt, the form state values will have both the computed ones
103    // and the raw ones (wrapper key and values).
104    $form_state->setRebuild(FALSE);
105    $form_state->setExecuted();
106  }
107
108  /**
109   * {@inheritdoc}
110   */
111  public function alterElement(array $element, array $data = []): array {
112    $inline_css = [];
113
114    foreach ($data as $variable => $value) {
115      $variable = UiSkinsUtility::getCssVariableName($variable);
116      $inline_css[] = "{$variable}{$value};";
117    }
118    $element['#attributes']['style'] = \implode(' ', $inline_css);
119
120    return $element;
121  }
122
123  /**
124   * {@inheritdoc}
125   */
126  public function onAttachToRoot(InstanceInterface $instance, string $node_id): array {
127    return $this->reloadWithNodeData($instance, $node_id);
128  }
129
130  /**
131   * {@inheritdoc}
132   */
133  public function onAttachToSlot(InstanceInterface $instance, string $node_id, string $parent_id): array {
134    return $this->reloadWithNodeData($instance, $node_id);
135  }
136
137  /**
138   * {@inheritdoc}
139   */
140  public function onActive(InstanceInterface $instance, array $data): array {
141    return $this->reloadWithLocalData($instance, $data);
142  }
143
144  /**
145   * {@inheritdoc}
146   */
147  public function onDelete(InstanceInterface $instance, ?string $parent_id): array {
148    return $this->reloadWithLocalData($instance, []);
149  }
150
151  /**
152   * {@inheritdoc}
153   */
154  public function isApplicable(): bool {
155    return parent::isApplicable() && $this->moduleHandler->moduleExists('ui_skins');
156  }
157
158  /**
159   * Extract values to save in configuration.
160   *
161   * @param array $variables
162   *   The variables to filter.
163   *
164   * @return array
165   *   An array of filtered variables.
166   */
167  protected function filterValues(array $variables): array {
168    $cleaned_variables = [];
169
170    foreach ($variables as $variable => $value) {
171      /** @var \Drupal\ui_skins\Definition\CssVariableDefinition $plugin_definition */
172      $plugin_definition = $this->cssVariablePluginManager->getDefinition($variable, FALSE);
173
174      if (!$plugin_definition) {
175        continue;
176      }
177
178      // Remove values that do not differ from the default values of the plugin.
179      if ($plugin_definition->isDefaultScopeValue(':root', $value)) {
180        continue;
181      }
182
183      $cleaned_variables[$variable] = $value;
184    }
185
186    return $cleaned_variables;
187  }
188
189}

Branches

Below are the source code lines that represent each code branch as identified by Xdebug. Please note a branch is not necessarily coterminous with a line, a line may contain multiple branches and therefore show up more than once. Please also be aware that some branches may be implicit rather than explicit, e.g. an if statement always has an else as part of its logical flow even if you didn't write one.

DesignTokensPanel->alterElement
111  public function alterElement(array $element, array $data = []): array {
112    $inline_css = [];
113
114    foreach ($data as $variable => $value) {
114    foreach ($data as $variable => $value) {
114    foreach ($data as $variable => $value) {
114    foreach ($data as $variable => $value) {
115      $variable = UiSkinsUtility::getCssVariableName($variable);
116      $inline_css[] = "{$variable}{$value};";
117    }
118    $element['#attributes']['style'] = \implode(' ', $inline_css);
119
120    return $element;
121  }
DesignTokensPanel->buildForm
61  public function buildForm(array &$form, FormStateInterface $form_state): void {
62    $data = $form_state->getBuildInfo()['args'][0];
63    $instance = $data['instance'] ?? [];
64    $grouped_plugin_definitions = $this->cssVariablePluginManager->getGroupedDefinitions();
65
66    if (empty($grouped_plugin_definitions)) {
67      return;
70    foreach ($grouped_plugin_definitions as $group => $definitions) {
70    foreach ($grouped_plugin_definitions as $group => $definitions) {
70    foreach ($grouped_plugin_definitions as $group => $definitions) {
71      $variables = [];
72
73      foreach ($definitions as $definition_id => $definition) {
73      foreach ($definitions as $definition_id => $definition) {
73      foreach ($definitions as $definition_id => $definition) {
74        $default = $definition->getDefaultValues();
75
76        if (!isset($default[':root'])) {
77          continue;
73      foreach ($definitions as $definition_id => $definition) {
74        $default = $definition->getDefaultValues();
75
76        if (!isset($default[':root'])) {
77          continue;
78        }
79        $variables[$definition_id] = [
80          '#type' => $definition->getType(),
73      foreach ($definitions as $definition_id => $definition) {
74        $default = $definition->getDefaultValues();
75
76        if (!isset($default[':root'])) {
77          continue;
78        }
79        $variables[$definition_id] = [
80          '#type' => $definition->getType(),
81          '#title' => $definition->getLabel(),
82          '#default_value' => $instance[$definition_id] ?? $default[':root'] ?? '',
83        ];
84      }
85
86      if (!empty($variables)) {
70    foreach ($grouped_plugin_definitions as $group => $definitions) {
71      $variables = [];
72
73      foreach ($definitions as $definition_id => $definition) {
74        $default = $definition->getDefaultValues();
75
76        if (!isset($default[':root'])) {
77          continue;
78        }
79        $variables[$definition_id] = [
80          '#type' => $definition->getType(),
81          '#title' => $definition->getLabel(),
82          '#default_value' => $instance[$definition_id] ?? $default[':root'] ?? '',
83        ];
84      }
85
86      if (!empty($variables)) {
87        $variables['#type'] = 'details';
70    foreach ($grouped_plugin_definitions as $group => $definitions) {
70    foreach ($grouped_plugin_definitions as $group => $definitions) {
71      $variables = [];
72
73      foreach ($definitions as $definition_id => $definition) {
74        $default = $definition->getDefaultValues();
75
76        if (!isset($default[':root'])) {
77          continue;
78        }
79        $variables[$definition_id] = [
80          '#type' => $definition->getType(),
81          '#title' => $definition->getLabel(),
82          '#default_value' => $instance[$definition_id] ?? $default[':root'] ?? '',
83        ];
84      }
85
86      if (!empty($variables)) {
87        $variables['#type'] = 'details';
88        $variables['#title'] = $group;
89        $form[$group] = $variables;
90      }
91    }
92  }
DesignTokensPanel->create
50  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
51    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
52    $instance->cssVariablePluginManager = $container->get('plugin.manager.ui_skins.css_variable');
53    $instance->moduleHandler = $container->get('module_handler');
54
55    return $instance;
56  }
DesignTokensPanel->filterValues
167  protected function filterValues(array $variables): array {
168    $cleaned_variables = [];
169
170    foreach ($variables as $variable => $value) {
170    foreach ($variables as $variable => $value) {
170    foreach ($variables as $variable => $value) {
171      /** @var \Drupal\ui_skins\Definition\CssVariableDefinition $plugin_definition */
172      $plugin_definition = $this->cssVariablePluginManager->getDefinition($variable, FALSE);
173
174      if (!$plugin_definition) {
175        continue;
179      if ($plugin_definition->isDefaultScopeValue(':root', $value)) {
180        continue;
170    foreach ($variables as $variable => $value) {
171      /** @var \Drupal\ui_skins\Definition\CssVariableDefinition $plugin_definition */
172      $plugin_definition = $this->cssVariablePluginManager->getDefinition($variable, FALSE);
173
174      if (!$plugin_definition) {
175        continue;
176      }
177
178      // Remove values that do not differ from the default values of the plugin.
179      if ($plugin_definition->isDefaultScopeValue(':root', $value)) {
180        continue;
181      }
182
183      $cleaned_variables[$variable] = $value;
170    foreach ($variables as $variable => $value) {
171      /** @var \Drupal\ui_skins\Definition\CssVariableDefinition $plugin_definition */
172      $plugin_definition = $this->cssVariablePluginManager->getDefinition($variable, FALSE);
173
174      if (!$plugin_definition) {
175        continue;
176      }
177
178      // Remove values that do not differ from the default values of the plugin.
179      if ($plugin_definition->isDefaultScopeValue(':root', $value)) {
180        continue;
181      }
182
183      $cleaned_variables[$variable] = $value;
184    }
185
186    return $cleaned_variables;
187  }
DesignTokensPanel->isApplicable
155    return parent::isApplicable() && $this->moduleHandler->moduleExists('ui_skins');
155    return parent::isApplicable() && $this->moduleHandler->moduleExists('ui_skins');
155    return parent::isApplicable() && $this->moduleHandler->moduleExists('ui_skins');
156  }
DesignTokensPanel->onActive
140  public function onActive(InstanceInterface $instance, array $data): array {
141    return $this->reloadWithLocalData($instance, $data);
142  }
DesignTokensPanel->onAttachToRoot
126  public function onAttachToRoot(InstanceInterface $instance, string $node_id): array {
127    return $this->reloadWithNodeData($instance, $node_id);
128  }
DesignTokensPanel->onAttachToSlot
133  public function onAttachToSlot(InstanceInterface $instance, string $node_id, string $parent_id): array {
134    return $this->reloadWithNodeData($instance, $node_id);
135  }
DesignTokensPanel->onDelete
147  public function onDelete(InstanceInterface $instance, ?string $parent_id): array {
148    return $this->reloadWithLocalData($instance, []);
149  }
DesignTokensPanel->validateForm
97  public function validateForm(array &$form, FormStateInterface $form_state): void {
98    $variables = $form_state->getValues();
99    $variables = $this->filterValues($variables);
100    $variables = $form_state->setValues($variables);
101    // Those two lines are necessary to prevent the form from being rebuilt.
102    // if rebuilt, the form state values will have both the computed ones
103    // and the raw ones (wrapper key and values).
104    $form_state->setRebuild(FALSE);
105    $form_state->setExecuted();
106  }