Code Coverage
 
Lines
Branches
Paths
Functions and Methods
Classes and Traits
Total
95.60% covered (success)
95.60%
174 / 182
96.67% covered (success)
96.67%
29 / 30
68.97% covered (warning)
68.97%
20 / 29
94.44% covered (success)
94.44%
17 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
HtmxEvents
95.60% covered (success)
95.60%
174 / 182
96.67% covered (success)
96.67%
29 / 30
68.97% covered (warning)
68.97%
20 / 29
94.44% covered (success)
94.44%
17 / 18
41.22
0.00% covered (danger)
0.00%
0 / 1
 onClickDelete
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onClickSavePreset
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onClickPaste
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onClickDuplicate
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onClickPasteStyles
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onClickDeleteStyles
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onRootDrop
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onSlotDrop
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onInstanceClick
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
5 / 5
25.00% covered (danger)
25.00%
1 / 4
100.00% covered (success)
100.00%
1 / 1
6.80
 onInstanceFormChange
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 onInstanceUpdateButtonClick
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
7 / 7
37.50% covered (danger)
37.50%
3 / 8
100.00% covered (success)
100.00%
1 / 1
7.91
 onThirdPartyFormChange
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onUndo
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onRedo
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onReset
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onRevert
0.00% covered (danger)
0.00%
0 / 8
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
 onClear
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 onPublish
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\display_builder;
6
7use Drupal\Component\Render\MarkupInterface;
8use Drupal\Core\Url;
9
10/**
11 * The HTMX Events class.
12 */
13class HtmxEvents {
14
15  public const HTMX_REQUEST = 'click consume';
16
17  /**
18   * Delete on click.
19   *
20   * The node ID isn't known until the contextual menu resolves what was
21   * right-clicked, so it's supplied at request time via 'hx-vals'
22   * (@see components/contextual_menu/contextual_menu.js) rather than baked into
23   * the URL here.
24   *
25   * @param array $build
26   *   The render array.
27   * @param string $builder_id
28   *   The instance entity ID.
29   *
30   * @return array
31   *   The render array.
32   */
33  public function onClickDelete(array $build, string $builder_id): array {
34    $url = new Url(
35      'display_builder.api_delete',
36      [
37        'display_builder_instance' => $builder_id,
38      ]
39    );
40
41    $htmx = DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST);
42    $htmx->on('click', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "close")', $builder_id));
43    $htmx->applyTo($build);
44
45    return $build;
46  }
47
48  /**
49   * Save as preset on click.
50   *
51   * The node ID isn't known until the contextual menu resolves what was
52   * right-clicked, so it's supplied at request time via 'hx-vals'
53   * (@see components/contextual_menu/contextual_menu.js) rather than baked into
54   * the URL here.
55   *
56   * @param array $build
57   *   The render array.
58   * @param string $builder_id
59   *   The instance entity ID.
60   * @param string|\Drupal\Component\Render\MarkupInterface $prompt
61   *   The prompt before save.
62   *
63   * @return array
64   *   The render array.
65   */
66  public function onClickSavePreset(array $build, string $builder_id, MarkupInterface|string $prompt): array {
67    $url = new Url(
68      'display_builder.api_save_preset',
69      [
70        'display_builder_instance' => $builder_id,
71      ]
72    );
73
74    $htmx = DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST);
75    $htmx->prompt((string) $prompt);
76    $htmx->applyTo($build);
77
78    return $build;
79  }
80
81  /**
82   * Paste on click.
83   *
84   * The node/parent/slot IDs aren't known until the contextual menu
85   * resolves what was right-clicked and what was previously copied, so
86   * they're supplied at request time via 'hx-vals'
87   * (@see components/contextual_menu/contextual_menu.js) rather than baked into
88   * the URL here.
89   *
90   * @param array $build
91   *   The render array.
92   * @param string $builder_id
93   *   The instance entity ID.
94   *
95   * @return array
96   *   The render array.
97   */
98  public function onClickPaste(array $build, string $builder_id): array {
99    $url = new Url(
100      'display_builder.api_paste',
101      [
102        'display_builder_instance' => $builder_id,
103      ]
104    );
105
106    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
107
108    return $build;
109  }
110
111  /**
112   * Duplicate on placeholder click.
113   *
114   * The node/parent/slot IDs aren't known until the contextual menu
115   * resolves what was right-clicked, so they're supplied at request time
116   * via 'hx-vals' (@see components/contextual_menu/contextual_menu.js) rather
117   * than baked into the URL here.
118   *
119   * @param array $build
120   *   The render array.
121   * @param string $builder_id
122   *   The instance entity ID.
123   *
124   * @return array
125   *   The render array.
126   */
127  public function onClickDuplicate(array $build, string $builder_id): array {
128    $url = new Url(
129      'display_builder.api_duplicate',
130      [
131        'display_builder_instance' => $builder_id,
132      ]
133    );
134
135    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
136
137    return $build;
138  }
139
140  /**
141   * Paste or merge styles on click.
142   *
143   * Used by both the "Paste styles" and "Merge styles" menu items - they
144   * hit the same endpoint and only differ in the 'mode' request value,
145   * which the contextual menu sets based on which item was clicked
146   * (@see components/contextual_menu/contextual_menu.js), same as the
147   * target/source node IDs.
148   *
149   * @param array $build
150   *   The render array.
151   * @param string $builder_id
152   *   The instance entity ID.
153   *
154   * @return array
155   *   The render array.
156   */
157  public function onClickPasteStyles(array $build, string $builder_id): array {
158    $url = new Url(
159      'display_builder.api_paste_styles',
160      [
161        'display_builder_instance' => $builder_id,
162      ]
163    );
164
165    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
166
167    return $build;
168  }
169
170  /**
171   * Delete styles on click.
172   *
173   * The node ID isn't known until the contextual menu resolves what was
174   * right-clicked, so it's supplied at request time via 'hx-vals'
175   * (@see components/contextual_menu/contextual_menu.js) rather than baked into
176   * the URL here.
177   *
178   * @param array $build
179   *   The render array.
180   * @param string $builder_id
181   *   The instance entity ID.
182   *
183   * @return array
184   *   The render array.
185   */
186  public function onClickDeleteStyles(array $build, string $builder_id): array {
187    $url = new Url(
188      'display_builder.api_delete_styles',
189      [
190        'display_builder_instance' => $builder_id,
191      ]
192    );
193
194    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
195
196    return $build;
197  }
198
199  /**
200   * Drop a component_id, a block_id, or an node_id, to the root dropzone.
201   *
202   * @param array $build
203   *   The render array.
204   * @param string $builder_id
205   *   The instance entity ID.
206   * @param string $island_id
207   *   The island initiating the event.
208   *
209   * @return array
210   *   The render array.
211   */
212  public function onRootDrop(array $build, string $builder_id, string $island_id): array {
213    $url = new Url(
214      'display_builder.api_root_attach',
215      [
216        'display_builder_instance' => $builder_id,
217        'from' => $island_id,
218      ]
219    );
220
221    $htmx = DisplayBuilderHtmx::request('post', $url, 'dragend consume');
222    $htmx->on('dragend', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "dragend")', $builder_id));
223    $htmx->applyTo($build);
224
225    return $build;
226  }
227
228  /**
229   * Drop a component_id, a block_id, or an node_id, to a component slot.
230   *
231   * @param array $build
232   *   The render array.
233   * @param string $builder_id
234   *   The instance entity ID.
235   * @param string $island_id
236   *   The island initiating the event.
237   * @param string $node_id
238   *   The node id of the source.
239   * @param string $slot
240   *   The slot.
241   *
242   * @return array
243   *   The render array.
244   */
245  public function onSlotDrop(array $build, string $builder_id, string $island_id, string $node_id, string $slot): array {
246    $url = new Url(
247      'display_builder.api_slot_attach',
248      [
249        'display_builder_instance' => $builder_id,
250        'node_id' => $node_id,
251        'slot' => $slot,
252        'from' => $island_id,
253      ]
254    );
255
256    $htmx = DisplayBuilderHtmx::request('post', $url, 'dragend consume');
257    $htmx->on('dragend', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "dragend")', $builder_id));
258    $htmx->applyTo($build);
259
260    return $build;
261  }
262
263  /**
264   * When a component or block is clicked.
265   *
266   * @param array $build
267   *   The render array.
268   * @param string $builder_id
269   *   The instance entity ID.
270   * @param string $node_id
271   *   The node id of the source.
272   * @param string $title
273   *   The instance title.
274   * @param int $index
275   *   The instance index.
276   *
277   * @return array
278   *   The render array.
279   */
280  public function onInstanceClick(array $build, string $builder_id, string $node_id, string $title, int $index): array {
281    $url = new Url(
282      'display_builder.api_get',
283      [
284        'display_builder_instance' => $builder_id,
285        'node_id' => $node_id,
286      ]
287    );
288
289    $htmx = DisplayBuilderHtmx::request('get', $url, self::HTMX_REQUEST);
290    $htmx->vals(['node_id' => $node_id]);
291    $htmx->on('click', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "click")', $builder_id));
292    $htmx->applyTo($build);
293
294    $attributes = [
295      'tabindex' => '0',
296      'data-node-id' => $node_id,
297    ];
298
299    // If not set before we add information for contextual menu or drawer label.
300    if (!isset($build['#attributes']['data-node-title'])) {
301      // Only for icon case, remove suffix without loading label.
302      $attributes['data-node-title'] = \ucfirst(\trim(\str_replace(['renderable', '_'], ['', ' '], $title)));
303    }
304
305    if (!isset($build['#attributes']['data-slot-position'])) {
306      $attributes['data-slot-position'] = $index;
307    }
308
309    $build['#attributes'] = \array_merge($build['#attributes'] ?? [], $attributes);
310
311    return $build;
312  }
313
314  /**
315   * When a value is changed in an instance island form.
316   *
317   * @param array $build
318   *   The render array.
319   * @param string $builder_id
320   *   The instance entity ID.
321   * @param string $island_id
322   *   The island initiating the event.
323   * @param string $node_id
324   *   The node id of the source.
325   *
326   * @return array
327   *   The render array.
328   */
329  public function onInstanceFormChange(array $build, string $builder_id, string $island_id, string $node_id): array {
330    if (!isset($build['source'])) {
331      return $build;
332    }
333
334    $url = new Url(
335      'display_builder.api_update',
336      [
337        'display_builder_instance' => $builder_id,
338        'node_id' => $node_id,
339        'from' => $island_id,
340      ]
341    );
342
343    $htmx = DisplayBuilderHtmx::request('put', $url, 'change consume');
344
345    $htmx->applyTo($build['source']);
346
347    return $build;
348  }
349
350  /**
351   * When the update button is clicked in an instance island form.
352   *
353   * @param array $build
354   *   The render array.
355   * @param string $builder_id
356   *   The instance entity ID.
357   * @param string $island_id
358   *   The island initiating the event.
359   * @param string $node_id
360   *   The node id of the source.
361   *
362   * @return array
363   *   The render array.
364   */
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
367      return $build;
368    }
369    $url = new Url(
370      'display_builder.api_update',
371      [
372        'display_builder_instance' => $builder_id,
373        'node_id' => $node_id,
374        'from' => $island_id,
375      ]
376    );
377
378    $htmx = DisplayBuilderHtmx::request('put', $url, self::HTMX_REQUEST);
379    $htmx->include('#' . $build['source']['#id']);
380
381    $htmx->applyTo($build['update']);
382
383    return $build;
384  }
385
386  /**
387   * When a value is changed in a third party island.
388   *
389   * @param array $build
390   *   The render array.
391   * @param string $builder_id
392   *   The instance entity ID.
393   * @param string $node_id
394   *   The node id of the source.
395   * @param string $island_id
396   *   The island id.
397   *
398   * @return array
399   *   The render array.
400   */
401  public function onThirdPartyFormChange(array $build, string $builder_id, string $node_id, string $island_id): array {
402    $url = new Url(
403      'display_builder.api_third_party_settings_update',
404      [
405        'display_builder_instance' => $builder_id,
406        'node_id' => $node_id,
407        'island_id' => $island_id,
408      ]
409    );
410
411    DisplayBuilderHtmx::request('put', $url, 'change')->applyTo($build);
412
413    return $build;
414  }
415
416  /**
417   * When the undo button is clicked.
418   *
419   * @param array $build
420   *   The render array.
421   * @param string $builder_id
422   *   The instance entity ID.
423   *
424   * @return array
425   *   The render array.
426   */
427  public function onUndo(array $build, string $builder_id): array {
428    $url = new Url(
429      'display_builder.api_undo',
430      [
431        'display_builder_instance' => $builder_id,
432      ]
433    );
434
435    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
436
437    return $build;
438  }
439
440  /**
441   * When the undo button is clicked.
442   *
443   * @param array $build
444   *   The render array.
445   * @param string $builder_id
446   *   The instance entity ID.
447   *
448   * @return array
449   *   The render array.
450   */
451  public function onRedo(array $build, string $builder_id): array {
452    $url = new Url(
453      'display_builder.api_redo',
454      [
455        'display_builder_instance' => $builder_id,
456      ]
457    );
458
459    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
460
461    return $build;
462  }
463
464  /**
465   * When the restore button is clicked.
466   *
467   * @param array $build
468   *   The render array.
469   * @param string $builder_id
470   *   The instance entity ID.
471   *
472   * @return array
473   *   The render array.
474   */
475  public function onReset(array $build, string $builder_id): array {
476    $url = new Url(
477      'display_builder.api_restore',
478      [
479        'display_builder_instance' => $builder_id,
480      ]
481    );
482
483    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
484
485    return $build;
486  }
487
488  /**
489   * When the revert button is clicked.
490   *
491   * @param array $build
492   *   The render array.
493   * @param string $builder_id
494   *   The instance entity ID.
495   *
496   * @return array
497   *   The render array.
498   */
499  public function onRevert(array $build, string $builder_id): array {
500    $url = new Url(
501      'display_builder.api_revert',
502      [
503        'display_builder_instance' => $builder_id,
504      ]
505    );
506
507    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
508
509    return $build;
510  }
511
512  /**
513   * When the history clear button is clicked.
514   *
515   * @param array $build
516   *   The render array.
517   * @param string $builder_id
518   *   The instance entity ID.
519   *
520   * @return array
521   *   The render array.
522   */
523  public function onClear(array $build, string $builder_id): array {
524    $url = new Url(
525      'display_builder.api_clear',
526      [
527        'display_builder_instance' => $builder_id,
528      ]
529    );
530
531    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
532
533    return $build;
534  }
535
536  /**
537   * When the save button is clicked.
538   *
539   * @param array $build
540   *   The render array.
541   * @param string $builder_id
542   *   The instance entity ID.
543   *
544   * @return array
545   *   The render array.
546   */
547  public function onPublish(array $build, string $builder_id): array {
548    $url = new Url(
549      'display_builder.api_publish',
550      [
551        'display_builder_instance' => $builder_id,
552      ]
553    );
554
555    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
556
557    return $build;
558  }
559
560}

