Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
HistoryButtons
0.00% covered (danger)
0.00%
0 / 66
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 5
380
0.00% covered (danger)
0.00%
0 / 1
 build
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 hasButtons
0.00% covered (danger)
0.00%
0 / 17
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
 buildUndoButton
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 buildRedoButton
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
 buildClearButton
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder\Plugin\display_builder\Island;
6
7use Drupal\Core\StringTranslation\TranslatableMarkup;
8use Drupal\display_builder\Attribute\Island;
9use Drupal\display_builder\InstanceInterface;
10use Drupal\display_builder\Island\IslandPluginToolbarButtonConfigurationBase;
11use Drupal\display_builder\Island\IslandReloadEventsTrait;
12use Drupal\display_builder\Island\IslandType;
13
14/**
15 * History buttons island plugin implementation.
16 */
17#[Island(
18  id: 'history',
19  enabled_by_default: TRUE,
20  label: new TranslatableMarkup('History'),
21  description: new TranslatableMarkup('Undo and redo changes.'),
22  type: IslandType::Button,
23  default_region: 'end',
24)]
25class HistoryButtons extends IslandPluginToolbarButtonConfigurationBase {
26
27  use IslandReloadEventsTrait;
28
29  /**
30   * {@inheritdoc}
31   */
32  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
33    $buttons = [
34      $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder) : [],
35      $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder) : [],
36    ];
37    $clear_button = $this->isButtonEnabled('clear') ? $this->buildClearButton($builder) : [];
38
39    if (empty(\array_filter($buttons))) {
40      return [];
41    }
42
43    $build = [
44      '#type' => 'component',
45      '#component' => 'display_builder:button_group',
46      '#slots' => [
47        'buttons' => $buttons,
48      ],
49    ];
50
51    return [$build, $clear_button];
52  }
53
54  /**
55   * {@inheritdoc}
56   */
57  protected function hasButtons(): array {
58    return [
59      'undo' => [
60        'title' => $this->t('Undo'),
61        'description' => $this->t('Undo action, icon is always visible, label is number of undo.'),
62        'default' => 'icon_label',
63      ],
64      'redo' => [
65        'title' => $this->t('Redo'),
66        'description' => $this->t('Redo action, icon is always visible, label is number of redo.'),
67        'default' => 'icon_label',
68      ],
69      'clear' => [
70        'title' => $this->t('Clear'),
71        'description' => $this->t('A button to clear the logs history (past and future).'),
72        'default' => 'hidden',
73      ],
74    ];
75  }
76
77  /**
78   * Builds the undo button.
79   *
80   * @param \Drupal\display_builder\InstanceInterface $builder
81   *   The builder instance.
82   *
83   * @return array
84   *   The undo button render array.
85   */
86  private function buildUndoButton(InstanceInterface $builder): array {
87    $past = $builder->getPast();
88    $undo = $this->buildButton(
89      ($this->showLabel('undo') && $past) ? (string) \count($past) : '',
90      'undo',
91      'arrow-counterclockwise',
92      $this->t('Undo (shortcut: Ctrl/Cmd+Z)'),
93      ['mod+z u' => $this->t('Undo last change')]
94    );
95
96    if (empty($past)) {
97      $undo['#attributes']['disabled'] = 'disabled';
98    }
99
100    return $this->htmxEvents->onUndo($undo, (string) $builder->id());
101  }
102
103  /**
104   * Builds the redo button.
105   *
106   * @param \Drupal\display_builder\InstanceInterface $builder
107   *   The builder instance.
108   *
109   * @return array
110   *   The redo button render array.
111   */
112  private function buildRedoButton(InstanceInterface $builder): array {
113    $future = $builder->getFuture();
114    $redo = $this->buildButton(
115      ($this->showLabel('redo') && $future) ? (string) \count($future) : '',
116      'redo',
117      'arrow-clockwise',
118      $this->t('Redo (shortcut: Ctrl/Cmd+Shift+Z)'),
119      ['mod+shift+z r' => $this->t('Redo last undone change')]
120    );
121
122    if (empty($future)) {
123      $redo['#attributes']['disabled'] = 'disabled';
124    }
125
126    return $this->htmxEvents->onRedo($redo, (string) $builder->id());
127  }
128
129  /**
130   * Builds the clear button.
131   *
132   * @param \Drupal\display_builder\InstanceInterface $builder
133   *   The builder instance.
134   *
135   * @return array
136   *   The clear button render array.
137   */
138  private function buildClearButton(InstanceInterface $builder): array {
139    $clear = $this->buildButton(
140      $this->showLabel('clear') ? $this->t('Clear') : '',
141      'clear',
142      $this->showIcon('clear') ? 'clock-history' : '',
143      $this->t('Clear history (shortcut: Shift+C)'),
144      ['shift+c' => $this->t('Clear all changes history')]
145    );
146    $clear['#props']['variant'] = 'warning';
147    $clear['#attributes']['outline'] = TRUE;
148
149    if (empty($builder->getPast()) && empty($builder->getFuture())) {
150      $clear['#attributes']['class'] = ['hidden'];
151    }
152
153    return $this->htmxEvents->onClear($clear, (string) $builder->id());
154  }
155
156}

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.

