Affiche les messages Drupal par-dessus les fenêtres modales
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 <body>), 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 <body> 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).
This commit is contained in:
@@ -69,7 +69,14 @@ html.gin--dark-mode .figli-page-nav a.is-active {
|
|||||||
([data-drupal-messages-fallback], used when Drupal.Message.add() -- our
|
([data-drupal-messages-fallback], used when Drupal.Message.add() -- our
|
||||||
own MessageCommand-driven AJAX messages included -- has no region to
|
own MessageCommand-driven AJAX messages included -- has no region to
|
||||||
attach to). Auto-dismiss timing for non-error messages is handled in
|
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 <body> 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],
|
||||||
[data-drupal-messages-fallback] {
|
[data-drupal-messages-fallback] {
|
||||||
position: fixed !important;
|
position: fixed !important;
|
||||||
@@ -78,7 +85,7 @@ html.gin--dark-mode .figli-page-nav a.is-active {
|
|||||||
left: auto !important;
|
left: auto !important;
|
||||||
width: auto;
|
width: auto;
|
||||||
max-width: 22rem;
|
max-width: 22rem;
|
||||||
z-index: 1000;
|
z-index: 100000;
|
||||||
}
|
}
|
||||||
[data-drupal-messages] .messages-list__wrapper,
|
[data-drupal-messages] .messages-list__wrapper,
|
||||||
[data-drupal-messages] .messages__wrapper,
|
[data-drupal-messages] .messages__wrapper,
|
||||||
|
|||||||
@@ -39,7 +39,32 @@
|
|||||||
root.querySelectorAll('.messages-list__item').forEach(handleMessage);
|
root.querySelectorAll('.messages-list__item').forEach(handleMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lifts the [data-drupal-messages] region to a direct <body> 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
|
||||||
|
* <body> 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 <body> 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() {
|
function init() {
|
||||||
|
liftMessages();
|
||||||
scan(document);
|
scan(document);
|
||||||
new MutationObserver(function (mutations) {
|
new MutationObserver(function (mutations) {
|
||||||
mutations.forEach(function (mutation) {
|
mutations.forEach(function (mutation) {
|
||||||
@@ -48,6 +73,16 @@
|
|||||||
if (node.classList && node.classList.contains('messages-list__item')) {
|
if (node.classList && node.classList.contains('messages-list__item')) {
|
||||||
handleMessage(node);
|
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) {
|
if (node.querySelectorAll) {
|
||||||
scan(node);
|
scan(node);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user