Include the footer menu at the bottom of the menu
authorAlexander Ebert <ebert@woltlab.com>
Sun, 12 Dec 2021 14:56:16 +0000 (15:56 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 12 Dec 2021 14:56:16 +0000 (15:56 +0100)
ts/WoltLabSuite/Core/Ui/Page/Menu/Container.ts
ts/WoltLabSuite/Core/Ui/Page/Menu/Main.ts
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Container.js
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Page/Menu/Main.js

index 7aa8eca9e70e490649bb340ab873312a413fedac..473e485dc2cc0f7a10568093cd4998f6d53a475c 100644 (file)
@@ -1,6 +1,6 @@
 import { PageMenuProvider } from "./Provider";
 import { createFocusTrap, FocusTrap } from "focus-trap";
-import { scrollDisable, scrollEnable } from "../../Screen";
+import { pageOverlayClose, pageOverlayOpen, scrollDisable, scrollEnable } from "../../Screen";
 
 export class PageMenuContainer {
   private readonly container = document.createElement("div");
@@ -19,6 +19,7 @@ export class PageMenuContainer {
     this.content.append(this.provider.getContent());
     this.provider.getMenuButton().setAttribute("aria-expanded", "true");
 
+    pageOverlayOpen();
     scrollDisable();
 
     this.container.hidden = false;
@@ -28,6 +29,7 @@ export class PageMenuContainer {
   close(): void {
     this.provider.getMenuButton().setAttribute("aria-expanded", "false");
 
+    pageOverlayClose();
     scrollEnable();
 
     this.container.hidden = true;
index e1ca3e1d5b2383ebb8eb97cb8751299fa5649ae7..24ee52de24c8adf9c714b15456ab24969bfdd97b 100644 (file)
@@ -73,9 +73,18 @@ export class PageMenuMain implements PageMenuProvider {
   }
 
   getContent(): DocumentFragment {
-    const fragment = document.createDocumentFragment();
+    const container = document.createElement("div");
+    container.classList.add("pageMenuMainContainer");
+
+    container.append(...this.buildMainMenu());
+
+    const footerMenu = this.buildFooterMenu();
+    if (footerMenu) {
+      container.append(footerMenu);
+    }
 
-    fragment.append(...this.buildMainMenu());
+    const fragment = document.createDocumentFragment();
+    fragment.append(container);
 
     return fragment;
   }
@@ -85,18 +94,41 @@ export class PageMenuMain implements PageMenuProvider {
   }
 
   private buildMainMenu(): HTMLElement[] {
-    const menu = this.mainMenu.querySelector(".boxMenu")!;
-    const menuItems: MenuItem[] = Array.from(menu.children).map((element: HTMLElement) => {
+    const boxMenu = this.mainMenu.querySelector(".boxMenu") as HTMLElement;
+
+    const nav = this.buildMenu(boxMenu);
+    nav.setAttribute("aria-label", window.PAGE_TITLE);
+    nav.setAttribute("role", "navigation");
+
+    return [nav];
+  }
+
+  private buildFooterMenu(): HTMLElement | null {
+    const box = document.querySelector('.box[data-box-identifier="com.woltlab.wcf.FooterMenu"]');
+    if (box === null) {
+      return null;
+    }
+
+    const boxMenu = box.querySelector(".boxMenu") as HTMLElement;
+    const nav = this.buildMenu(boxMenu);
+    nav.classList.add("pageMenuMainNavigationFooter");
+
+    const label = box.querySelector("nav")!.getAttribute("aria-label")!;
+    nav.setAttribute("aria-label", label);
+
+    return nav;
+  }
+
+  private buildMenu(boxMenu: HTMLElement): HTMLElement {
+    const menuItems: MenuItem[] = Array.from(boxMenu.children).map((element: HTMLElement) => {
       return normalizeMenuItem(element);
     });
 
     const nav = document.createElement("nav");
     nav.classList.add("pageMenuMainNavigation");
-    nav.setAttribute("aria-label", window.PAGE_TITLE);
-    nav.setAttribute("role", "navigation");
     nav.append(this.buildMenuItemList(menuItems));
 
-    return [nav];
+    return nav;
   }
 
   private buildMenuItemList(menuItems: MenuItem[]): HTMLUListElement {
index a2ce3966b1818fdc8b49e2d29e770725e9c65186..7d9ab2e5900b8da545c4f88d97a8a2c89eebda53 100644 (file)
@@ -14,12 +14,14 @@ define(["require", "exports", "focus-trap", "../../Screen"], function (require,
             this.content.innerHTML = "";
             this.content.append(this.provider.getContent());
             this.provider.getMenuButton().setAttribute("aria-expanded", "true");
+            (0, Screen_1.pageOverlayOpen)();
             (0, Screen_1.scrollDisable)();
             this.container.hidden = false;
             this.getFocusTrap().activate();
         }
         close() {
             this.provider.getMenuButton().setAttribute("aria-expanded", "false");
+            (0, Screen_1.pageOverlayClose)();
             (0, Screen_1.scrollEnable)();
             this.container.hidden = true;
             this.getFocusTrap().deactivate();
index e0cd9a127121e8b6e3536bbdfb7fd36445a4f8a8..5a797f2448e994f40df037b291befd3859a66bf7 100644 (file)
@@ -53,24 +53,47 @@ define(["require", "exports", "tslib", "./Container", "../../../Language", "../.
             });
         }
         getContent() {
+            const container = document.createElement("div");
+            container.classList.add("pageMenuMainContainer");
+            container.append(...this.buildMainMenu());
+            const footerMenu = this.buildFooterMenu();
+            if (footerMenu) {
+                container.append(footerMenu);
+            }
             const fragment = document.createDocumentFragment();
-            fragment.append(...this.buildMainMenu());
+            fragment.append(container);
             return fragment;
         }
         getMenuButton() {
             return this.mainMenu;
         }
         buildMainMenu() {
-            const menu = this.mainMenu.querySelector(".boxMenu");
-            const menuItems = Array.from(menu.children).map((element) => {
+            const boxMenu = this.mainMenu.querySelector(".boxMenu");
+            const nav = this.buildMenu(boxMenu);
+            nav.setAttribute("aria-label", window.PAGE_TITLE);
+            nav.setAttribute("role", "navigation");
+            return [nav];
+        }
+        buildFooterMenu() {
+            const box = document.querySelector('.box[data-box-identifier="com.woltlab.wcf.FooterMenu"]');
+            if (box === null) {
+                return null;
+            }
+            const boxMenu = box.querySelector(".boxMenu");
+            const nav = this.buildMenu(boxMenu);
+            nav.classList.add("pageMenuMainNavigationFooter");
+            const label = box.querySelector("nav").getAttribute("aria-label");
+            nav.setAttribute("aria-label", label);
+            return nav;
+        }
+        buildMenu(boxMenu) {
+            const menuItems = Array.from(boxMenu.children).map((element) => {
                 return normalizeMenuItem(element);
             });
             const nav = document.createElement("nav");
             nav.classList.add("pageMenuMainNavigation");
-            nav.setAttribute("aria-label", window.PAGE_TITLE);
-            nav.setAttribute("role", "navigation");
             nav.append(this.buildMenuItemList(menuItems));
-            return [nav];
+            return nav;
         }
         buildMenuItemList(menuItems) {
             const list = document.createElement("ul");