HistoryButtons->build
32  public function build(InstanceInterface $builder, array $data = [], array $options = []): array {
33    $buttons = [
34      $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder) : [],
34      $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder) : [],
34      $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder) : [],
34      $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder) : [],
35      $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder) : [],
35      $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder) : [],
34      $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder) : [],
34      $this->isButtonEnabled('undo') ? $this->buildUndoButton($builder) : [],
35      $this->isButtonEnabled('redo') ? $this->buildRedoButton($builder) : [],
36    ];
37    $clear_button = $this->isButtonEnabled('clear') ? $this->buildClearButton($builder) : [];
37    $clear_button = $this->isButtonEnabled('clear') ? $this->buildClearButton($builder) : [];
37    $clear_button = $this->isButtonEnabled('clear') ? $this->buildClearButton($builder) : [];
37    $clear_button = $this->isButtonEnabled('clear') ? $this->buildClearButton($builder) : [];
38
39    if (empty(\array_filter($buttons))) {
40      return [];
44      '#type' => 'component',
45      '#component' => 'display_builder:button_group',
46      '#slots' => [
47        'buttons' => $buttons,
48      ],
49    ];
50
51    return [$build, $clear_button];
52  }
HistoryButtons->buildClearButton
138  private function buildClearButton(InstanceInterface $builder): array {
139    $clear = $this->buildButton(
140      $this->showLabel('clear') ? $this->t('Clear') : '',
140      $this->showLabel('clear') ? $this->t('Clear') : '',
140      $this->showLabel('clear') ? $this->t('Clear') : '',
140      $this->showLabel('clear') ? $this->t('Clear') : '',
141      'clear',
142      $this->showIcon('clear') ? 'clock-history' : '',
142      $this->showIcon('clear') ? 'clock-history' : '',
142      $this->showIcon('clear') ? 'clock-history' : '',
142      $this->showIcon('clear') ? 'clock-history' : '',
143      $this->t('Clear history (shortcut: Shift+C)'),
144      ['shift+c' => $this->t('Clear all changes history')]
145    );
146    $clear['#props']['variant'] = 'warning';
147    $clear['#attributes']['outline'] = TRUE;
148
149    if (empty($builder->getPast()) && empty($builder->getFuture())) {
149    if (empty($builder->getPast()) && empty($builder->getFuture())) {
149    if (empty($builder->getPast()) && empty($builder->getFuture())) {
150      $clear['#attributes']['class'] = ['hidden'];
151    }
152
153    return $this->htmxEvents->onClear($clear, (string) $builder->id());
153    return $this->htmxEvents->onClear($clear, (string) $builder->id());
154  }
HistoryButtons->buildRedoButton
112  private function buildRedoButton(InstanceInterface $builder): array {
113    $future = $builder->getFuture();
114    $redo = $this->buildButton(
115      ($this->showLabel('redo') && $future) ? (string) \count($future) : '',
115      ($this->showLabel('redo') && $future) ? (string) \count($future) : '',
115      ($this->showLabel('redo') && $future) ? (string) \count($future) : '',
115      ($this->showLabel('redo') && $future) ? (string) \count($future) : '',
115      ($this->showLabel('redo') && $future) ? (string) \count($future) : '',
115      ($this->showLabel('redo') && $future) ? (string) \count($future) : '',
116      'redo',
117      'arrow-clockwise',
118      $this->t('Redo (shortcut: Ctrl/Cmd+Shift+Z)'),
119      ['mod+shift+z r' => $this->t('Redo last undone change')]
120    );
121
122    if (empty($future)) {
123      $redo['#attributes']['disabled'] = 'disabled';
124    }
125
126    return $this->htmxEvents->onRedo($redo, (string) $builder->id());
126    return $this->htmxEvents->onRedo($redo, (string) $builder->id());
127  }
HistoryButtons->buildUndoButton
86  private function buildUndoButton(InstanceInterface $builder): array {
87    $past = $builder->getPast();
88    $undo = $this->buildButton(
89      ($this->showLabel('undo') && $past) ? (string) \count($past) : '',
89      ($this->showLabel('undo') && $past) ? (string) \count($past) : '',
89      ($this->showLabel('undo') && $past) ? (string) \count($past) : '',
89      ($this->showLabel('undo') && $past) ? (string) \count($past) : '',
89      ($this->showLabel('undo') && $past) ? (string) \count($past) : '',
89      ($this->showLabel('undo') && $past) ? (string) \count($past) : '',
90      'undo',
91      'arrow-counterclockwise',
92      $this->t('Undo (shortcut: Ctrl/Cmd+Z)'),
93      ['mod+z u' => $this->t('Undo last change')]
94    );
95
96    if (empty($past)) {
97      $undo['#attributes']['disabled'] = 'disabled';
98    }
99
100    return $this->htmxEvents->onUndo($undo, (string) $builder->id());
100    return $this->htmxEvents->onUndo($undo, (string) $builder->id());
101  }
HistoryButtons->hasButtons
60        'title' => $this->t('Undo'),
61        'description' => $this->t('Undo action, icon is always visible, label is number of undo.'),
62        'default' => 'icon_label',
63      ],
64      'redo' => [
65        'title' => $this->t('Redo'),
66        'description' => $this->t('Redo action, icon is always visible, label is number of redo.'),
67        'default' => 'icon_label',
68      ],
69      'clear' => [
70        'title' => $this->t('Clear'),
71        'description' => $this->t('A button to clear the logs history (past and future).'),
72        'default' => 'hidden',
73      ],
74    ];
75  }