Files
Sensores/static/lib/Highcharts-10.2.1/es-modules/Accessibility/Components/MenuComponent.js
2025-04-17 00:35:33 -06:00

453 lines
15 KiB
JavaScript

/* *
*
* (c) 2009-2021 Øystein Moseng
*
* Accessibility component for exporting menu.
*
* License: www.highcharts.com/license
*
* !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
*
* */
'use strict';
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import Chart from '../../Core/Chart/Chart.js';
import U from '../../Core/Utilities.js';
var attr = U.attr;
import AccessibilityComponent from '../AccessibilityComponent.js';
import KeyboardNavigationHandler from '../KeyboardNavigationHandler.js';
import ChartUtilities from '../Utils/ChartUtilities.js';
var getChartTitle = ChartUtilities.getChartTitle, unhideChartElementFromAT = ChartUtilities.unhideChartElementFromAT;
import HTMLUtilities from '../Utils/HTMLUtilities.js';
var getFakeMouseEvent = HTMLUtilities.getFakeMouseEvent;
/* *
*
* Functions
*
* */
/* eslint-disable valid-jsdoc */
/**
* Get the wrapped export button element of a chart.
* @private
*/
function getExportMenuButtonElement(chart) {
return chart.exportSVGElements && chart.exportSVGElements[0];
}
/**
* @private
*/
function exportingShouldHaveA11y(chart) {
var exportingOpts = chart.options.exporting, exportButton = getExportMenuButtonElement(chart);
return !!(exportingOpts &&
exportingOpts.enabled !== false &&
exportingOpts.accessibility &&
exportingOpts.accessibility.enabled &&
exportButton &&
exportButton.element);
}
/* *
*
* Class
*
* */
/**
* The MenuComponent class
*
* @private
* @class
* @name Highcharts.MenuComponent
*/
var MenuComponent = /** @class */ (function (_super) {
__extends(MenuComponent, _super);
function MenuComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
/* *
*
* Functions
*
* */
/* eslint-disable valid-jsdoc */
/**
* Init the component
*/
MenuComponent.prototype.init = function () {
var chart = this.chart, component = this;
this.addEvent(chart, 'exportMenuShown', function () {
component.onMenuShown();
});
this.addEvent(chart, 'exportMenuHidden', function () {
component.onMenuHidden();
});
this.createProxyGroup();
};
/**
* @private
*/
MenuComponent.prototype.onMenuHidden = function () {
var menu = this.chart.exportContextMenu;
if (menu) {
menu.setAttribute('aria-hidden', 'true');
}
this.setExportButtonExpandedState('false');
};
/**
* @private
*/
MenuComponent.prototype.onMenuShown = function () {
var chart = this.chart, menu = chart.exportContextMenu;
if (menu) {
this.addAccessibleContextMenuAttribs();
unhideChartElementFromAT(chart, menu);
}
this.setExportButtonExpandedState('true');
};
/**
* @private
* @param {string} stateStr
*/
MenuComponent.prototype.setExportButtonExpandedState = function (stateStr) {
if (this.exportButtonProxy) {
this.exportButtonProxy.buttonElement.setAttribute('aria-expanded', stateStr);
}
};
/**
* Called on each render of the chart. We need to update positioning of the
* proxy overlay.
*/
MenuComponent.prototype.onChartRender = function () {
var chart = this.chart, focusEl = chart.focusElement, a11y = chart.accessibility;
this.proxyProvider.clearGroup('chartMenu');
this.proxyMenuButton();
if (this.exportButtonProxy &&
focusEl &&
focusEl === chart.exportingGroup) {
if (focusEl.focusBorder) {
chart.setFocusToElement(focusEl, this.exportButtonProxy.buttonElement);
}
else if (a11y) {
a11y.keyboardNavigation.tabindexContainer.focus();
}
}
};
/**
* @private
*/
MenuComponent.prototype.proxyMenuButton = function () {
var chart = this.chart;
var proxyProvider = this.proxyProvider;
var buttonEl = getExportMenuButtonElement(chart);
if (exportingShouldHaveA11y(chart) && buttonEl) {
this.exportButtonProxy = proxyProvider.addProxyElement('chartMenu', { click: buttonEl }, {
'aria-label': chart.langFormat('accessibility.exporting.menuButtonLabel', {
chart: chart,
chartTitle: getChartTitle(chart)
}),
'aria-expanded': false,
title: chart.options.lang.contextButtonTitle || null
});
}
};
/**
* @private
*/
MenuComponent.prototype.createProxyGroup = function () {
var chart = this.chart;
if (chart && this.proxyProvider) {
this.proxyProvider.addGroup('chartMenu', 'div');
}
};
/**
* @private
*/
MenuComponent.prototype.addAccessibleContextMenuAttribs = function () {
var chart = this.chart, exportList = chart.exportDivElements;
if (exportList && exportList.length) {
// Set tabindex on the menu items to allow focusing by script
// Set role to give screen readers a chance to pick up the contents
exportList.forEach(function (item) {
if (item) {
if (item.tagName === 'LI' &&
!(item.children && item.children.length)) {
item.setAttribute('tabindex', -1);
}
else {
item.setAttribute('aria-hidden', 'true');
}
}
});
// Set accessibility properties on parent div
var parentDiv = (exportList[0] && exportList[0].parentNode);
if (parentDiv) {
attr(parentDiv, {
'aria-hidden': void 0,
'aria-label': chart.langFormat('accessibility.exporting.chartMenuLabel', { chart: chart }),
role: 'list' // Needed for webkit/VO
});
}
}
};
/**
* Get keyboard navigation handler for this component.
* @private
*/
MenuComponent.prototype.getKeyboardNavigation = function () {
var keys = this.keyCodes, chart = this.chart, component = this;
return new KeyboardNavigationHandler(chart, {
keyCodeMap: [
// Arrow prev handler
[
[keys.left, keys.up],
function () {
return component.onKbdPrevious(this);
}
],
// Arrow next handler
[
[keys.right, keys.down],
function () {
return component.onKbdNext(this);
}
],
// Click handler
[
[keys.enter, keys.space],
function () {
return component.onKbdClick(this);
}
]
],
// Only run exporting navigation if exporting support exists and is
// enabled on chart
validate: function () {
return !!chart.exporting &&
chart.options.exporting.enabled !== false &&
chart.options.exporting.accessibility.enabled !==
false;
},
// Focus export menu button
init: function () {
var proxy = component.exportButtonProxy;
var svgEl = component.chart.exportingGroup;
if (proxy && svgEl) {
chart.setFocusToElement(svgEl, proxy.buttonElement);
}
},
// Hide the menu
terminate: function () {
chart.hideExportMenu();
}
});
};
/**
* @private
* @param {Highcharts.KeyboardNavigationHandler} keyboardNavigationHandler
* @return {number} Response code
*/
MenuComponent.prototype.onKbdPrevious = function (keyboardNavigationHandler) {
var chart = this.chart;
var a11yOptions = chart.options.accessibility;
var response = keyboardNavigationHandler.response;
// Try to highlight prev item in list. Highlighting e.g.
// separators will fail.
var i = chart.highlightedExportItemIx || 0;
while (i--) {
if (chart.highlightExportItem(i)) {
return response.success;
}
}
// We failed, so wrap around or move to prev module
if (a11yOptions.keyboardNavigation.wrapAround) {
chart.highlightLastExportItem();
return response.success;
}
return response.prev;
};
/**
* @private
* @param {Highcharts.KeyboardNavigationHandler} keyboardNavigationHandler
* @return {number} Response code
*/
MenuComponent.prototype.onKbdNext = function (keyboardNavigationHandler) {
var chart = this.chart;
var a11yOptions = chart.options.accessibility;
var response = keyboardNavigationHandler.response;
// Try to highlight next item in list. Highlighting e.g.
// separators will fail.
for (var i = (chart.highlightedExportItemIx || 0) + 1; i < chart.exportDivElements.length; ++i) {
if (chart.highlightExportItem(i)) {
return response.success;
}
}
// We failed, so wrap around or move to next module
if (a11yOptions.keyboardNavigation.wrapAround) {
chart.highlightExportItem(0);
return response.success;
}
return response.next;
};
/**
* @private
* @param {Highcharts.KeyboardNavigationHandler} keyboardNavigationHandler
* @return {number} Response code
*/
MenuComponent.prototype.onKbdClick = function (keyboardNavigationHandler) {
var chart = this.chart;
var curHighlightedItem = chart.exportDivElements[chart.highlightedExportItemIx];
var exportButtonElement = getExportMenuButtonElement(chart).element;
if (chart.openMenu) {
this.fakeClickEvent(curHighlightedItem);
}
else {
this.fakeClickEvent(exportButtonElement);
chart.highlightExportItem(0);
}
return keyboardNavigationHandler.response.success;
};
return MenuComponent;
}(AccessibilityComponent));
/* *
*
* Class Namespace
*
* */
(function (MenuComponent) {
/* *
*
* Declarations
*
* */
/* *
*
* Constants
*
* */
var composedClasses = [];
/* *
*
* Functions
*
* */
/* eslint-disable valid-jsdoc */
/**
* @private
*/
function compose(ChartClass) {
if (composedClasses.indexOf(ChartClass) === -1) {
composedClasses.push(ChartClass);
var chartProto = Chart.prototype;
chartProto.hideExportMenu = chartHideExportMenu;
chartProto.highlightExportItem = chartHighlightExportItem;
chartProto.highlightLastExportItem = chartHighlightLastExportItem;
chartProto.showExportMenu = chartShowExportMenu;
}
}
MenuComponent.compose = compose;
/**
* Show the export menu and focus the first item (if exists).
*
* @private
* @function Highcharts.Chart#showExportMenu
*/
function chartShowExportMenu() {
var exportButton = getExportMenuButtonElement(this);
if (exportButton) {
var el = exportButton.element;
if (el.onclick) {
el.onclick(getFakeMouseEvent('click'));
}
}
}
/**
* @private
* @function Highcharts.Chart#hideExportMenu
*/
function chartHideExportMenu() {
var chart = this, exportList = chart.exportDivElements;
if (exportList && chart.exportContextMenu && chart.openMenu) {
// Reset hover states etc.
exportList.forEach(function (el) {
if (el &&
el.className === 'highcharts-menu-item' &&
el.onmouseout) {
el.onmouseout(getFakeMouseEvent('mouseout'));
}
});
chart.highlightedExportItemIx = 0;
// Hide the menu div
chart.exportContextMenu.hideMenu();
// Make sure the chart has focus and can capture keyboard events
chart.container.focus();
}
}
/**
* Highlight export menu item by index.
*
* @private
* @function Highcharts.Chart#highlightExportItem
*/
function chartHighlightExportItem(ix) {
var listItem = this.exportDivElements && this.exportDivElements[ix];
var curHighlighted = this.exportDivElements &&
this.exportDivElements[this.highlightedExportItemIx];
if (listItem &&
listItem.tagName === 'LI' &&
!(listItem.children && listItem.children.length)) {
// Test if we have focus support for SVG elements
var hasSVGFocusSupport = !!(this.renderTo.getElementsByTagName('g')[0] || {}).focus;
// Only focus if we can set focus back to the elements after
// destroying the menu (#7422)
if (listItem.focus && hasSVGFocusSupport) {
listItem.focus();
}
if (curHighlighted && curHighlighted.onmouseout) {
curHighlighted.onmouseout(getFakeMouseEvent('mouseout'));
}
if (listItem.onmouseover) {
listItem.onmouseover(getFakeMouseEvent('mouseover'));
}
this.highlightedExportItemIx = ix;
return true;
}
return false;
}
/**
* Try to highlight the last valid export menu item.
*
* @private
* @function Highcharts.Chart#highlightLastExportItem
*/
function chartHighlightLastExportItem() {
var chart = this;
if (chart.exportDivElements) {
var i = chart.exportDivElements.length;
while (i--) {
if (chart.highlightExportItem(i)) {
return true;
}
}
}
return false;
}
})(MenuComponent || (MenuComponent = {}));
/* *
*
* Default Export
*
* */
export default MenuComponent;