100 lines
2.9 KiB
JavaScript
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();
|
|
}
|
|
|
|
};
|