pvbemu/app/toolkit/MenuBar.js

120 lines
3.4 KiB
JavaScript

"use strict";
// Main application menu bar
Toolkit.MenuBar = class MenuBar extends Toolkit.Panel {
// Object constructor
constructor(application, options) {
super(application, options);
// Configure instance fields
this.expanded = null;
this.lastFocus = null;
this.menuBar = this;
this.name = options.name || "";
// Configure element
this.element.style.position = "relative";
this.element.style.zIndex = "2";
this.element.setAttribute("role", "menubar");
this.setLayout("flex", {
direction: "row",
wrap : "false"
});
this.setOverflow("visible", "visible");
this.element.addEventListener(
"blur" , e=>this.onblur (e), { capture: true });
this.element.addEventListener(
"focus", e=>this.onfocus(e), { capture: true });
// Configure properties
this.setName(this.name);
application.addComponent(this);
}
///////////////////////////// Public Methods //////////////////////////////
// Add a component as a child of this container
add(component, index) {
super.add(component, index);
component.child();
return component;
}
// Create a Menu and associate it with the application and component
newMenu(options, index) {
// Create and add a new menu
let menu = this.add(new Toolkit.Menu(this.application,options), index);
menu.element.insertAdjacentElement("afterend", menu.menu.element);
// Ensure only the first menu is focusable
for (let x = 0; x < this.children.length; x++)
this.children[x].element
.setAttribute("tabindex", x == 0 ? "0" : "-1");
return menu;
}
// Return focus to where it was before the menu was activated
restoreFocus() {
if (!this.contains(document.activeElement))
return;
let elm = this.lastFocus;
if (elm == null)
elm = document.body;
elm.focus();
if (this.contains(document.activeElement))
document.activeElement.blur();
}
// Specify the menu's accessible name
setName(name) {
this.name = name || "";
this.localize();
}
///////////////////////////// Package Methods /////////////////////////////
// Blur event capture
onblur(e) {
if (this.contains(e.relatedTarget))
return;
if (this.children.length > 0)
this.children[0].element.setAttribute("tabindex", "0");
if (this.expanded != null)
this.expanded.setExpanded(false);
}
// Focus event capture
onfocus(e) {
// Configure tabstop on the first menu
if (this.children.length > 0)
this.children[0].element.setAttribute("tabindex", "-1");
// Retain a reference to the previously focused element
if (this.contains(e.relatedTarget))
return;
let from = e.relatedTarget;
if (from == null)
from = document.body;
if ("component" in from)
from = from.component;
this.lastFocus = from;
}
// Update display text with localized strings
localize() {
let text = this.name;
if (this.application)
text = this.application.translate(text, this);
this.element.setAttribute("aria-label", text);
}
};