Correctifs RGAA - Menu principal


Cette page ne doit être appliquée que si le script de migration assistée vous demande de passer la migration manuelle skin.20240717.INTRANETSEARCH.rgaa.mainmenu

La navigation principale a été revue pour une meilleure navigation au clavier en mode mobile et pour une meilleur compréhension des menus de navigation par les technologies d'assistance.

Voici ci-après les modifications apportées et à reporter si les templates XSL concernés ont été surchargés

  1. Template "header-left"
  2. Template "header-icons"
  3. Template "user-menu"
  4. Gestion du bouton "Retour" dans le menu principal en mode mobile

Template "header-left"

L'élément <nav class="left" role="navigation" aria-label="Navigation principale"> contenant le logo et le menu principal en mode desktop est maintenant caché en mobile (< 1400px)
Un élément <div class="left mobile"> contenant uniquement le logo a été rajouté et est visible uniquement en mode mobile.

<xsl:template name="header-left">
        <nav class="left" role="navigation" aria-label="skin.{$skin}:SKIN_NAV_MAIN_NAVIGATION" i18n:attr="aria-label">
            <!-- Logo -->
            <xsl:call-template name="header-main-logo"/>
            
            <xsl:call-template name="main-menu">
                <xsl:with-param name="device">desktop</xsl:with-param>
            </xsl:call-template>
        </nav>
            
        <!-- For mobile -->
        <div class="left mobile">
            <xsl:call-template name="header-main-logo"/>    
        </div>
    </xsl:template>

Template "header-icons"

L'élément <nav role="navigation" aria-label="Menu secondaire" class="icons"> a été remplacé par un <div class="icons">.
En effet les icones de notifications ne sont pas des éléments de navigation dans le site mais généralement des liens externes.

Le bouton "burger" permettant d'ouvrir le menu principal en mode mobile, est maintenant entouré d'un élément <nav role="navigation" aria-label="Menu utilisateur">

<xsl:template name="header-icons">
        <div class="icons">
            <ul>
                <xsl:call-template name="search-button"/>
                
                <xsl:call-template name="top-links"/>
                <xsl:call-template name="alerts"/>
                
                <!-- User menu -->
                <xsl:call-template name="user-menu"/>
                
                <li class="burger">
                    <nav role="navigation" aria-label="skin.{$skin}:SKIN_NAV_MAIN_NAVIGATION" i18n:attr="aria-label">
                        <button aria-haspopup="dialog" aria-label="skin.{$skin}:SKIN_NAV_MAIN_NAVIGATION_MENU" i18n:attr="aria-label" onclick="openMenuMobile(this)"><i aria-hidden="true" class="fas fa-bars"></i></button>
                    </nav>
                </li>
            </ul>
        </div>
  </xsl:template>

Template "user-menu"

Le menu utilisateur est maintenant entouré d'un élément <nav role="navigation" aria-label="Menu utilisateur">.
De plus, les scripts lié à l'ouverture/fermeture du menu utilisateur a été revu pour une meilleure navigation au clavier et pour supporter la fermeture du menu via la touche ECHAP

<xsl:template name="user-menu">
        <xsl:if test="$currentUser/user/login">
            <li class="profil" style="display: none">
                <nav role="navigation" aria-label="skin.{$skin}:SKIN_NAV_USER_MENU" i18n:attr="aria-label">
                   [...]   
                   <xsl:call-template name="profil-img"/> 
                </nav>
            </li>
      </xsl:if>
      <script type="text/javascript">
            const closeUserMenuOnEscape = (event) => {
                if (event.key === "Escape") {
                    var $openUserMenu = $j("header .icons .profil .dropdown.openAccessibility");
                    $openUserMenu.removeClass('openAccessibility');
                    $openUserMenu.prev().attr("aria-expanded", "false");
                    $openUserMenu.prev().focus();
                }
            }
    
            function openUserMenuOnClick(el)
            {
                var isOpen = $j(el).next(".dropdown").is(':visible');
                if(!isOpen) {
                    // Open menu
                    $j(el).next(".dropdown").addClass('openAccessibility');
                    $j(el).attr("aria-expanded", "true");
                    $j(el).next(".dropdown").find('ul > li a').first().focus();
                    $j(el).closest('li').get(0).addEventListener('keydown', closeUserMenuOnEscape);
                }  else {
                    // Close menu
                    $j(el).next(".dropdown").removeClass('openAccessibility');
                    $j(el).attr("aria-expanded", "false");
                    $j(el).closest('li').get(0).removeEventListener('keydown', closeUserMenuOnEscape);
                }
            }
            
            $j(".icons ul li.profil").mouseenter(function (el) {
                // Show user menu
                var $dropdown = $j(this).find(".dropdown");
                if (!$dropdown.is(':visible'))
                {
                    $dropdown.addClass("openAccessibility");
                    $j(this).find('> button').attr("aria-expanded", true);
                }
            });
            
            $j(".icons ul li.profil").mouseleave(function (el) {
                // Hide user menu 
                var $dropdown = $j(this).find(".dropdown");
                if ($dropdown.is(':visible'))
                {
                    $dropdown.removeClass("openAccessibility");
                    $j(this).find('> button').attr("aria-expanded", false);
                }
            });
            
            $j(document).ready(function() {
                var _getAmetysUserCb = function(user)
                {
                    if (user)
                    {
                        $j('.profil').show();
                    }
                    else
                    {
                        $j('.profil').hide();
                    }
                }
                
                getAmetysUser(_getAmetysUserCb);
            });
        </script>
