From 488cc36a546c1d070c734a8b11019919a4d8cc11 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Wed, 16 Apr 2025 14:48:49 +0200 Subject: [PATCH 01/15] #3519238: add checkbox to secondary toolbar --- frontend_editing.services.yml | 4 ++ src/Hook/FrontendEditingHooks.php | 58 +++++++++++++++++++++++ src/ToolbarItem.php | 78 +++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 src/Hook/FrontendEditingHooks.php create mode 100644 src/ToolbarItem.php diff --git a/frontend_editing.services.yml b/frontend_editing.services.yml index 696c3d4..2a6c136 100644 --- a/frontend_editing.services.yml +++ b/frontend_editing.services.yml @@ -9,3 +9,7 @@ services: frontend_editing.form_builder: class: Drupal\frontend_editing\FrontendEditingFormBuilder arguments: ['@entity_type.manager', '@entity.form_builder', '@form_builder'] + frontend_editing.toolbar_item: + class: Drupal\frontend_editing\ToolbarItem + arguments: [ '@plugin.manager.element_info' ] + Drupal\frontend_editing\ToolbarItem: '@frontend_editing.toolbar_item' diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php new file mode 100644 index 0000000..2ca751e --- /dev/null +++ b/src/Hook/FrontendEditingHooks.php @@ -0,0 +1,58 @@ +<?php + +namespace Drupal\frontend_editing\Hook; + +use Drupal\Core\Hook\Attribute\Hook; +use Drupal\frontend_editing\RenderCallbacks; +use Drupal\frontend_editing\ToolbarItem; + +/** + * Hook implementations for frontend_editing. + */ +class FrontendEditingHooks { + + /** + * Implements hook_toolbar(). + */ + #[Hook('toolbar')] + public function toolbar() { + if (!\Drupal::currentUser()->hasPermission('access frontend editing')) { + return ['#cache' => ['contexts' => ['user.permissions']]]; + } + $items['toggle'] = [ + '#type' => 'toolbar_item', + 'tab' => [ + '#lazy_builder' => [ + 'frontend_editing.toolbar_item:renderToggle', + [], + ], + '#create_placeholder' => TRUE, + '#cache' => [ + 'tags' => [ + 'frontend_editing:toggle', + ], + ], + ], + '#wrapper_attributes' => [ + 'class' => [ + 'toggle-toolbar-tab', + ], + ], + '#cache' => [ + 'contexts' => [ + 'user.permissions', + ], + ], + '#weight' => -20, + ]; + // \Drupal\toolbar\Element\ToolbarItem::preRenderToolbarItem adds an + // #attributes property to each toolbar item's tab child automatically. + // Lazy builders don't support an #attributes property so we need to + // add another render callback to remove the #attributes property. We start by + // adding the defaults, and then we append our own pre render callback. + $items['toggle'] += \Drupal::service('plugin.manager.element_info')->getInfo('toolbar_item'); + $items['toggle']['#pre_render'][] = [ToolbarItem::class, 'removeTabAttributes']; + return $items; + } + +} diff --git a/src/ToolbarItem.php b/src/ToolbarItem.php new file mode 100644 index 0000000..810a7b6 --- /dev/null +++ b/src/ToolbarItem.php @@ -0,0 +1,78 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\frontend_editing; + +use Drupal\Component\Serialization\Json; +use Drupal\Component\Utility\Html; +use Drupal\Core\Render\ElementInfoManagerInterface; +use Drupal\Core\Security\TrustedCallbackInterface; +use Drupal\Core\Url; + +/** + * Defines a class for lazy building render arrays. + * + * @internal + */ +final class ToolbarItem implements TrustedCallbackInterface { + + /** + * Constructs LazyBuilders object. + * + * @param \Drupal\Core\Render\ElementInfoManagerInterface $elementInfo + * Element info. + */ + public function __construct( + protected ElementInfoManagerInterface $elementInfo, + ) { + } + + /** + * Render announcements. + * + * @return array + * Render array. + */ + public function renderToggle(): array { + $build = [ + '#type' => 'checkbox', + '#cache' => [ + 'context' => ['user.permissions'], + ], + '#title' => t('Frontend Editing'), + '#id' => Html::getId('toolbar-item-toggle'), + '#attributes' => [ + 'title' => t('Toggle'), + // 'class' => [ + // ], + ], + // '#attached' => [ + // 'library' => [ + // 'frontend_editing/drupal.frontend_editing.toolbar', + // ], + // ], + ]; + + // The renderer has already added element defaults by the time the lazy + // builder is run. + // @see https://www.drupal.org/project/drupal/issues/2609250 + $build += $this->elementInfo->getInfo('checkbox'); + return $build; + } + + /** + * {@inheritdoc} + */ + public static function trustedCallbacks(): array { + return ['renderToggle', 'removeTabAttributes']; + } + + /** + * Render callback. + */ + public static function removeTabAttributes(array $element): array { + unset($element['tab']['#attributes']); + return $element; + } +} -- GitLab From 1e65494c91a90142d8da7f869ef254a0280a814c Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Wed, 16 Apr 2025 17:49:28 +0200 Subject: [PATCH 02/15] #3519238: style the toolbar item --- css/ui_toggle.css | 42 +++++++++++++++++++++++++++++++ src/Hook/FrontendEditingHooks.php | 2 +- src/ToolbarItem.php | 26 ++++++++++--------- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/css/ui_toggle.css b/css/ui_toggle.css index 687609d..f9ef914 100644 --- a/css/ui_toggle.css +++ b/css/ui_toggle.css @@ -32,6 +32,30 @@ text-align: right; } +.frontend-editing-toolbar-toggle { + background: rgba(var(--fe-editing-primary-color), 0.6); + padding: 0.5rem 0.75rem; + text-transform: uppercase; + color: white; + display: block; + font-weight: 500; + border-radius: 999px; + box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px; + text-align: right; + height: 2rem; + padding-left: 2.5rem; + margin-right: 1rem; +} + +.frontend-editing-toolbar-toggle a { + color: white; +} + + /* Overrides undesired styles from gin. */ +.gin-secondary-toolbar .toolbar-secondary .toolbar-bar .toolbar-tab.frontend-editing-toolbar-toggle:hover { + border-radius: 999px; +} + .frontend-editing-toggle a::before { content: ' '; position: absolute; @@ -50,6 +74,24 @@ border-radius: 999px; } +.frontend-editing-toolbar-toggle a::before { + content: ' '; + position: absolute; + top: 0; + left: 0.5rem; + bottom: 0; + width: 1.5rem; + height: 1.5rem; + margin-bottom: auto; + margin-top: auto; + background-color: #fff; + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzIzMjIyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTkgMy4xNzFhMS44MjkgMS44MjkgMCAwIDAtMS4yOTMuNTM2TDQuMzk1IDE3LjAxOWwtLjk3IDMuNTU2IDMuNTU2LS45N0wyMC4yOTMgNi4yOTNBMS44MjkgMS44MjkgMCAwIDAgMTkgMy4xN1ptLTEuNDY1LTEuNzA4YTMuODI5IDMuODI5IDAgMCAxIDQuMTcyIDYuMjQ0bC0xMy41IDEzLjVhMSAxIDAgMCAxLS40NDQuMjU4bC01LjUgMS41YTEgMSAwIDAgMS0xLjIyOC0xLjIyOGwxLjUtNS41YTEgMSAwIDAgMSAuMjU4LS40NDRsMTMuNS0xMy41YTMuODI5IDMuODI5IDAgMCAxIDEuMjQyLS44M1oiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==); + background-size: 14px; + background-repeat: no-repeat; + background-position: center; + border-radius: 100%; +} + .frontend-editing-toggle a.frontend-editing--enabled { background: rgb(var(--fe-editing-primary-color)); text-align: left; diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 2ca751e..0ce23de 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -35,7 +35,7 @@ class FrontendEditingHooks { ], '#wrapper_attributes' => [ 'class' => [ - 'toggle-toolbar-tab', + 'frontend-editing-toolbar-toggle', ], ], '#cache' => [ diff --git a/src/ToolbarItem.php b/src/ToolbarItem.php index 810a7b6..685c721 100644 --- a/src/ToolbarItem.php +++ b/src/ToolbarItem.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace Drupal\frontend_editing; -use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Html; use Drupal\Core\Render\ElementInfoManagerInterface; use Drupal\Core\Security\TrustedCallbackInterface; @@ -35,29 +34,32 @@ final class ToolbarItem implements TrustedCallbackInterface { * Render array. */ public function renderToggle(): array { + $toggle_state = \Drupal::service('user.data') + ->get('frontend_editing', \Drupal::currentUser()->id(), 'enabled'); + $build = [ - '#type' => 'checkbox', + '#type' => 'link', + '#url' => Url::fromRoute('frontend_editing.toggle'), '#cache' => [ 'context' => ['user.permissions'], ], - '#title' => t('Frontend Editing'), + '#title' => $toggle_state ? t('On') : t('Off'), '#id' => Html::getId('toolbar-item-toggle'), '#attributes' => [ - 'title' => t('Toggle'), - // 'class' => [ - // ], + 'title' => 'Enable frontend editing actions', + 'class' => [ + 'use-ajax', + 'frontend-editing-toggle-link', + ], + 'data-once' => "ajax", + 'data-toggle-state' => TRUE, ], - // '#attached' => [ - // 'library' => [ - // 'frontend_editing/drupal.frontend_editing.toolbar', - // ], - // ], ]; // The renderer has already added element defaults by the time the lazy // builder is run. // @see https://www.drupal.org/project/drupal/issues/2609250 - $build += $this->elementInfo->getInfo('checkbox'); + $build += $this->elementInfo->getInfo('link'); return $build; } -- GitLab From 9776c01e45702c0a74b77835e260c1cc23a7f204 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Thu, 17 Apr 2025 13:38:20 +0200 Subject: [PATCH 03/15] #3519238: add ajax to the tab and style it --- css/ui_toggle.css | 35 +++++++++++++++++--- src/Controller/FrontendEditingController.php | 9 +++++ src/ToolbarItem.php | 14 +++++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/css/ui_toggle.css b/css/ui_toggle.css index f9ef914..0c297e6 100644 --- a/css/ui_toggle.css +++ b/css/ui_toggle.css @@ -42,9 +42,9 @@ border-radius: 999px; box-shadow: rgba(0, 0, 0, 0.16) 0px 1px 4px; text-align: right; - height: 2rem; - padding-left: 2.5rem; + height: 1.9rem; margin-right: 1rem; + min-width: 5rem; } .frontend-editing-toolbar-toggle a { @@ -56,6 +56,25 @@ border-radius: 999px; } +/* Overrides undesired styles from gin. */ +.gin-secondary-toolbar .toolbar-secondary .toolbar-bar .toolbar-tab.frontend-editing-toolbar-toggle:focus-within { + border-radius: 999px; +} + +/* Overrides undesired styles from gin. */ +.gin-secondary-toolbar__layout-container a.frontend-editing-toolbar-toggle-link:focus { + box-shadow: none; +} + +a.frontend-editing-toolbar-toggle-link, a.frontend-editing-toggle-link, .toolbar-tab a.frontend-editing-toolbar-toggle-link:focus:not(:hover) { + text-decoration: none; +} + +.frontend-editing-toolbar-toggle-link:hover, .frontend-editing-toolbar-toggle-link:hover:focus, .frontend-editing-toggle-link:hover { + color: white; + text-decoration: underline; +} + .frontend-editing-toggle a::before { content: ' '; position: absolute; @@ -85,22 +104,28 @@ margin-bottom: auto; margin-top: auto; background-color: #fff; - background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzIzMjIyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTkgMy4xNzFhMS44MjkgMS44MjkgMCAwIDAtMS4yOTMuNTM2TDQuMzk1IDE3LjAxOWwtLjk3IDMuNTU2IDMuNTU2LS45N0wyMC4yOTMgNi4yOTNBMS44MjkgMS44MjkgMCAwIDAgMTkgMy4xN1ptLTEuNDY1LTEuNzA4YTMuODI5IDMuODI5IDAgMCAxIDQuMTcyIDYuMjQ0bC0xMy41IDEzLjVhMSAxIDAgMCAxLS40NDQuMjU4bC01LjUgMS41YTEgMSAwIDAgMS0xLjIyOC0xLjIyOGwxLjUtNS41YTEgMSAwIDAgMSAuMjU4LS40NDRsMTMuNS0xMy41YTMuODI5IDMuODI5IDAgMCAxIDEuMjQyLS44M1oiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==); + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzIzMjIyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTkgMy4xNzFhMS44MjkgMS44MjkgMCAwIDAtMS4yOTMuNTM2TDQuMzk1IDE3LjAxOWwtLjk3IDMuNTU2IDMuNTU2LS45N0wyMC4yOTMgNi4yOTNBMS44MjkgMS44MjkgMCAwIDAgMTkgMy4xN1ptLTEuNDY1LTEuNzA4YTMuODI5IDMuODI5IDAgMCAxIDQuMTcyIDYuMjQ0bC0xMy41IDEzLjVhMSAxIDAgMCAxLS40NDQuMjU4bC01LjUgMS41YTEgMSAwIDAgMS0xLjIyOC0xLjIyOGwxLjUtNS41YTEgMSAwIDAgMSAuMjU4LS40NDRsMTMuNS0xMy41YTMuODI5IDMuODI5IDAgMCAxIDEuMjQyLS44M1oiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=="); background-size: 14px; background-repeat: no-repeat; background-position: center; border-radius: 100%; } -.frontend-editing-toggle a.frontend-editing--enabled { +.frontend-editing-toggle a.frontend-editing--enabled, +.frontend-editing-toolbar-toggle:has(a.frontend-editing--enabled) +{ background: rgb(var(--fe-editing-primary-color)); text-align: left; } -.frontend-editing-toggle a.frontend-editing--enabled::before { +.frontend-editing-toggle a.frontend-editing--enabled::before{ left: calc(100% - 1.75rem - 0.5rem); } +.frontend-editing-toolbar-toggle a.frontend-editing--enabled::before { + left: calc(100% - 1.75rem - 0.25rem); +} + .frontend-editing-toggle-not-configured { box-shadow: 0 0 0 0 rgba(255, 0, 0, 1); transform: scale(1); diff --git a/src/Controller/FrontendEditingController.php b/src/Controller/FrontendEditingController.php index 6a76076..89acb29 100644 --- a/src/Controller/FrontendEditingController.php +++ b/src/Controller/FrontendEditingController.php @@ -122,13 +122,17 @@ class FrontendEditingController extends ControllerBase { if ($new_state) { $message = $this->t('Frontend editing has been enabled.'); $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'addClass', ['frontend-editing--enabled'])); + $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'addClass', ['frontend-editing--enabled'])); $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'text', [$this->t('On')])); + $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'text', [$this->t('On')])); $response->addCommand(new InvokeCommand('body', 'removeClass', ['frontend-editing--hidden'])); } else { $message = $this->t('Frontend editing has been disabled.'); $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'removeClass', ['frontend-editing--enabled'])); + $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'removeClass', ['frontend-editing--enabled'])); $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'text', [$this->t('Off')])); + $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'text', [$this->t('Off')])); $response->addCommand(new InvokeCommand('body', 'addClass', ['frontend-editing--hidden'])); } $response->addCommand(new MessageCommand($message, NULL, ['type' => 'status'])); @@ -136,7 +140,12 @@ class FrontendEditingController extends ControllerBase { 'data-toggle-state', $new_state, ])); + $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'attr', [ + 'data-toggle-state', + $new_state, + ])); $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'removeClass', ['frontend-editing-toggle-not-configured'])); + $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'removeClass', ['frontend-editing-toggle-not-configured'])); return $response; } diff --git a/src/ToolbarItem.php b/src/ToolbarItem.php index 685c721..74d8832 100644 --- a/src/ToolbarItem.php +++ b/src/ToolbarItem.php @@ -36,6 +36,7 @@ final class ToolbarItem implements TrustedCallbackInterface { public function renderToggle(): array { $toggle_state = \Drupal::service('user.data') ->get('frontend_editing', \Drupal::currentUser()->id(), 'enabled'); + $active_class = $toggle_state ? 'frontend-editing--enabled' : ''; $build = [ '#type' => 'link', @@ -44,15 +45,20 @@ final class ToolbarItem implements TrustedCallbackInterface { 'context' => ['user.permissions'], ], '#title' => $toggle_state ? t('On') : t('Off'), - '#id' => Html::getId('toolbar-item-toggle'), + '#id' => Html::getId('frontend-editing-toolbar-toggle-link'), '#attributes' => [ 'title' => 'Enable frontend editing actions', 'class' => [ 'use-ajax', - 'frontend-editing-toggle-link', + 'frontend-editing-toolbar-toggle-link', + $active_class, + ], + ], + '#attached' => [ + 'library' => [ + 'core/drupal.ajax', + 'frontend_editing/ui_toggle', ], - 'data-once' => "ajax", - 'data-toggle-state' => TRUE, ], ]; -- GitLab From cc08398fce9717b1ddf0f0598fdd1a3e3f865ef7 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Thu, 17 Apr 2025 14:12:40 +0200 Subject: [PATCH 04/15] #3519238: mobile styling --- css/ui_toggle.css | 20 ++++++++++++++++++++ src/Hook/FrontendEditingHooks.php | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/css/ui_toggle.css b/css/ui_toggle.css index 0c297e6..d14d50d 100644 --- a/css/ui_toggle.css +++ b/css/ui_toggle.css @@ -148,3 +148,23 @@ a.frontend-editing-toolbar-toggle-link, a.frontend-editing-toggle-link, .toolbar box-shadow: 0 0 0 0 rgba(255, 0, 0, 0); } } + +@media only screen and (max-width: 600px) { + .frontend-editing-toolbar-toggle { + margin-top: 0.25rem; + margin-right: 0; + } + + .frontend-editing-toolbar-toggle a::before { + left: auto; + right: 2.35rem; + } + + .frontend-editing-toolbar-toggle a.frontend-editing--enabled::before { + left: calc(100% - 1rem - 0.1rem); + } + + a.frontend-editing-toolbar-toggle-link { + position: relative; + } +} diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 0ce23de..f02d3ff 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -43,7 +43,7 @@ class FrontendEditingHooks { 'user.permissions', ], ], - '#weight' => -20, + '#weight' => -11, ]; // \Drupal\toolbar\Element\ToolbarItem::preRenderToolbarItem adds an // #attributes property to each toolbar item's tab child automatically. -- GitLab From 3fdfe0bee79ad1304728ee53269686457ad90c9d Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Thu, 17 Apr 2025 14:36:45 +0200 Subject: [PATCH 05/15] #3519238: show the tab only if the setting is not enabled --- src/Hook/FrontendEditingHooks.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index f02d3ff..3b98dee 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -19,6 +19,12 @@ class FrontendEditingHooks { if (!\Drupal::currentUser()->hasPermission('access frontend editing')) { return ['#cache' => ['contexts' => ['user.permissions']]]; } + + $config = \Drupal::config('frontend_editing.settings'); + if ($config->get('ui_toggle')) { + return []; + } + $items['toggle'] = [ '#type' => 'toolbar_item', 'tab' => [ -- GitLab From 2cd2332eaacebce27aa5cb8b43bdd6988a82cf7b Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Thu, 17 Apr 2025 14:48:45 +0200 Subject: [PATCH 06/15] #3519238: run code sniffer --- css/ui_toggle.css | 16 ++++++++-------- frontend_editing.module | 2 ++ src/Controller/FrontendEditingController.php | 1 - src/Controller/PreviewController.php | 4 ++-- src/Form/EntityReferenceAddForm.php | 2 +- src/Hook/FrontendEditingHooks.php | 1 - src/ToolbarItem.php | 1 + 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/css/ui_toggle.css b/css/ui_toggle.css index d14d50d..39367b1 100644 --- a/css/ui_toggle.css +++ b/css/ui_toggle.css @@ -51,26 +51,27 @@ color: white; } - /* Overrides undesired styles from gin. */ .gin-secondary-toolbar .toolbar-secondary .toolbar-bar .toolbar-tab.frontend-editing-toolbar-toggle:hover { border-radius: 999px; } -/* Overrides undesired styles from gin. */ .gin-secondary-toolbar .toolbar-secondary .toolbar-bar .toolbar-tab.frontend-editing-toolbar-toggle:focus-within { border-radius: 999px; } -/* Overrides undesired styles from gin. */ .gin-secondary-toolbar__layout-container a.frontend-editing-toolbar-toggle-link:focus { box-shadow: none; } -a.frontend-editing-toolbar-toggle-link, a.frontend-editing-toggle-link, .toolbar-tab a.frontend-editing-toolbar-toggle-link:focus:not(:hover) { +a.frontend-editing-toolbar-toggle-link, +a.frontend-editing-toggle-link, +.toolbar-tab a.frontend-editing-toolbar-toggle-link:focus:not(:hover) { text-decoration: none; } -.frontend-editing-toolbar-toggle-link:hover, .frontend-editing-toolbar-toggle-link:hover:focus, .frontend-editing-toggle-link:hover { +.frontend-editing-toolbar-toggle-link:hover, +.frontend-editing-toolbar-toggle-link:hover:focus, +.frontend-editing-toggle-link:hover { color: white; text-decoration: underline; } @@ -112,13 +113,12 @@ a.frontend-editing-toolbar-toggle-link, a.frontend-editing-toggle-link, .toolbar } .frontend-editing-toggle a.frontend-editing--enabled, -.frontend-editing-toolbar-toggle:has(a.frontend-editing--enabled) -{ +.frontend-editing-toolbar-toggle:has(a.frontend-editing--enabled) { background: rgb(var(--fe-editing-primary-color)); text-align: left; } -.frontend-editing-toggle a.frontend-editing--enabled::before{ +.frontend-editing-toggle a.frontend-editing--enabled::before { left: calc(100% - 1.75rem - 0.5rem); } diff --git a/frontend_editing.module b/frontend_editing.module index 1ee9a3e..52dd156 100644 --- a/frontend_editing.module +++ b/frontend_editing.module @@ -274,6 +274,7 @@ function frontend_editing_field_formatter_third_party_settings_form(FormatterInt } return $element; } + /** * Check formatter third party settings. */ @@ -289,6 +290,7 @@ function frontend_editing_check_third_party_formatter_settings(&$element) { } } } + /** * Implements hook_field_formatter_settings_summary_alter(). */ diff --git a/src/Controller/FrontendEditingController.php b/src/Controller/FrontendEditingController.php index 89acb29..79030c6 100644 --- a/src/Controller/FrontendEditingController.php +++ b/src/Controller/FrontendEditingController.php @@ -11,7 +11,6 @@ use Drupal\Core\Ajax\InvokeCommand; use Drupal\Core\Ajax\MessageCommand; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Entity\ContentEntityInterface; -use Drupal\Core\Entity\EntityFormBuilder; use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Render\Element; use Drupal\Core\Render\RendererInterface; diff --git a/src/Controller/PreviewController.php b/src/Controller/PreviewController.php index 41977a8..02423c4 100644 --- a/src/Controller/PreviewController.php +++ b/src/Controller/PreviewController.php @@ -34,7 +34,7 @@ class PreviewController extends PreviewControllerBase { /** * {@inheritdoc} */ - public function view(EntityInterface $entity_preview, $view_mode_id = 'default', $langcode = NULL, Request $request = NULL) { + public function view(EntityInterface $entity_preview, $view_mode_id = 'default', $langcode = NULL, ?Request $request = NULL) { $build = parent::view($entity_preview, $view_mode_id, $langcode); // In case it is ajax request, respond with ajax response. if ($request->isXmlHttpRequest()) { @@ -52,7 +52,7 @@ class PreviewController extends PreviewControllerBase { /** * {@inheritdoc} */ - public function nodeView(EntityInterface $node_preview, $view_mode_id = 'full', $langcode = NULL, Request $request = NULL) { + public function nodeView(EntityInterface $node_preview, $view_mode_id = 'full', $langcode = NULL, ?Request $request = NULL) { $build = parent::view($node_preview, $view_mode_id, $langcode); // In case it is ajax request, respond with ajax response. if ($request->isXmlHttpRequest()) { diff --git a/src/Form/EntityReferenceAddForm.php b/src/Form/EntityReferenceAddForm.php index 8a12b26..ea7cbf2 100644 --- a/src/Form/EntityReferenceAddForm.php +++ b/src/Form/EntityReferenceAddForm.php @@ -48,7 +48,7 @@ class EntityReferenceAddForm extends FormBase { /** * {@inheritdoc} */ - public function buildForm(array $form, FormStateInterface $form_state, FieldDefinitionInterface $field_definition = NULL) { + public function buildForm(array $form, FormStateInterface $form_state, ?FieldDefinitionInterface $field_definition = NULL) { if (!empty($field_definition)) { $settings = $field_definition->getSettings(); if ($settings['target_type'] == 'media' && $this->moduleHandler->moduleExists('media_library_form_element')) { diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 3b98dee..3bb4c0e 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -3,7 +3,6 @@ namespace Drupal\frontend_editing\Hook; use Drupal\Core\Hook\Attribute\Hook; -use Drupal\frontend_editing\RenderCallbacks; use Drupal\frontend_editing\ToolbarItem; /** diff --git a/src/ToolbarItem.php b/src/ToolbarItem.php index 74d8832..e1d7533 100644 --- a/src/ToolbarItem.php +++ b/src/ToolbarItem.php @@ -83,4 +83,5 @@ final class ToolbarItem implements TrustedCallbackInterface { unset($element['tab']['#attributes']); return $element; } + } -- GitLab From 5464a1a789b18ddbf35b627af3028bae4904506f Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Thu, 17 Apr 2025 15:00:16 +0200 Subject: [PATCH 07/15] #3519238: unify selector --- css/ui_toggle.css | 10 ++++------ src/Controller/FrontendEditingController.php | 21 ++++++-------------- src/ToolbarItem.php | 2 +- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/css/ui_toggle.css b/css/ui_toggle.css index 39367b1..613e24e 100644 --- a/css/ui_toggle.css +++ b/css/ui_toggle.css @@ -59,18 +59,16 @@ border-radius: 999px; } -.gin-secondary-toolbar__layout-container a.frontend-editing-toolbar-toggle-link:focus { +.gin-secondary-toolbar__layout-container a.frontend-editing-toggle-link:focus { box-shadow: none; } -a.frontend-editing-toolbar-toggle-link, a.frontend-editing-toggle-link, -.toolbar-tab a.frontend-editing-toolbar-toggle-link:focus:not(:hover) { +.toolbar-tab a.frontend-editing-toggle-link:focus:not(:hover) { text-decoration: none; } -.frontend-editing-toolbar-toggle-link:hover, -.frontend-editing-toolbar-toggle-link:hover:focus, +.frontend-editing-toggle-link:hover:focus, .frontend-editing-toggle-link:hover { color: white; text-decoration: underline; @@ -164,7 +162,7 @@ a.frontend-editing-toggle-link, left: calc(100% - 1rem - 0.1rem); } - a.frontend-editing-toolbar-toggle-link { + a.frontend-editing-toggle-link { position: relative; } } diff --git a/src/Controller/FrontendEditingController.php b/src/Controller/FrontendEditingController.php index 79030c6..9eb36e4 100644 --- a/src/Controller/FrontendEditingController.php +++ b/src/Controller/FrontendEditingController.php @@ -120,31 +120,22 @@ class FrontendEditingController extends ControllerBase { $response = new AjaxResponse(); if ($new_state) { $message = $this->t('Frontend editing has been enabled.'); - $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'addClass', ['frontend-editing--enabled'])); - $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'addClass', ['frontend-editing--enabled'])); - $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'text', [$this->t('On')])); - $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'text', [$this->t('On')])); + $response->addCommand(new InvokeCommand('.frontend-editing-toggle-link', 'addClass', ['frontend-editing--enabled'])); + $response->addCommand(new InvokeCommand('.frontend-editing-toggle-link', 'text', [$this->t('On')])); $response->addCommand(new InvokeCommand('body', 'removeClass', ['frontend-editing--hidden'])); } else { $message = $this->t('Frontend editing has been disabled.'); - $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'removeClass', ['frontend-editing--enabled'])); - $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'removeClass', ['frontend-editing--enabled'])); - $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'text', [$this->t('Off')])); - $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'text', [$this->t('Off')])); + $response->addCommand(new InvokeCommand('.frontend-editing-toggle-link', 'removeClass', ['frontend-editing--enabled'])); + $response->addCommand(new InvokeCommand('.frontend-editing-toggle-link', 'text', [$this->t('Off')])); $response->addCommand(new InvokeCommand('body', 'addClass', ['frontend-editing--hidden'])); } $response->addCommand(new MessageCommand($message, NULL, ['type' => 'status'])); - $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'attr', [ + $response->addCommand(new InvokeCommand('.frontend-editing-toggle-link', 'attr', [ 'data-toggle-state', $new_state, ])); - $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'attr', [ - 'data-toggle-state', - $new_state, - ])); - $response->addCommand(new InvokeCommand('#frontend-editing-toggle-link', 'removeClass', ['frontend-editing-toggle-not-configured'])); - $response->addCommand(new InvokeCommand('.frontend-editing-toolbar-toggle-link', 'removeClass', ['frontend-editing-toggle-not-configured'])); + $response->addCommand(new InvokeCommand('.frontend-editing-toggle-link', 'removeClass', ['frontend-editing-toggle-not-configured'])); return $response; } diff --git a/src/ToolbarItem.php b/src/ToolbarItem.php index e1d7533..ae5b76a 100644 --- a/src/ToolbarItem.php +++ b/src/ToolbarItem.php @@ -50,7 +50,7 @@ final class ToolbarItem implements TrustedCallbackInterface { 'title' => 'Enable frontend editing actions', 'class' => [ 'use-ajax', - 'frontend-editing-toolbar-toggle-link', + 'frontend-editing-toggle-link', $active_class, ], ], -- GitLab From deaf8027930fec0f0271a70fd433fa013e81c190 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Thu, 17 Apr 2025 15:12:33 +0200 Subject: [PATCH 08/15] #3519238: fix linting error --- src/Controller/FrontendEditingController.php | 2 ++ src/Hook/FrontendEditingHooks.php | 26 +++++++++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Controller/FrontendEditingController.php b/src/Controller/FrontendEditingController.php index 9eb36e4..b447d9f 100644 --- a/src/Controller/FrontendEditingController.php +++ b/src/Controller/FrontendEditingController.php @@ -78,6 +78,8 @@ class FrontendEditingController extends ControllerBase { * The user data storage. * @param \Drupal\frontend_editing\FieldReferenceHelperInterface $field_reference_helper * The field reference helper. + * @param \Drupal\frontend_editing\FrontendEditingFormBuilderInterface $frontend_editing_form_builder + * The frontend editing form builder. */ public function __construct(RendererInterface $renderer, EntityRepositoryInterface $entity_repository, UserDataInterface $userData, FieldReferenceHelperInterface $field_reference_helper, FrontendEditingFormBuilderInterface $frontend_editing_form_builder) { $this->renderer = $renderer; diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 3bb4c0e..53bee03 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -2,24 +2,42 @@ namespace Drupal\frontend_editing\Hook; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\Session\AccountProxyInterface; use Drupal\frontend_editing\ToolbarItem; +use Symfony\Component\DependencyInjection\Attribute\Autowire; /** * Hook implementations for frontend_editing. */ class FrontendEditingHooks { + /** + * Constructs FrontendEditing hooks. + * + * @param \Drupal\Core\Session\AccountProxyInterface $currentUser + * The current user. + * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory + * The config factory object. + */ + public function __construct( + #[Autowire(service: 'current_user')] + protected AccountProxyInterface $currentUser, + #[Autowire(service: 'config.factory')] + protected ConfigFactoryInterface $configFactory, + ) {} + /** * Implements hook_toolbar(). */ #[Hook('toolbar')] public function toolbar() { - if (!\Drupal::currentUser()->hasPermission('access frontend editing')) { + if (!$this->currentUser->hasPermission('access frontend editing')) { return ['#cache' => ['contexts' => ['user.permissions']]]; } - $config = \Drupal::config('frontend_editing.settings'); + $config = $this->configFactory->get('frontend_editing.settings'); if ($config->get('ui_toggle')) { return []; } @@ -53,8 +71,8 @@ class FrontendEditingHooks { // \Drupal\toolbar\Element\ToolbarItem::preRenderToolbarItem adds an // #attributes property to each toolbar item's tab child automatically. // Lazy builders don't support an #attributes property so we need to - // add another render callback to remove the #attributes property. We start by - // adding the defaults, and then we append our own pre render callback. + // add another render callback to remove the #attributes property. We start + // by adding the defaults, and then we append our own pre render callback. $items['toggle'] += \Drupal::service('plugin.manager.element_info')->getInfo('toolbar_item'); $items['toggle']['#pre_render'][] = [ToolbarItem::class, 'removeTabAttributes']; return $items; -- GitLab From 4a3407c1611cd827d4230d32244441bf61da6311 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Thu, 17 Apr 2025 15:21:25 +0200 Subject: [PATCH 09/15] #3519238: hode on admin route --- src/Hook/FrontendEditingHooks.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 53bee03..5418b7e 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -4,6 +4,7 @@ namespace Drupal\frontend_editing\Hook; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\Routing\AdminContext; use Drupal\Core\Session\AccountProxyInterface; use Drupal\frontend_editing\ToolbarItem; use Symfony\Component\DependencyInjection\Attribute\Autowire; @@ -26,6 +27,8 @@ class FrontendEditingHooks { protected AccountProxyInterface $currentUser, #[Autowire(service: 'config.factory')] protected ConfigFactoryInterface $configFactory, + #[Autowire(service: 'router.admin_context')] + protected AdminContext $adminContext, ) {} /** @@ -38,7 +41,7 @@ class FrontendEditingHooks { } $config = $this->configFactory->get('frontend_editing.settings'); - if ($config->get('ui_toggle')) { + if ($config->get('ui_toggle') || $this->adminContext->isAdminRoute()) { return []; } -- GitLab From 5ee7dfa05cddc363067d98d794f52edc7140dac6 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Fri, 18 Apr 2025 09:51:31 +0200 Subject: [PATCH 10/15] #3519238: fix css for mobile --- css/ui_toggle.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/ui_toggle.css b/css/ui_toggle.css index 613e24e..3d44375 100644 --- a/css/ui_toggle.css +++ b/css/ui_toggle.css @@ -147,7 +147,7 @@ a.frontend-editing-toggle-link, } } -@media only screen and (max-width: 600px) { +@media only screen and (max-width: 975px) { .frontend-editing-toolbar-toggle { margin-top: 0.25rem; margin-right: 0; -- GitLab From 337a2d3f59c78c7e8b6483c1c70602b4b1876421 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Fri, 18 Apr 2025 09:57:13 +0200 Subject: [PATCH 11/15] #3519238: add legacy hook for < 10.4 --- frontend_editing.module | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/frontend_editing.module b/frontend_editing.module index 52dd156..8914538 100644 --- a/frontend_editing.module +++ b/frontend_editing.module @@ -17,6 +17,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\RevisionableInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FormatterInterface; +use Drupal\Core\Field\WidgetInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element; use Drupal\Core\Render\Markup; @@ -25,6 +26,7 @@ use Drupal\Core\Url; use Drupal\frontend_editing\Ajax\CloseSidePanelCommand; use Drupal\frontend_editing\Ajax\EntityPreviewCommand; use Drupal\frontend_editing\Ajax\ScrollTopCommand; +use Drupal\frontend_editing\Hook\FrontendEditingHooks; use Drupal\node\NodeInterface; /** @@ -804,3 +806,11 @@ function frontend_editing_preprocess_page_title(&$variables) { } } } + +/** + * Implements field_widget_third_party_settings_form(). + */ +#[LegacyHook] +function frontend_editing_field_widget_third_party_settings_form(WidgetInterface $plugin, FieldDefinitionInterface $field_definition, $form_mode, array $form, FormStateInterface $form_state) { + return \Drupal::service(FrontendEditingHooks::class)->fieldWidgetThirdPartySettingsForm($plugin, $field_definition, $form_mode, $form, $form_state); +} -- GitLab From 10a68d7ea647246c01606f012d8b61fd06b11595 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Fri, 18 Apr 2025 11:07:35 +0200 Subject: [PATCH 12/15] #3519238: fix legacy hook and clean code --- frontend_editing.module | 8 ++++---- frontend_editing.services.yml | 5 ++++- src/Hook/FrontendEditingHooks.php | 9 ++++++++- src/ToolbarItem.php | 23 ++++++++++++++++++----- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/frontend_editing.module b/frontend_editing.module index 8914538..f55ebee 100644 --- a/frontend_editing.module +++ b/frontend_editing.module @@ -17,8 +17,8 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\RevisionableInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FormatterInterface; -use Drupal\Core\Field\WidgetInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Hook\Attribute\LegacyHook; use Drupal\Core\Render\Element; use Drupal\Core\Render\Markup; use Drupal\Core\Routing\RouteMatchInterface; @@ -808,9 +808,9 @@ function frontend_editing_preprocess_page_title(&$variables) { } /** - * Implements field_widget_third_party_settings_form(). + * Implements hook_toolbar(). */ #[LegacyHook] -function frontend_editing_field_widget_third_party_settings_form(WidgetInterface $plugin, FieldDefinitionInterface $field_definition, $form_mode, array $form, FormStateInterface $form_state) { - return \Drupal::service(FrontendEditingHooks::class)->fieldWidgetThirdPartySettingsForm($plugin, $field_definition, $form_mode, $form, $form_state); +function frontend_editing_toolbar() { + return \Drupal::service(FrontendEditingHooks::class)->toolbar(); } diff --git a/frontend_editing.services.yml b/frontend_editing.services.yml index 2a6c136..159ff00 100644 --- a/frontend_editing.services.yml +++ b/frontend_editing.services.yml @@ -11,5 +11,8 @@ services: arguments: ['@entity_type.manager', '@entity.form_builder', '@form_builder'] frontend_editing.toolbar_item: class: Drupal\frontend_editing\ToolbarItem - arguments: [ '@plugin.manager.element_info' ] + arguments: [ '@plugin.manager.element_info', '@user.data', '@current_user' ] Drupal\frontend_editing\ToolbarItem: '@frontend_editing.toolbar_item' + Drupal\frontend_editing\Hook\FrontendEditingHooks: + class: Drupal\frontend_editing\Hook\FrontendEditingHooks + autowire: true diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 5418b7e..45bf521 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -4,6 +4,7 @@ namespace Drupal\frontend_editing\Hook; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Hook\Attribute\Hook; +use Drupal\Core\Render\ElementInfoManager; use Drupal\Core\Routing\AdminContext; use Drupal\Core\Session\AccountProxyInterface; use Drupal\frontend_editing\ToolbarItem; @@ -21,6 +22,10 @@ class FrontendEditingHooks { * The current user. * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * The config factory object. + * @param \Drupal\Core\Routing\AdminContext $adminContext + * The admin context. + * @param \Drupal\Core\Render\ElementInfoManager $elementInfoManager + * The element info manager. */ public function __construct( #[Autowire(service: 'current_user')] @@ -29,6 +34,8 @@ class FrontendEditingHooks { protected ConfigFactoryInterface $configFactory, #[Autowire(service: 'router.admin_context')] protected AdminContext $adminContext, + #[Autowire(service: 'plugin.manager.element_info')] + protected ElementInfoManager $elementInfoManager, ) {} /** @@ -76,7 +83,7 @@ class FrontendEditingHooks { // Lazy builders don't support an #attributes property so we need to // add another render callback to remove the #attributes property. We start // by adding the defaults, and then we append our own pre render callback. - $items['toggle'] += \Drupal::service('plugin.manager.element_info')->getInfo('toolbar_item'); + $items['toggle'] += $this->elementInfoManager->getInfo('toolbar_item'); $items['toggle']['#pre_render'][] = [ToolbarItem::class, 'removeTabAttributes']; return $items; } diff --git a/src/ToolbarItem.php b/src/ToolbarItem.php index ae5b76a..f33cbee 100644 --- a/src/ToolbarItem.php +++ b/src/ToolbarItem.php @@ -7,7 +7,10 @@ namespace Drupal\frontend_editing; use Drupal\Component\Utility\Html; use Drupal\Core\Render\ElementInfoManagerInterface; use Drupal\Core\Security\TrustedCallbackInterface; +use Drupal\Core\Session\AccountProxyInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; +use Drupal\user\UserDataInterface; /** * Defines a class for lazy building render arrays. @@ -16,16 +19,23 @@ use Drupal\Core\Url; */ final class ToolbarItem implements TrustedCallbackInterface { + use StringTranslationTrait; + /** * Constructs LazyBuilders object. * * @param \Drupal\Core\Render\ElementInfoManagerInterface $elementInfo * Element info. + * @param \Drupal\user\UserDataInterface $userData + * The user data. + * @param \Drupal\Core\Session\AccountProxyInterface $currentUser + * The current user. */ public function __construct( protected ElementInfoManagerInterface $elementInfo, - ) { - } + protected UserDataInterface $userData, + protected AccountProxyInterface $currentUser, + ) {} /** * Render announcements. @@ -34,8 +44,11 @@ final class ToolbarItem implements TrustedCallbackInterface { * Render array. */ public function renderToggle(): array { - $toggle_state = \Drupal::service('user.data') - ->get('frontend_editing', \Drupal::currentUser()->id(), 'enabled'); + $toggle_state = $this->userData->get( + 'frontend_editing', + $this->currentUser->id(), + 'enabled' + ); $active_class = $toggle_state ? 'frontend-editing--enabled' : ''; $build = [ @@ -44,7 +57,7 @@ final class ToolbarItem implements TrustedCallbackInterface { '#cache' => [ 'context' => ['user.permissions'], ], - '#title' => $toggle_state ? t('On') : t('Off'), + '#title' => $toggle_state ? $this->t('On') : $this->t('Off'), '#id' => Html::getId('frontend-editing-toolbar-toggle-link'), '#attributes' => [ 'title' => 'Enable frontend editing actions', -- GitLab From 16d9a911d49676b049e3de29297d50d27b0c11d4 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Sat, 19 Apr 2025 19:51:03 +0200 Subject: [PATCH 13/15] #3519238: translate title --- src/ToolbarItem.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ToolbarItem.php b/src/ToolbarItem.php index f33cbee..e9320ab 100644 --- a/src/ToolbarItem.php +++ b/src/ToolbarItem.php @@ -60,7 +60,7 @@ final class ToolbarItem implements TrustedCallbackInterface { '#title' => $toggle_state ? $this->t('On') : $this->t('Off'), '#id' => Html::getId('frontend-editing-toolbar-toggle-link'), '#attributes' => [ - 'title' => 'Enable frontend editing actions', + 'title' => $this->t('Enable frontend editing actions'), 'class' => [ 'use-ajax', 'frontend-editing-toggle-link', -- GitLab From f860df481caa6691a6a7a6cad9fb7429f2425804 Mon Sep 17 00:00:00 2001 From: Alejandro Ortega <a.ortega@1xinternet.de> Date: Sat, 19 Apr 2025 19:51:11 +0200 Subject: [PATCH 14/15] #3519238: return config metadata --- src/Hook/FrontendEditingHooks.php | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 45bf521..81fb52b 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -44,12 +44,22 @@ class FrontendEditingHooks { #[Hook('toolbar')] public function toolbar() { if (!$this->currentUser->hasPermission('access frontend editing')) { - return ['#cache' => ['contexts' => ['user.permissions']]]; + return [ + '#cache' => [ + 'contexts' => ['user.permissions'], + ], + ]; } $config = $this->configFactory->get('frontend_editing.settings'); - if ($config->get('ui_toggle') || $this->adminContext->isAdminRoute()) { - return []; + $ui_toggle_enabled = $config->get('ui_toggle'); + if ($ui_toggle_enabled || $this->adminContext->isAdminRoute()) { + return [ + '#cache' => [ + 'contexts' => ['user.permissions'], + 'tags' => $config->getCacheTags(), + ], + ]; } $items['toggle'] = [ @@ -72,9 +82,8 @@ class FrontendEditingHooks { ], ], '#cache' => [ - 'contexts' => [ - 'user.permissions', - ], + 'contexts' => ['user.permissions'], + 'tags' => $config->getCacheTags(), ], '#weight' => -11, ]; -- GitLab From 358a1f3595202a545f11bb56e5fa29a3c52b8532 Mon Sep 17 00:00:00 2001 From: Artem Dmitriiev <a.dmitriiev@1xinternet.de> Date: Mon, 21 Apr 2025 09:58:46 +0200 Subject: [PATCH 15/15] Take into account caching --- src/Hook/FrontendEditingHooks.php | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/Hook/FrontendEditingHooks.php b/src/Hook/FrontendEditingHooks.php index 81fb52b..c991559 100644 --- a/src/Hook/FrontendEditingHooks.php +++ b/src/Hook/FrontendEditingHooks.php @@ -2,6 +2,7 @@ namespace Drupal\frontend_editing\Hook; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Hook\Attribute\Hook; use Drupal\Core\Render\ElementInfoManager; @@ -43,23 +44,21 @@ class FrontendEditingHooks { */ #[Hook('toolbar')] public function toolbar() { + $items = []; + $cache_metadata = new CacheableMetadata(); + $cache_metadata->addCacheContexts(['user.permissions']); if (!$this->currentUser->hasPermission('access frontend editing')) { - return [ - '#cache' => [ - 'contexts' => ['user.permissions'], - ], - ]; + $cache_metadata->applyTo($items); + return $items; } $config = $this->configFactory->get('frontend_editing.settings'); + $cache_metadata->addCacheableDependency($config); + $cache_metadata->addCacheContexts(['route']); $ui_toggle_enabled = $config->get('ui_toggle'); if ($ui_toggle_enabled || $this->adminContext->isAdminRoute()) { - return [ - '#cache' => [ - 'contexts' => ['user.permissions'], - 'tags' => $config->getCacheTags(), - ], - ]; + $cache_metadata->applyTo($items); + return $items; } $items['toggle'] = [ @@ -81,10 +80,6 @@ class FrontendEditingHooks { 'frontend-editing-toolbar-toggle', ], ], - '#cache' => [ - 'contexts' => ['user.permissions'], - 'tags' => $config->getCacheTags(), - ], '#weight' => -11, ]; // \Drupal\toolbar\Element\ToolbarItem::preRenderToolbarItem adds an @@ -94,6 +89,7 @@ class FrontendEditingHooks { // by adding the defaults, and then we append our own pre render callback. $items['toggle'] += $this->elementInfoManager->getInfo('toolbar_item'); $items['toggle']['#pre_render'][] = [ToolbarItem::class, 'removeTabAttributes']; + $cache_metadata->applyTo($items); return $items; } -- GitLab