* @module WoltLabSuite/Core/Ui/Mobile
*/
+import { createFocusTrap, FocusTrap } from "focus-trap";
import * as Core from "../Core";
import DomChangeListener from "../Dom/Change/Listener";
import DomUtil from "../Dom/Util";
import { PageMenuMainProvider } from "./Page/Menu/Main/Provider";
import { hasValidUserMenu, PageMenuUser } from "./Page/Menu/User";
import * as UiScreen from "./Screen";
+import * as Language from "../Language";
let _dropdownMenu: HTMLUListElement | null = null;
let _dropdownMenuMessage: HTMLElement | null = null;
let _enabled = false;
let _enabledLGTouchNavigation = false;
let _enableMobileMenu = false;
+let _focusTrap: FocusTrap | undefined = undefined;
const _knownMessages = new WeakSet<HTMLElement>();
let _mobileSidebarEnabled = false;
let _pageMenuMain: PageMenuMain;
initButtonGroupNavigation();
initMessages();
+ initMessagesA11y();
initMobileMenu();
UiCloseOverlay.add("WoltLabSuite/Core/Ui/Mobile", closeAllMenus);
}
function initMessages(): void {
+ const isScreenSmDown = UiScreen.is("screen-sm-down");
+
document.querySelectorAll(".message").forEach((message: HTMLElement) => {
if (_knownMessages.has(message)) {
return;
toggleMobileNavigation(message, quickOptions, navigation);
}
});
+ quickOptions.addEventListener("keydown", (event) => {
+ if (event.key === "Enter") {
+ event.preventDefault();
+
+ quickOptions.click();
+ }
+ });
+
+ if (isScreenSmDown) {
+ enableMessageA11y(quickOptions);
+ }
}
}
_knownMessages.add(message);
});
}
+function enableMessageA11y(quickOptions: HTMLElement): void {
+ quickOptions.tabIndex = 0;
+ quickOptions.setAttribute("role", "button");
+ quickOptions.setAttribute("aria-label", Language.get("wcf.global.button.more"));
+}
+
+function disableMessageA11y(quickOptions: HTMLElement): void {
+ quickOptions.removeAttribute("tabindex");
+ quickOptions.removeAttribute("role");
+ quickOptions.removeAttribute("aria-label");
+}
+
+function initMessagesA11y(): void {
+ UiScreen.on("screen-sm-down", {
+ match() {
+ document.querySelectorAll(".message").forEach((message: HTMLElement) => {
+ const navigation = message.querySelector(".jsMobileNavigation") as HTMLAnchorElement;
+ if (navigation) {
+ const quickOptions = message.querySelector(".messageQuickOptions") as HTMLElement;
+ if (quickOptions && navigation.childElementCount) {
+ enableMessageA11y(quickOptions);
+ }
+ }
+ });
+ },
+ unmatch() {
+ document.querySelectorAll(".message").forEach((message: HTMLElement) => {
+ if (!_knownMessages.has(message)) {
+ return;
+ }
+
+ const navigation = message.querySelector(".jsMobileNavigation") as HTMLAnchorElement;
+ if (navigation) {
+ const quickOptions = message.querySelector(".messageQuickOptions") as HTMLElement;
+ if (quickOptions && navigation.childElementCount) {
+ disableMessageA11y(quickOptions);
+ }
+ }
+ });
+ },
+ });
+}
function initMobileMenu(): void {
if (_enableMobileMenu) {
_pageMenuMain = new PageMenuMain(_pageMenuMainProvider);
UiDropdownReusable.init("com.woltlab.wcf.jsMobileNavigation", _dropdownMenu);
} else if (_dropdownMenu.classList.contains("dropdownOpen")) {
closeDropdown();
+ _focusTrap!.deactivate();
+ _focusTrap = undefined;
+
if (_dropdownMenuMessage === message) {
// toggle behavior
return;
});
_dropdownMenu.classList.add("dropdownOpen");
_dropdownMenuMessage = message;
+
+ _focusTrap = createFocusTrap(_dropdownMenu, {
+ allowOutsideClick: true,
+ escapeDeactivates(): boolean {
+ toggleMobileNavigation(message, quickOptions, navigation);
+
+ return false;
+ },
+ });
+ _focusTrap.activate();
}
function setupLGTouchNavigation(): void {
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @module WoltLabSuite/Core/Ui/Mobile
*/
-define(["require", "exports", "tslib", "../Core", "../Dom/Change/Listener", "../Dom/Util", "../Environment", "./Alignment", "./CloseOverlay", "./Dropdown/Reusable", "./Page/Menu/Main", "./Page/Menu/User", "./Screen"], function (require, exports, tslib_1, Core, Listener_1, Util_1, Environment, UiAlignment, CloseOverlay_1, UiDropdownReusable, Main_1, User_1, UiScreen) {
+define(["require", "exports", "tslib", "focus-trap", "../Core", "../Dom/Change/Listener", "../Dom/Util", "../Environment", "./Alignment", "./CloseOverlay", "./Dropdown/Reusable", "./Page/Menu/Main", "./Page/Menu/User", "./Screen", "../Language"], function (require, exports, tslib_1, focus_trap_1, Core, Listener_1, Util_1, Environment, UiAlignment, CloseOverlay_1, UiDropdownReusable, Main_1, User_1, UiScreen, Language) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeShadow = exports.rebuildShadow = exports.disableShadow = exports.disable = exports.enableShadow = exports.enable = exports.setup = void 0;
CloseOverlay_1 = (0, tslib_1.__importDefault)(CloseOverlay_1);
UiDropdownReusable = (0, tslib_1.__importStar)(UiDropdownReusable);
UiScreen = (0, tslib_1.__importStar)(UiScreen);
+ Language = (0, tslib_1.__importStar)(Language);
let _dropdownMenu = null;
let _dropdownMenuMessage = null;
let _enabled = false;
let _enabledLGTouchNavigation = false;
let _enableMobileMenu = false;
+ let _focusTrap = undefined;
const _knownMessages = new WeakSet();
let _mobileSidebarEnabled = false;
let _pageMenuMain;
_enabled = true;
initButtonGroupNavigation();
initMessages();
+ initMessagesA11y();
initMobileMenu();
CloseOverlay_1.default.add("WoltLabSuite/Core/Ui/Mobile", closeAllMenus);
Listener_1.default.add("WoltLabSuite/Core/Ui/Mobile", () => {
});
}
function initMessages() {
+ const isScreenSmDown = UiScreen.is("screen-sm-down");
document.querySelectorAll(".message").forEach((message) => {
if (_knownMessages.has(message)) {
return;
toggleMobileNavigation(message, quickOptions, navigation);
}
});
+ quickOptions.addEventListener("keydown", (event) => {
+ if (event.key === "Enter") {
+ event.preventDefault();
+ quickOptions.click();
+ }
+ });
+ if (isScreenSmDown) {
+ enableMessageA11y(quickOptions);
+ }
}
}
_knownMessages.add(message);
});
}
+ function enableMessageA11y(quickOptions) {
+ quickOptions.tabIndex = 0;
+ quickOptions.setAttribute("role", "button");
+ quickOptions.setAttribute("aria-label", Language.get("wcf.global.button.more"));
+ }
+ function disableMessageA11y(quickOptions) {
+ quickOptions.removeAttribute("tabindex");
+ quickOptions.removeAttribute("role");
+ quickOptions.removeAttribute("aria-label");
+ }
+ function initMessagesA11y() {
+ UiScreen.on("screen-sm-down", {
+ match() {
+ document.querySelectorAll(".message").forEach((message) => {
+ const navigation = message.querySelector(".jsMobileNavigation");
+ if (navigation) {
+ const quickOptions = message.querySelector(".messageQuickOptions");
+ if (quickOptions && navigation.childElementCount) {
+ enableMessageA11y(quickOptions);
+ }
+ }
+ });
+ },
+ unmatch() {
+ document.querySelectorAll(".message").forEach((message) => {
+ if (!_knownMessages.has(message)) {
+ return;
+ }
+ const navigation = message.querySelector(".jsMobileNavigation");
+ if (navigation) {
+ const quickOptions = message.querySelector(".messageQuickOptions");
+ if (quickOptions && navigation.childElementCount) {
+ disableMessageA11y(quickOptions);
+ }
+ }
+ });
+ },
+ });
+ }
function initMobileMenu() {
if (_enableMobileMenu) {
_pageMenuMain = new Main_1.PageMenuMain(_pageMenuMainProvider);
}
else if (_dropdownMenu.classList.contains("dropdownOpen")) {
closeDropdown();
+ _focusTrap.deactivate();
+ _focusTrap = undefined;
if (_dropdownMenuMessage === message) {
// toggle behavior
return;
});
_dropdownMenu.classList.add("dropdownOpen");
_dropdownMenuMessage = message;
+ _focusTrap = (0, focus_trap_1.createFocusTrap)(_dropdownMenu, {
+ allowOutsideClick: true,
+ escapeDeactivates() {
+ toggleMobileNavigation(message, quickOptions, navigation);
+ return false;
+ },
+ });
+ _focusTrap.activate();
}
function setupLGTouchNavigation() {
_enabledLGTouchNavigation = true;