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