From 3688bddba895179e2d6d5d2563ec7c9c89d77df2 Mon Sep 17 00:00:00 2001 From: bach Date: Wed, 9 Sep 2026 12:59:37 +0200 Subject: [PATCH] =?UTF-8?q?Affiche=20les=20messages=20Drupal=20par-dessus?= =?UTF-8?q?=20les=20fen=C3=AAtres=20modales?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La région [data-drupal-messages] vit dans le layout Gin, où des stacking contexts ancêtres neutralisaient son position:fixed + z-index : tout le sous-arbre passait sous l'overlay de la modale jQuery UI (enfant direct du ), rendant illisibles les messages insérés pendant l'édition d'une ligne (MessageCommand -- erreur de répartition, création...). admin-chrome.js déplace la région en enfant direct du au chargement et la re-vérifie dès qu'une modale entre dans le DOM ; admin-chrome.css passe son z-index à 100000, hors d'atteinte du _moveToTop de jQuery UI (qui ne remonte un dialog que au-dessus des siblings .ui-front, ce que la région n'est pas). --- .../figli_compta_ledger/css/admin-chrome.css | 11 ++++-- .../figli_compta_ledger/js/admin-chrome.js | 35 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/web/modules/custom/figli_compta_ledger/css/admin-chrome.css b/web/modules/custom/figli_compta_ledger/css/admin-chrome.css index e64604a..c32534c 100644 --- a/web/modules/custom/figli_compta_ledger/css/admin-chrome.css +++ b/web/modules/custom/figli_compta_ledger/css/admin-chrome.css @@ -69,7 +69,14 @@ html.gin--dark-mode .figli-page-nav a.is-active { ([data-drupal-messages-fallback], used when Drupal.Message.add() -- our own MessageCommand-driven AJAX messages included -- has no region to attach to). Auto-dismiss timing for non-error messages is handled in - admin-chrome.js. */ + admin-chrome.js. + z-index 100000: the region is lifted to a direct child by + admin-chrome.js (Gin's layout stacking contexts would otherwise bury + it under the modal overlay), and 100000 puts it above the jQuery UI + dialog itself (~100, .ui-front) and its overlay (dialog - 1) -- and + unreachable: jQuery UI only ever raises a dialog above .ui-front + siblings (_moveToTop), which the messages wrapper is not. Messages + stay readable on top of everything while a modal is open. */ [data-drupal-messages], [data-drupal-messages-fallback] { position: fixed !important; @@ -78,7 +85,7 @@ html.gin--dark-mode .figli-page-nav a.is-active { left: auto !important; width: auto; max-width: 22rem; - z-index: 1000; + z-index: 100000; } [data-drupal-messages] .messages-list__wrapper, [data-drupal-messages] .messages__wrapper, diff --git a/web/modules/custom/figli_compta_ledger/js/admin-chrome.js b/web/modules/custom/figli_compta_ledger/js/admin-chrome.js index 2d56da8..7702fa5 100644 --- a/web/modules/custom/figli_compta_ledger/js/admin-chrome.js +++ b/web/modules/custom/figli_compta_ledger/js/admin-chrome.js @@ -39,7 +39,32 @@ root.querySelectorAll('.messages-list__item').forEach(handleMessage); } + /** + * Lifts the [data-drupal-messages] region to a direct child. + * + * Gin renders it deep inside its layout (main.page-content > region + * highlighted), where ancestor stacking contexts neutralize the + * region's position:fixed + high z-index (admin-chrome.css): the whole + * subtree then stacks below the jQuery UI modal overlay -- a direct + * child -- which is why messages inserted while a modal is open + * (MessageCommand-driven, e.g. the répartition-sum error on the + * ligne_comptable modal form) rendered unreadably *under* the overlay. + * As a child, the region's z-index competes directly with the + * overlay/dialog and wins. Core itself puts the fallback wrapper at + * body level (Drupal.Message.defaultWrapper(), misc/message.js), so + * this is also where messages already land on a page without the + * region; MessageCommand re-queries the region at response time, so + * moving it after page load breaks no insertion path. + */ + function liftMessages() { + var region = document.querySelector('[data-drupal-messages]'); + if (region && region.parentElement !== document.body) { + document.body.appendChild(region); + } + } + function init() { + liftMessages(); scan(document); new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { @@ -48,6 +73,16 @@ if (node.classList && node.classList.contains('messages-list__item')) { handleMessage(node); } + // A modal (or a re-rendered messages region) entering the DOM: + // re-check the lift right when it matters -- the region must + // already be body-level when the dialog's overlay and any + // MessageCommand insertions show up. matches() first because + // querySelector() never matches the node itself. liftMessages() + // is idempotent, so over-triggering is harmless. + if (node.matches('.ui-dialog, [data-drupal-messages]') + || node.querySelector('.ui-dialog, [data-drupal-messages]')) { + liftMessages(); + } if (node.querySelectorAll) { scan(node); }