Paths

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

HtmxEvents->onClear
523  public function onClear(array $build, string $builder_id): array {
524    $url = new Url(
525      'display_builder.api_clear',
526      [
527        'display_builder_instance' => $builder_id,
528      ]
529    );
530
531    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
532
533    return $build;
534  }
HtmxEvents->onClickDelete
33  public function onClickDelete(array $build, string $builder_id): array {
34    $url = new Url(
35      'display_builder.api_delete',
36      [
37        'display_builder_instance' => $builder_id,
38      ]
39    );
40
41    $htmx = DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST);
42    $htmx->on('click', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "close")', $builder_id));
43    $htmx->applyTo($build);
44
45    return $build;
46  }
HtmxEvents->onClickDeleteStyles
186  public function onClickDeleteStyles(array $build, string $builder_id): array {
187    $url = new Url(
188      'display_builder.api_delete_styles',
189      [
190        'display_builder_instance' => $builder_id,
191      ]
192    );
193
194    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
195
196    return $build;
197  }
HtmxEvents->onClickDuplicate
127  public function onClickDuplicate(array $build, string $builder_id): array {
128    $url = new Url(
129      'display_builder.api_duplicate',
130      [
131        'display_builder_instance' => $builder_id,
132      ]
133    );
134
135    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
136
137    return $build;
138  }
HtmxEvents->onClickPaste
98  public function onClickPaste(array $build, string $builder_id): array {
99    $url = new Url(
100      'display_builder.api_paste',
101      [
102        'display_builder_instance' => $builder_id,
103      ]
104    );
105
106    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
107
108    return $build;
109  }
HtmxEvents->onClickPasteStyles
157  public function onClickPasteStyles(array $build, string $builder_id): array {
158    $url = new Url(
159      'display_builder.api_paste_styles',
160      [
161        'display_builder_instance' => $builder_id,
162      ]
163    );
164
165    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
166
167    return $build;
168  }
HtmxEvents->onClickSavePreset
66  public function onClickSavePreset(array $build, string $builder_id, MarkupInterface|string $prompt): array {
67    $url = new Url(
68      'display_builder.api_save_preset',
69      [
70        'display_builder_instance' => $builder_id,
71      ]
72    );
73
74    $htmx = DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST);
75    $htmx->prompt((string) $prompt);
76    $htmx->applyTo($build);
77
78    return $build;
79  }
HtmxEvents->onInstanceClick
280  public function onInstanceClick(array $build, string $builder_id, string $node_id, string $title, int $index): array {
281    $url = new Url(
282      'display_builder.api_get',
283      [
284        'display_builder_instance' => $builder_id,
285        'node_id' => $node_id,
286      ]
287    );
288
289    $htmx = DisplayBuilderHtmx::request('get', $url, self::HTMX_REQUEST);
290    $htmx->vals(['node_id' => $node_id]);
291    $htmx->on('click', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "click")', $builder_id));
292    $htmx->applyTo($build);
293
294    $attributes = [
295      'tabindex' => '0',
296      'data-node-id' => $node_id,
297    ];
298
299    // If not set before we add information for contextual menu or drawer label.
300    if (!isset($build['#attributes']['data-node-title'])) {
 
302      $attributes['data-node-title'] = \ucfirst(\trim(\str_replace(['renderable', '_'], ['', ' '], $title)));
303    }
304
305    if (!isset($build['#attributes']['data-slot-position'])) {
 
305    if (!isset($build['#attributes']['data-slot-position'])) {
 
306      $attributes['data-slot-position'] = $index;
307    }
308
309    $build['#attributes'] = \array_merge($build['#attributes'] ?? [], $attributes);
 
309    $build['#attributes'] = \array_merge($build['#attributes'] ?? [], $attributes);
310
311    return $build;
312  }
280  public function onInstanceClick(array $build, string $builder_id, string $node_id, string $title, int $index): array {
281    $url = new Url(
282      'display_builder.api_get',
283      [
284        'display_builder_instance' => $builder_id,
285        'node_id' => $node_id,
286      ]
287    );
288
289    $htmx = DisplayBuilderHtmx::request('get', $url, self::HTMX_REQUEST);
290    $htmx->vals(['node_id' => $node_id]);
291    $htmx->on('click', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "click")', $builder_id));
292    $htmx->applyTo($build);
293
294    $attributes = [
295      'tabindex' => '0',
296      'data-node-id' => $node_id,
297    ];
298
299    // If not set before we add information for contextual menu or drawer label.
300    if (!isset($build['#attributes']['data-node-title'])) {
 
302      $attributes['data-node-title'] = \ucfirst(\trim(\str_replace(['renderable', '_'], ['', ' '], $title)));
303    }
304
305    if (!isset($build['#attributes']['data-slot-position'])) {
 
305    if (!isset($build['#attributes']['data-slot-position'])) {
 
309    $build['#attributes'] = \array_merge($build['#attributes'] ?? [], $attributes);
310
311    return $build;
312  }
280  public function onInstanceClick(array $build, string $builder_id, string $node_id, string $title, int $index): array {
281    $url = new Url(
282      'display_builder.api_get',
283      [
284        'display_builder_instance' => $builder_id,
285        'node_id' => $node_id,
286      ]
287    );
288
289    $htmx = DisplayBuilderHtmx::request('get', $url, self::HTMX_REQUEST);
290    $htmx->vals(['node_id' => $node_id]);
291    $htmx->on('click', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "click")', $builder_id));
292    $htmx->applyTo($build);
293
294    $attributes = [
295      'tabindex' => '0',
296      'data-node-id' => $node_id,
297    ];
298
299    // If not set before we add information for contextual menu or drawer label.
300    if (!isset($build['#attributes']['data-node-title'])) {
 
305    if (!isset($build['#attributes']['data-slot-position'])) {
 
306      $attributes['data-slot-position'] = $index;
307    }
308
309    $build['#attributes'] = \array_merge($build['#attributes'] ?? [], $attributes);
 
309    $build['#attributes'] = \array_merge($build['#attributes'] ?? [], $attributes);
310
311    return $build;
312  }
280  public function onInstanceClick(array $build, string $builder_id, string $node_id, string $title, int $index): array {
281    $url = new Url(
282      'display_builder.api_get',
283      [
284        'display_builder_instance' => $builder_id,
285        'node_id' => $node_id,
286      ]
287    );
288
289    $htmx = DisplayBuilderHtmx::request('get', $url, self::HTMX_REQUEST);
290    $htmx->vals(['node_id' => $node_id]);
291    $htmx->on('click', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "click")', $builder_id));
292    $htmx->applyTo($build);
293
294    $attributes = [
295      'tabindex' => '0',
296      'data-node-id' => $node_id,
297    ];
298
299    // If not set before we add information for contextual menu or drawer label.
300    if (!isset($build['#attributes']['data-node-title'])) {
 
305    if (!isset($build['#attributes']['data-slot-position'])) {
 
309    $build['#attributes'] = \array_merge($build['#attributes'] ?? [], $attributes);
310
311    return $build;
312  }
HtmxEvents->onInstanceFormChange
329  public function onInstanceFormChange(array $build, string $builder_id, string $island_id, string $node_id): array {
330    if (!isset($build['source'])) {
 
331      return $build;
329  public function onInstanceFormChange(array $build, string $builder_id, string $island_id, string $node_id): array {
330    if (!isset($build['source'])) {
 
334    $url = new Url(
335      'display_builder.api_update',
336      [
337        'display_builder_instance' => $builder_id,
338        'node_id' => $node_id,
339        'from' => $island_id,
340      ]
341    );
342
343    $htmx = DisplayBuilderHtmx::request('put', $url, 'change consume');
344
345    $htmx->applyTo($build['source']);
346
347    return $build;
348  }
HtmxEvents->onInstanceUpdateButtonClick
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
367      return $build;
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
369    $url = new Url(
370      'display_builder.api_update',
371      [
372        'display_builder_instance' => $builder_id,
373        'node_id' => $node_id,
374        'from' => $island_id,
375      ]
376    );
377
378    $htmx = DisplayBuilderHtmx::request('put', $url, self::HTMX_REQUEST);
379    $htmx->include('#' . $build['source']['#id']);
380
381    $htmx->applyTo($build['update']);
382
383    return $build;
384  }
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
367      return $build;
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
369    $url = new Url(
370      'display_builder.api_update',
371      [
372        'display_builder_instance' => $builder_id,
373        'node_id' => $node_id,
374        'from' => $island_id,
375      ]
376    );
377
378    $htmx = DisplayBuilderHtmx::request('put', $url, self::HTMX_REQUEST);
379    $htmx->include('#' . $build['source']['#id']);
380
381    $htmx->applyTo($build['update']);
382
383    return $build;
384  }
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
367      return $build;
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
369    $url = new Url(
370      'display_builder.api_update',
371      [
372        'display_builder_instance' => $builder_id,
373        'node_id' => $node_id,
374        'from' => $island_id,
375      ]
376    );
377
378    $htmx = DisplayBuilderHtmx::request('put', $url, self::HTMX_REQUEST);
379    $htmx->include('#' . $build['source']['#id']);
380
381    $htmx->applyTo($build['update']);
382
383    return $build;
384  }
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
367      return $build;
365  public function onInstanceUpdateButtonClick(array $build, string $builder_id, string $island_id, string $node_id): array {
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
366    if (!isset($build['update']) || !isset($build['source']) || !isset($build['source']['#id'])) {
 
369    $url = new Url(
370      'display_builder.api_update',
371      [
372        'display_builder_instance' => $builder_id,
373        'node_id' => $node_id,
374        'from' => $island_id,
375      ]
376    );
377
378    $htmx = DisplayBuilderHtmx::request('put', $url, self::HTMX_REQUEST);
379    $htmx->include('#' . $build['source']['#id']);
380
381    $htmx->applyTo($build['update']);
382
383    return $build;
384  }
HtmxEvents->onPublish
547  public function onPublish(array $build, string $builder_id): array {
548    $url = new Url(
549      'display_builder.api_publish',
550      [
551        'display_builder_instance' => $builder_id,
552      ]
553    );
554
555    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
556
557    return $build;
558  }
HtmxEvents->onRedo
451  public function onRedo(array $build, string $builder_id): array {
452    $url = new Url(
453      'display_builder.api_redo',
454      [
455        'display_builder_instance' => $builder_id,
456      ]
457    );
458
459    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
460
461    return $build;
462  }
HtmxEvents->onReset
475  public function onReset(array $build, string $builder_id): array {
476    $url = new Url(
477      'display_builder.api_restore',
478      [
479        'display_builder_instance' => $builder_id,
480      ]
481    );
482
483    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
484
485    return $build;
486  }
HtmxEvents->onRevert
499  public function onRevert(array $build, string $builder_id): array {
500    $url = new Url(
501      'display_builder.api_revert',
502      [
503        'display_builder_instance' => $builder_id,
504      ]
505    );
506
507    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
508
509    return $build;
510  }
HtmxEvents->onRootDrop
212  public function onRootDrop(array $build, string $builder_id, string $island_id): array {
213    $url = new Url(
214      'display_builder.api_root_attach',
215      [
216        'display_builder_instance' => $builder_id,
217        'from' => $island_id,
218      ]
219    );
220
221    $htmx = DisplayBuilderHtmx::request('post', $url, 'dragend consume');
222    $htmx->on('dragend', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "dragend")', $builder_id));
223    $htmx->applyTo($build);
224
225    return $build;
226  }
HtmxEvents->onSlotDrop
245  public function onSlotDrop(array $build, string $builder_id, string $island_id, string $node_id, string $slot): array {
246    $url = new Url(
247      'display_builder.api_slot_attach',
248      [
249        'display_builder_instance' => $builder_id,
250        'node_id' => $node_id,
251        'slot' => $slot,
252        'from' => $island_id,
253      ]
254    );
255
256    $htmx = DisplayBuilderHtmx::request('post', $url, 'dragend consume');
257    $htmx->on('dragend', \sprintf('Drupal.displayBuilder.handleSecondDrawer(%s, this, event, "dragend")', $builder_id));
258    $htmx->applyTo($build);
259
260    return $build;
261  }
HtmxEvents->onThirdPartyFormChange
401  public function onThirdPartyFormChange(array $build, string $builder_id, string $node_id, string $island_id): array {
402    $url = new Url(
403      'display_builder.api_third_party_settings_update',
404      [
405        'display_builder_instance' => $builder_id,
406        'node_id' => $node_id,
407        'island_id' => $island_id,
408      ]
409    );
410
411    DisplayBuilderHtmx::request('put', $url, 'change')->applyTo($build);
412
413    return $build;
414  }
HtmxEvents->onUndo
427  public function onUndo(array $build, string $builder_id): array {
428    $url = new Url(
429      'display_builder.api_undo',
430      [
431        'display_builder_instance' => $builder_id,
432      ]
433    );
434
435    DisplayBuilderHtmx::request('post', $url, self::HTMX_REQUEST)->applyTo($build);
436
437    return $build;
438  }