</xsl:template>

Gestion du bouton "Retour" dans le menu principal en mode mobile

Pour une meilleure navigation clavier en mode mobile dans le menu principal, le positionnement du bouton "Retour" a été revue.

Cette modification impacte plusieurs templates XSL.

Dans le template "menu-mobile", l'appel au template "menu-mobile-back" a été supprimé.
Par ailleurs, les attributs role et aria-label ont été rajoutés

<xsl:template name="menu-mobile">
        <div class="menu-mobile" role="dialog" aria-label="skin.{$skin}:SKIN_NAV_MAIN_MENU" i18n:attr="aria-label">
            <xsl:call-template name="menu-mobile-close"/>
            <xsl:call-template name="menu-mobile-logo"/>
            <xsl:call-template name="main-menu-mobile"/>
            <div class="access-mobile"></div>
        </div>
    </xsl:template>

Dans le template "submenu-mobile-levels",  les éléments <ul class="submenu"> deviennent des <div class="submenu"> contenant le <ul><li> de la liste des pages et un bouton "Retour"

<xsl:template name="submenu-mobile-levels">
        <xsl:if test="page[(not(@sitemap:invisible) or @sitemap:invisible = 'false')]">
            
            <div class="submenu">
                 <xsl:call-template name="menu-mobile-back"/>
                 
                 <ul>
                    <li class="title">
                        <a href="{resolver:resolve('page', @sitemap:id)}">
                            <xsl:value-of select="@sitemap:title" />
                        </a>
                    </li>
                    
                    <xsl:apply-templates select="page[not(@sitemap:invisible) or @sitemap:invisible = 'false']" mode="level-mobile"/>
                </ul>
            </div>
        </xsl:if>
    </xsl:template>

Modification similaire pour le template <xsl:template match="page" mode="level-mobile">

<xsl:template match="page" mode="level-mobile">
        <li>
            <xsl:attribute name="class"><xsl:if test="page[not(@sitemap:invisible) or @sitemap:invisible = 'false']">has-submenu</xsl:if></xsl:attribute>
            
            <a href="{resolver:resolve('page', @sitemap:id)}">
                <xsl:if test="@sitemap:type = 'LINK' and @sitemap:link-type = 'WEB'">
                    <xsl:call-template name="external-link-attributes"/>
                </xsl:if>
                <span><xsl:value-of select="@sitemap:title" /></span>
            </a>
            <xsl:if test="page[not(@sitemap:invisible) or @sitemap:invisible = 'false']">
                <button aria-label="{@sitemap:title}" aria-expanded="false" class="open-submenu-sr">
                    <i class="fas fa-angle-right" aria-hidden="true"></i>
                </button>
            </xsl:if>
            
            <xsl:if test="page[not(@sitemap:invisible) or @sitemap:invisible = 'false']">
                <div class="submenu">
                    <xsl:call-template name="menu-mobile-back"/>
                 
                    <ul>
                        <xsl:apply-templates select="page[not(@sitemap:invisible) or @sitemap:invisible = 'false']" mode="level-mobile"/>
                    </ul>
                </div>
            </xsl:if>
        </li>
    </xsl:template>

Dans le template "menu-mobile-back", l'action JS au clic sur le bouton "Retour" attend le bouton en 1er argument.

<xsl:template name="menu-mobile-back">
        <button 
            aria-label="skin.{$skin}:SKIN_NAV_MENU_MOBILE_BACK"
            i18n:attr="aria-label"
            class="return" 
            onclick="closeLevel(this)">
            <i class="fas fa-arrow-left" aria-hidden="true"></i>
        </button>
</xsl:template>
Retour en haut