Изменения документа Menu Macro
Редактировал(а) Coluns 14.06.2024
Сводка
-
Объекты (3 изменено, 1 добавлено, 0 удалено)
Подробности
- XWiki.JavaScriptExtension[0]
-
- Код
-
... ... @@ -1,26 +1,85 @@ 1 -require(['jquery'], function($) { 1 +define('menu-ui-translation-keys', { 2 + prefix: 'menu.ui.', 3 + keys: [ 4 + "openSubMenu", 5 + "closeSubMenu" 6 + ] 7 +}); 8 +require(['jquery','xwiki-l10n!menu-ui-translation-keys'], function($, l10n) { 2 2 // It's not possible to write a CSS selector that targets list items containing lists so we rely on JavaScript. 3 3 // The 'dropdown' CSS class is used only to display the down/left arrow. 4 - $('.menu-horizontal li ul').parent().addClass('xDropdown'); 5 - 11 + // All nodes on the tree. 12 + $('.menu-horizontal ul , .menu-vertical ul') 13 + .attr('role', 'menu'); 14 + // All leaves on the tree. 15 + $('.menu-horizontal li, .menu-vertical li') 16 + .attr('role', 'menuitem'); 17 + $('.menu-horizontal li ul, .menu-vertical li ul') 18 + .parent() 19 + .addClass('xDropdown'); 6 6 // Make sure the menu separators are really empty. 7 - $('.menu-horizontal, .menu-vertical').find('li > br:first-child').remove(); 21 + var menus = $('.menu-horizontal, .menu-vertical'); 22 + menus.find('li > br:first-child').remove(); 8 8 9 - // Collapsible menu bahavior. 10 - $('.menu-vertical.collapsible').each(function(){ 24 + // Add aria attributes to the menu separators. 25 + menus.find('li') 26 + .filter(function() {return this.textContent.trim() === ""; }) 27 + .attr('role', 'separator') 28 + .attr('aria-hidden', 'true'); 29 + 30 + // Vertical menus are initially expanded 31 + $('.menu-vertical.collapsible').each(function() { 11 11 var open = $(this).hasClass('open'); 12 12 $(this).find('li ul').each(function() { 13 13 $(this).addClass('xDropdown-menu').parent().addClass('xDropdown' + (open ? ' open' : '')); 14 - // Wrap everything (including text nodes) before the sub-menu in a DIV that will toggle its state. 15 - var toggle = this.ownerDocument.createElement('div'); 16 - $(this).parent().prepend(toggle); 17 - for(var next = toggle.nextSibling; next != this; next = toggle.nextSibling) { 18 - toggle.appendChild(next); 35 + }); 36 + }); 37 + 38 + function setDropdownButtonTitle(dropDownButton) { 39 + var xDropdown = $(dropDownButton).parent().parent(); 40 + if($(xDropdown).hasClass('open')) { 41 + $(dropDownButton).attr('title', l10n['closeSubMenu']); 42 + $(xDropdown).attr('aria-expanded', "true"); 43 + } else { 44 + $(dropDownButton).attr('title', l10n['openSubMenu']); 45 + $(xDropdown).attr('aria-expanded', "false"); 46 + } 47 + } 48 + 49 + $('.xDropdown').each(function() { 50 + var dropDownHeader = this.ownerDocument.createElement("div"); 51 + $(dropDownHeader).addClass("xDropdown-header"); 52 + var dropDownButton = this.ownerDocument.createElement("button"); 53 + $(dropDownButton).addClass("xDropdown-header-toggle"); 54 + setDropdownButtonTitle(dropDownButton); 55 + dropDownButton.addEventListener('click',function() { 56 + //Swaps the state of the submenu. 57 + var xDropdown = $(this).parent().parent(); 58 + xDropdown.toggleClass('open'); 59 + setDropdownButtonTitle(dropDownButton); 60 + }); 61 + let dropDownContent = $(this).contents(); 62 + // We put all the content of the entry in the header, 63 + // except for the last one which is the content of the dropdown. This dropdown stays where it is. 64 + for (let index = 0; index < dropDownContent.length - 1 ; index++) { 65 + let item = dropDownContent[index]; 66 + dropDownHeader.append(item); 19 19 } 20 - $(toggle).addClass('xDropdown-toggle').on('click', function() { 21 - $(this).parent().toggleClass('open'); 22 - }); 68 + dropDownHeader.append(dropDownButton); 69 + $(this).prepend(dropDownHeader); 70 + $(dropDownHeader).next().addClass('xDropdown-menu'); 71 + }); 72 + 73 + $('.menu-horizontal .xDropdown').each(function() { 74 + // In case of horizontal menus, make it so that a class is added on hover, instead of using the :hover pseudo-class 75 + this.addEventListener("mouseover", function() { 76 + $(this).addClass('open'); 77 + setDropdownButtonTitle(this.firstChild.lastChild); 23 23 }); 79 + this.addEventListener("mouseout", function() { 80 + $(this).removeClass('open'); 81 + setDropdownButtonTitle(this.firstChild.lastChild); 82 + }); 24 24 }); 25 25 26 26 // In case of horizontal responsive menus, make sub-submenus in the navbar work on mobile devices
- XWiki.StyleSheetExtension[1]
-
- Код
-
... ... @@ -4,6 +4,32 @@ 4 4 } 5 5 } 6 6 .menu { 7 + /* Rotate the carets when the menu is opened. */ 8 + .xDropdown{ 9 + > .xDropdown-header > .xDropdown-header-toggle:before { 10 + transform: rotate(90deg); 11 + } 12 + &.open > .xDropdown-header > .xDropdown-header-toggle:before { 13 + transform: rotate(0); 14 + } 15 + } 16 + .xDropdown-header-toggle { 17 + background: transparent; 18 + border:none; 19 + border-radius: @border-radius-base; 20 + margin: 0 .3em; 21 + line-height: (@line-height-computed / 2); 22 + min-width: 24px; 23 + min-height: 24px; 24 + &:hover, &:focus-within { 25 + background-color: @dropdown-bg; 26 + } 27 + &:before { 28 + .caret; 29 + margin-left: 0; 30 + content: ''; 31 + } 32 + } 7 7 &.menu-vertical { 8 8 ul { 9 9 list-style-type: none; ... ... @@ -25,32 +25,8 @@ 25 25 .xDropdown-menu { 26 26 display: none; 27 27 } 28 - .xDropdown-toggle { 29 - cursor: pointer; 30 - position: relative; 31 - &:hover { 32 - background-color: @nav-link-hover-bg; 33 - } 34 - &:after { 35 - .caret; 36 - content: ''; 37 - /* Positioning */ 38 - position: absolute; 39 - margin-top: @line-height-computed / 3; 40 - right: 1em; 41 - /* Collapsed arrow style */ 42 - border-bottom: 4px solid transparent; 43 - border-right: 4px solid; 44 - border-top: 4px solid transparent; 45 - } 46 - } 47 47 .xDropdown.open { 48 - > .xDropdown-toggle:after { 49 - /* Expanded arrow style */ 50 - .caret; 51 - margin-top: @line-height-computed / 2; 52 - } 53 - > .xDropdown-menu { 55 + > ul { 54 54 display: block; 55 55 } 56 56 } ... ... @@ -66,22 +66,35 @@ 66 66 .box-shadow(0 2px 8px rgba(0,0,0,0.4) inset); 67 67 min-height: @navbar-height; 68 68 padding-left: 25px; 71 + .xDropdown.open { 72 + > .xDropdown-header > .xDropdown-header-toggle:before { 73 + transform: rotate(0); 74 + } 75 + > ul { 76 + display: block; 77 + } 78 + } 69 69 & > ul { 70 70 padding-left: 0; 71 71 list-style-type: none; 72 72 margin: 0; 83 + min-height: 50px; 84 + display: flex; 85 + align-items: stretch; 73 73 & > li { 74 74 position: relative; 75 - display: block; 88 + min-height: 50px; 89 + display: flex; 90 + align-items: center; 76 76 padding: @nav-link-padding; 77 - padding-top: @navbar-padding-vertical;78 - padding-bottom: @navbar-padding-vertical;92 + padding-top: 0; 93 + padding-bottom: 0; 79 79 @media (min-width: @grid-float-breakpoint) { 80 80 float: left; 81 81 } 82 82 line-height: @line-height-computed; 83 83 color: @navbar-default-link-color; 84 - &:hover { 99 + &:hover, &:focus-within { 85 85 color: @navbar-default-link-hover-color; 86 86 background-color: @navbar-default-link-hover-bg; 87 87 background-color: @navbar-default-link-active-bg; ... ... @@ -95,7 +95,7 @@ 95 95 /* Links inside menu */ 96 96 a { 97 97 color: @navbar-default-link-color; 98 - &:hover { 113 + &:hover, &:focus-within { 99 99 text-decoration: none; 100 100 } 101 101 } ... ... @@ -104,6 +104,10 @@ 104 104 /* Limit the height to the nav height minus the padding and minus border */ 105 105 max-height: @navbar-height - (2 * @navbar-padding-vertical) - 2px; 106 106 overflow: hidden; 122 + &.xDropdown-header{ 123 + /* No border on the dropdown header */ 124 + max-height: unset; 125 + } 107 107 } 108 108 /* Separator vertical inside menu */ 109 109 &:empty { ... ... @@ -148,7 +148,7 @@ 148 148 color: @dropdown-link-color; 149 149 overflow: hidden; 150 150 text-overflow: ellipsis; // Displaying ... if the text is too long 151 - &:hover { 170 + &:hover, &:focus-within { 152 152 /* &:extend(.dropdown-menu>li>a:hover); */ 153 153 text-decoration: none; 154 154 /* color: @dropdown-link-hover-color; ... ... @@ -166,7 +166,7 @@ 166 166 color: @dropdown-link-color; 167 167 /* Empty dropdowns should have height in order to display the arrow */ 168 168 min-height: 2 * @font-size-base; 169 - &:hover { 188 + &:hover, &:focus-within { 170 170 text-decoration: none; 171 171 /* color: @dropdown-link-hover-color; 172 172 background-color: @dropdown-link-hover-bg;*/ ... ... @@ -180,12 +180,6 @@ 180 180 padding: 0; 181 181 display: inherit; 182 182 } 183 - /* Place the arrow on the right */ 184 - &:after { 185 - position: absolute; 186 - margin-top: @line-height-computed / 2; 187 - right: 8px; 188 - } 189 189 } 190 190 /* Separator horizontal inside menu */ 191 191 &:empty { ... ... @@ -198,17 +198,9 @@ 198 198 /* Stylization: Generic */ 199 199 li { 200 200 /* Display submenus on hover */ 201 - & :hover> ul {214 + &.open > ul { 202 202 display: block; 203 203 } 204 - /* Display an arrow for expandable items */ 205 - &.xDropdown { 206 - &:after { 207 - .caret; 208 - content: ''; 209 - margin-left: .5em; 210 - } 211 - } 212 212 } 213 213 /* The only way to have a menu with more than 2 levels without JavaScript is to use a fixed width. */ 214 214 &.fixedWidth { ... ... @@ -230,7 +230,7 @@ 230 230 } 231 231 /* Resetting rules for mobile view */ 232 232 @media (max-width: @screen-xs-max) { 233 - > ul { 238 + > ul { 234 234 margin: 0 0 0 -25px; /* Remove padding added in normal view */ 235 235 > li { 236 236 &:empty { ... ... @@ -252,19 +252,16 @@ 252 252 /* Links inside menu */ 253 253 a { 254 254 color: @navbar-default-link-color; 255 - &:hover { 256 - /* Preserve the styling from dropdown */ 257 - } 258 258 } 259 259 /* Submenus inside menu */ 260 260 &.xDropdown { 261 261 color: @navbar-default-link-color; 262 - & :hover{264 + &.open { 263 263 background-color: transparent; 264 264 color: inherit; 265 265 } 266 266 /* When in dropdown we also have a link */ 267 - > span > a { 269 + > span > a { 268 268 color: @navbar-default-link-color; 269 269 } 270 270 }
- XWiki.WikiMacroClass[0]
-
- Код
-
... ... @@ -1,6 +1,7 @@ 1 1 {{velocity}} 2 2 #set ($id = $xcontext.macro.params.id) 3 3 #set ($type = $xcontext.macro.params.type) 4 +#set ($label = $xcontext.macro.params.label) 4 4 #set ($colorTheme = $xwiki.getUserPreference('colorTheme')) 5 5 #if ("$!colorTheme" != '') 6 6 ## Make sure we use an absolute reference (see XWIKI-9672) ... ... @@ -8,16 +8,24 @@ 8 8 #end 9 9 #set ($discard = $xwiki.ssx.use("$xcontext.macro.doc.prefixedFullName", {'colorTheme': $colorTheme})) 10 10 #set ($discard = $xwiki.jsx.use("$xcontext.macro.doc.prefixedFullName")) 12 +## Make sure the label is non-empty as otherwise the aria-label doesn't work. 13 +#if ("$!label" != '') 14 + #set ($label = $wikimacro.context.getXDOM().getIdGenerator().generateUniqueId('Menu','')) 15 +#end 11 11 #if($type.contains('horizontal')) 12 12 ## Make sure the id is non-empty for horizontal menus as otherwise the toggle doesn't work. 13 - #if ( $stringtool.isBlank("$!id"))18 + #if ("$!id" == '') 14 14 #set ($id = $wikimacro.context.getXDOM().getIdGenerator().generateUniqueId("M", "GeneratedMenuId")) 15 15 #end 16 - (% role="navigation" class="menu-horizontal-toggle" %)((( 21 + (% role='navigation' class='menu-horizontal-toggle' 22 + aria-label="${services.rendering.escape($label, 'xwiki/2.1')}" %)((( 17 17 (% class="navbar-header" %)((( 18 18 {{html}} 19 - <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#$!{escapetool.xml($id)}" aria-expanded="false"> 20 - <span class="sr-only"></span> 25 + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#$!{escapetool.xml($id)}" 26 + aria-expanded="false" aria-controls="$!{escapetool.xml($id)}"> 27 + <span class="sr-only"> 28 + $escapetool.xml($services.localization.render('menu.ui.horizontal.toggler.description')) 29 + </span> 21 21 <span class="icon-bar"></span> 22 22 <span class="icon-bar"></span> 23 23 <span class="icon-bar"></span> ... ... @@ -24,12 +24,13 @@ 24 24 </button> 25 25 {{/html}} 26 26 ))) 27 - (% id="$!{services.rendering.escape($id, 'xwiki/2.1')}" class="menu menu-${services.rendering.escape($!type, 'xwiki/2.1')} collapse navbar-collapse" %)((( 36 + (% id="$!{services.rendering.escape($id, 'xwiki/2.1')}" class="menu menu-${services.rendering.escape($!type, 'xwiki/2.1')} collapse navbar-collapse" role="navigation" %)((( 28 28 {{wikimacrocontent/}} 29 29 ))) 30 30 ))) 31 31 #else 32 - (% #if ("$!id" != '') id="${services.rendering.escape($id, 'xwiki/2.1')}"#end class="menu menu-${services.rendering.escape($!type, 'xwiki/2.1')}" %)((( 41 + (% role="navigation" #if ("$!id" != '') id="${services.rendering.escape($id, 'xwiki/2.1')}"#end class="menu menu-${services.rendering.escape($!type, 'xwiki/2.1')}" 42 + aria-label="${services.rendering.escape($label, 'xwiki/2.1')}" %)((( 33 33 {{wikimacrocontent/}} 34 34 ))) 35 35 #end
- XWiki.WikiMacroParameterClass[3]
-
- Описание параметра
-
... ... @@ -1,0 +1,1 @@ 1 +Optional menu label used to describe the content of the menu. - Обязательность параметра
-
... ... @@ -1,0 +1,1 @@ 1 +Нет - Имя параметра
-
... ... @@ -1,0 +1,1 @@ 1 +label