/* *
|
*
|
* (c) 2009-2019 Øystein Moseng
|
*
|
* Accessibility component for chart legend.
|
*
|
* License: www.highcharts.com/license
|
*
|
* */
|
|
'use strict';
|
|
Object.defineProperty(exports, "__esModule", {
|
value: true
|
});
|
|
var _Globals = require('../../../parts/Globals.js');
|
|
var _Globals2 = _interopRequireDefault(_Globals);
|
|
var _AccessibilityComponent = require('../AccessibilityComponent.js');
|
|
var _AccessibilityComponent2 = _interopRequireDefault(_AccessibilityComponent);
|
|
var _KeyboardNavigationHandler = require('../KeyboardNavigationHandler.js');
|
|
var _KeyboardNavigationHandler2 = _interopRequireDefault(_KeyboardNavigationHandler);
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
/**
|
* Highlight legend item by index.
|
*
|
* @private
|
* @function Highcharts.Chart#highlightLegendItem
|
*
|
* @param {number} ix
|
*
|
* @return {boolean}
|
*/
|
_Globals2.default.Chart.prototype.highlightLegendItem = function (ix) {
|
var items = this.legend.allItems,
|
oldIx = this.highlightedLegendItemIx;
|
|
if (items[ix]) {
|
if (items[oldIx]) {
|
_Globals2.default.fireEvent(items[oldIx].legendGroup.element, 'mouseout');
|
}
|
// Scroll if we have to
|
if (items[ix].pageIx !== undefined && items[ix].pageIx + 1 !== this.legend.currentPage) {
|
this.legend.scroll(1 + items[ix].pageIx - this.legend.currentPage);
|
}
|
// Focus
|
this.setFocusToElement(items[ix].legendItem, items[ix].a11yProxyElement);
|
_Globals2.default.fireEvent(items[ix].legendGroup.element, 'mouseover');
|
return true;
|
}
|
return false;
|
};
|
|
// Keep track of pressed state for legend items
|
_Globals2.default.addEvent(_Globals2.default.Legend, 'afterColorizeItem', function (e) {
|
var chart = this.chart,
|
a11yOptions = chart.options.accessibility,
|
legendItem = e.item;
|
if (a11yOptions.enabled && legendItem && legendItem.a11yProxyElement) {
|
legendItem.a11yProxyElement.setAttribute('aria-pressed', e.visible ? 'false' : 'true');
|
}
|
});
|
|
/**
|
* The LegendComponent class
|
*
|
* @private
|
* @class
|
* @name Highcharts.LegendComponent
|
* @param {Highcharts.Chart} chart
|
* Chart object
|
*/
|
var LegendComponent = function LegendComponent(chart) {
|
this.initBase(chart);
|
};
|
LegendComponent.prototype = new _AccessibilityComponent2.default();
|
_Globals2.default.extend(LegendComponent.prototype, /** @lends Highcharts.LegendComponent */{
|
|
/**
|
* The legend needs updates on every render, in order to update positioning
|
* of the proxy overlays.
|
*/
|
onChartRender: function onChartRender() {
|
var chart = this.chart,
|
a11yOptions = chart.options.accessibility,
|
items = chart.legend && chart.legend.allItems,
|
component = this;
|
|
// Ignore render after proxy clicked. No need to destroy it, and
|
// destroying also kills focus.
|
if (component.legendProxyButtonClicked) {
|
delete component.legendProxyButtonClicked;
|
return;
|
}
|
|
// Always Remove group if exists
|
this.removeElement(this.legendProxyGroup);
|
|
// Skip everything if we do not have legend items, or if we have a
|
// color axis
|
if (!items || !items.length || chart.colorAxis && chart.colorAxis.length || !chart.options.legend.accessibility.enabled) {
|
return;
|
}
|
|
// Add proxy group
|
this.legendProxyGroup = this.addProxyGroup({
|
'aria-label': chart.langFormat('accessibility.legendLabel'),
|
'role': a11yOptions.landmarkVerbosity === 'all' ? 'region' : null
|
});
|
|
// Proxy the legend items
|
items.forEach(function (item) {
|
if (item.legendItem && item.legendItem.element) {
|
item.a11yProxyElement = component.createProxyButton(item.legendItem, component.legendProxyGroup, {
|
tabindex: -1,
|
'aria-pressed': !item.visible,
|
'aria-label': chart.langFormat('accessibility.legendItem', {
|
chart: chart,
|
itemName: component.stripTags(item.name)
|
})
|
},
|
// Consider useHTML
|
item.legendGroup.div ? item.legendItem : item.legendGroup,
|
// Additional click event (fires first)
|
function () {
|
// Keep track of when we should ignore next render
|
component.legendProxyButtonClicked = true;
|
});
|
}
|
});
|
},
|
|
/**
|
* Get keyboard navigation handler for this component.
|
* @return {Highcharts.KeyboardNavigationHandler}
|
*/
|
getKeyboardNavigation: function getKeyboardNavigation() {
|
var keys = this.keyCodes,
|
component = this,
|
chart = this.chart,
|
a11yOptions = chart.options.accessibility;
|
return new _KeyboardNavigationHandler2.default(chart, {
|
keyCodeMap: [
|
// Arrow key handling
|
[[keys.left, keys.right, keys.up, keys.down], function (keyCode) {
|
var direction = keyCode === keys.left || keyCode === keys.up ? -1 : 1;
|
|
// Try to highlight next/prev legend item
|
var res = chart.highlightLegendItem(component.highlightedLegendItemIx + direction);
|
if (res) {
|
component.highlightedLegendItemIx += direction;
|
return this.response.success;
|
}
|
|
// Failed, can we wrap around?
|
if (chart.legend.allItems.length > 1 && a11yOptions.keyboardNavigation.wrapAround) {
|
// Wrap around if we failed and have more than 1 item
|
this.init(direction);
|
return this.response.success;
|
}
|
|
// No wrap, move
|
return this.response[direction > 0 ? 'next' : 'prev'];
|
}],
|
|
// Click item
|
[[keys.enter, keys.space], function () {
|
var legendItem = chart.legend.allItems[component.highlightedLegendItemIx];
|
if (legendItem && legendItem.a11yProxyElement) {
|
_Globals2.default.fireEvent(legendItem.a11yProxyElement, 'click');
|
}
|
return this.response.success;
|
}]],
|
|
// Only run this module if we have at least one legend - wait for
|
// it - item. Don't run if the legend is populated by a colorAxis.
|
// Don't run if legend navigation is disabled.
|
validate: function validate() {
|
var legendOptions = chart.options.legend;
|
return chart.legend && chart.legend.allItems && chart.legend.display && !(chart.colorAxis && chart.colorAxis.length) && legendOptions && legendOptions.accessibility && legendOptions.accessibility.enabled && legendOptions.accessibility.keyboardNavigation && legendOptions.accessibility.keyboardNavigation.enabled;
|
},
|
|
// Focus first/last item
|
init: function init(direction) {
|
var ix = direction > 0 ? 0 : chart.legend.allItems.length - 1;
|
chart.highlightLegendItem(ix);
|
component.highlightedLegendItemIx = ix;
|
}
|
});
|
}
|
|
});
|
|
exports.default = LegendComponent;
|