pvbemu/app/toolkit/MenuBar.js

100 lines
2.9 KiB
JavaScript

"use strict";
// Main application menu bar
Toolkit.MenuBar = class MenuBar extends Toolkit.Component {
// Object constructor
constructor(application, options) {
super(application, "div");
// Configure instance fields
this.expanded = null;
this.lastFocus = null;
this.menuBar = this;
this.menus = [];
this.name = options.name || "";
// Configure element
this.element.style.display = "flex";
this.element.style.position = "relative";
this.element.style.zIndex = "1";
this.element.setAttribute("role", "menubar");
// Configure properties
this.setName(this.name);
application.addComponent(this);
}
///////////////////////////// Public Methods //////////////////////////////
// Create a Menu and associate it with the application and component
newMenu(options, index) {
let menu = new Toolkit.Menu(this, options);
// Determine the ordinal position of the element within the container
index = !(typeof index == "number") ? this.menus.length :
Math.floor(Math.min(Math.max(0, index), this.menus.length));
// Add the menu to the menu bar
let ref = this.menus[index];
this.element.insertBefore(menu.element, ref ? ref.element : null);
this.menus.splice(index, 0, menu);
menu.element.insertAdjacentElement("afterend", menu.menu);
// Ensure only the first menu is focusable
for (let x = 0; x < this.menus.length; x++)
this.menus[x].element.setAttribute("tabindex", x==0 ? "0" : "-1");
return menu;
}
// Specify the menu's accessible name
setName(name) {
this.name = name || "";
this.localize();
}
///////////////////////////// Package Methods /////////////////////////////
// Notify of a change to component focus
focusChanged(from, to) {
// Configure tabstop on the first menu
if (this.menus.length > 0)
this.menus[0].element.setAttribute("tabindex",
this.contains(to) ? "-1" : "0");
// Retain a reference to the previously focused element
if (!this.contains(from)) {
if (from == null)
from = document.body;
if ("component" in from)
from = from.component;
this.lastFocus = from;
}
super.focusChanged(from, to);
}
// 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);
}
// Return focus to where it was before the menu was activated
restoreFocus() {
let elm = this.lastFocus;
if (elm == null)
elm = document.body;
elm.focus();
}
};