11/* *
22 *
3- * (c) 2009-2020 Øystein Moseng
3+ * (c) 2009-2021 Øystein Moseng
44 *
55 * Accessibility component for chart info region and table.
66 *
1111 * */
1212import H from '../../Core/Globals.js' ;
1313var doc = H . doc ;
14+ import AST from '../../Core/Renderer/HTML/AST.js' ;
1415import U from '../../Core/Utilities.js' ;
1516var extend = U . extend , format = U . format , pick = U . pick ;
1617import AccessibilityComponent from '../AccessibilityComponent.js' ;
1718import Announcer from '../Utils/Announcer.js' ;
1819import AnnotationsA11y from './AnnotationsA11y.js' ;
1920var getAnnotationsInfoHTML = AnnotationsA11y . getAnnotationsInfoHTML ;
2021import ChartUtilities from '../Utils/ChartUtilities.js' ;
21- var unhideChartElementFromAT = ChartUtilities . unhideChartElementFromAT , getChartTitle = ChartUtilities . getChartTitle , getAxisDescription = ChartUtilities . getAxisDescription ;
22+ var getAxisDescription = ChartUtilities . getAxisDescription , getAxisRangeDescription = ChartUtilities . getAxisRangeDescription , getChartTitle = ChartUtilities . getChartTitle , unhideChartElementFromAT = ChartUtilities . unhideChartElementFromAT ;
2223import HTMLUtilities from '../Utils/HTMLUtilities.js' ;
2324var addClass = HTMLUtilities . addClass , setElAttrs = HTMLUtilities . setElAttrs , escapeStringForHTML = HTMLUtilities . escapeStringForHTML , stripHTMLTagsFromString = HTMLUtilities . stripHTMLTagsFromString , getElement = HTMLUtilities . getElement , visuallyHideElement = HTMLUtilities . visuallyHideElement ;
2425/* eslint-disable no-invalid-this, valid-jsdoc */
26+ /**
27+ * @private
28+ */
29+ function stripEmptyHTMLTags ( str ) {
30+ return str . replace ( / < ( \w + ) [ ^ > ] * ?> \s * < \/ \1> / g, '' ) ;
31+ }
2532/**
2633 * @private
2734 */
@@ -56,27 +63,6 @@ function buildTypeDescriptionFromSeries(chart, types, context) {
5663function getTableSummary ( chart ) {
5764 return chart . langFormat ( 'accessibility.table.tableSummary' , { chart : chart } ) ;
5865}
59- /**
60- * @private
61- */
62- function stripEmptyHTMLTags ( str ) {
63- return str . replace ( / < ( \w + ) [ ^ > ] * ?> \s * < \/ \1> / g, '' ) ;
64- }
65- /**
66- * @private
67- */
68- function enableSimpleHTML ( str ) {
69- return str
70- . replace ( / & l t ; ( h [ 1 - 7 ] | p | d i v | u l | o l | l i ) & g t ; / g, '<$1>' )
71- . replace ( / & l t ; & # x 2 F ; ( h [ 1 - 7 ] | p | d i v | u l | o l | l i | a | b u t t o n ) & g t ; / g, '</$1>' )
72- . replace ( / & l t ; ( d i v | a | b u t t o n ) i d = & q u o t ; ( [ a - z A - Z \- 0 - 9 # ] * ?) & q u o t ; & g t ; / g, '<$1 id="$2">' ) ;
73- }
74- /**
75- * @private
76- */
77- function stringToSimpleHTML ( str ) {
78- return stripEmptyHTMLTags ( enableSimpleHTML ( escapeStringForHTML ( str ) ) ) ;
79- }
8066/**
8167 * Return simplified explaination of chart type. Some types will not be familiar
8268 * to most users, but in those cases we try to add an explaination of the type.
@@ -122,7 +108,7 @@ extend(InfoRegionsComponent.prototype, /** @lends Highcharts.InfoRegionsComponen
122108 var chart = this . chart ;
123109 var component = this ;
124110 this . initRegionsDefinitions ( ) ;
125- this . addEvent ( chart , 'afterGetTable ' , function ( e ) {
111+ this . addEvent ( chart , 'aftergetTableAST ' , function ( e ) {
126112 component . onDataTableCreated ( e ) ;
127113 } ) ;
128114 this . addEvent ( chart , 'afterViewData' , function ( tableDiv ) {
@@ -219,7 +205,7 @@ extend(InfoRegionsComponent.prototype, /** @lends Highcharts.InfoRegionsComponen
219205 updateScreenReaderSection : function ( regionKey ) {
220206 var chart = this . chart , region = this . screenReaderSections [ regionKey ] , content = region . buildContent ( chart ) , sectionDiv = region . element = ( region . element || this . createElement ( 'div' ) ) , hiddenDiv = ( sectionDiv . firstChild || this . createElement ( 'div' ) ) ;
221207 this . setScreenReaderSectionAttribs ( sectionDiv , regionKey ) ;
222- hiddenDiv . innerHTML = content ;
208+ AST . setElementHTML ( hiddenDiv , content ) ;
223209 sectionDiv . appendChild ( hiddenDiv ) ;
224210 region . insertIntoDOM ( sectionDiv , chart ) ;
225211 visuallyHideElement ( hiddenDiv ) ;
@@ -273,7 +259,7 @@ extend(InfoRegionsComponent.prototype, /** @lends Highcharts.InfoRegionsComponen
273259 } , formattedString = H . i18nFormat ( format , context , chart ) ;
274260 this . dataTableButtonId = dataTableButtonId ;
275261 this . sonifyButtonId = sonifyButtonId ;
276- return stringToSimpleHTML ( formattedString ) ;
262+ return stripEmptyHTMLTags ( formattedString ) ;
277263 } ,
278264 /**
279265 * @private
@@ -284,7 +270,7 @@ extend(InfoRegionsComponent.prototype, /** @lends Highcharts.InfoRegionsComponen
284270 . screenReaderSection . afterChartFormat , context = {
285271 endOfChartMarker : this . getEndOfChartMarkerText ( )
286272 } , formattedString = H . i18nFormat ( format , context , chart ) ;
287- return stringToSimpleHTML ( formattedString ) ;
273+ return stripEmptyHTMLTags ( formattedString ) ;
288274 } ,
289275 /**
290276 * @private
@@ -364,7 +350,10 @@ extend(InfoRegionsComponent.prototype, /** @lends Highcharts.InfoRegionsComponen
364350 if ( this . viewDataTableButton ) {
365351 this . viewDataTableButton . setAttribute ( 'aria-expanded' , 'true' ) ;
366352 }
367- e . html = e . html . replace ( '<table ' , '<table tabindex="-1" summary="' + getTableSummary ( chart ) + '"' ) ;
353+ var attributes = e . tree . attributes || { } ;
354+ attributes . tabindex = - 1 ;
355+ attributes . summary = getTableSummary ( chart ) ;
356+ e . tree . attributes = attributes ;
368357 }
369358 } ,
370359 /**
@@ -455,102 +444,19 @@ extend(InfoRegionsComponent.prototype, /** @lends Highcharts.InfoRegionsComponen
455444 * @return {string }
456445 */
457446 getAxisDescriptionText : function ( collectionKey ) {
458- var component = this , chart = this . chart , axes = chart [ collectionKey ] ;
447+ var chart = this . chart ;
448+ var axes = chart [ collectionKey ] ;
459449 return chart . langFormat ( 'accessibility.axis.' + collectionKey + 'Description' + ( axes . length > 1 ? 'Plural' : 'Singular' ) , {
460450 chart : chart ,
461451 names : axes . map ( function ( axis ) {
462452 return getAxisDescription ( axis ) ;
463453 } ) ,
464454 ranges : axes . map ( function ( axis ) {
465- return component . getAxisRangeDescription ( axis ) ;
455+ return getAxisRangeDescription ( axis ) ;
466456 } ) ,
467457 numAxes : axes . length
468458 } ) ;
469459 } ,
470- /**
471- * Return string with text description of the axis range.
472- * @private
473- * @param {Highcharts.Axis } axis The axis to get range desc of.
474- * @return {string } A string with the range description for the axis.
475- */
476- getAxisRangeDescription : function ( axis ) {
477- var axisOptions = axis . options || { } ;
478- // Handle overridden range description
479- if ( axisOptions . accessibility &&
480- typeof axisOptions . accessibility . rangeDescription !== 'undefined' ) {
481- return axisOptions . accessibility . rangeDescription ;
482- }
483- // Handle category axes
484- if ( axis . categories ) {
485- return this . getCategoryAxisRangeDesc ( axis ) ;
486- }
487- // Use time range, not from-to?
488- if ( axis . dateTime && ( axis . min === 0 || axis . dataMin === 0 ) ) {
489- return this . getAxisTimeLengthDesc ( axis ) ;
490- }
491- // Just use from and to.
492- // We have the range and the unit to use, find the desc format
493- return this . getAxisFromToDescription ( axis ) ;
494- } ,
495- /**
496- * @private
497- * @param {Highcharts.Axis } axis
498- * @return {string }
499- */
500- getCategoryAxisRangeDesc : function ( axis ) {
501- var chart = this . chart ;
502- if ( axis . dataMax && axis . dataMin ) {
503- return chart . langFormat ( 'accessibility.axis.rangeCategories' , {
504- chart : chart ,
505- axis : axis ,
506- numCategories : axis . dataMax - axis . dataMin + 1
507- } ) ;
508- }
509- return '' ;
510- } ,
511- /**
512- * @private
513- * @param {Highcharts.Axis } axis
514- * @return {string }
515- */
516- getAxisTimeLengthDesc : function ( axis ) {
517- var chart = this . chart , range = { } , rangeUnit = 'Seconds' ;
518- range . Seconds = ( ( axis . max || 0 ) - ( axis . min || 0 ) ) / 1000 ;
519- range . Minutes = range . Seconds / 60 ;
520- range . Hours = range . Minutes / 60 ;
521- range . Days = range . Hours / 24 ;
522- [ 'Minutes' , 'Hours' , 'Days' ] . forEach ( function ( unit ) {
523- if ( range [ unit ] > 2 ) {
524- rangeUnit = unit ;
525- }
526- } ) ;
527- var rangeValue = range [ rangeUnit ] . toFixed ( rangeUnit !== 'Seconds' &&
528- rangeUnit !== 'Minutes' ? 1 : 0 // Use decimals for days/hours
529- ) ;
530- // We have the range and the unit to use, find the desc format
531- return chart . langFormat ( 'accessibility.axis.timeRange' + rangeUnit , {
532- chart : chart ,
533- axis : axis ,
534- range : rangeValue . replace ( '.0' , '' )
535- } ) ;
536- } ,
537- /**
538- * @private
539- * @param {Highcharts.Axis } axis
540- * @return {string }
541- */
542- getAxisFromToDescription : function ( axis ) {
543- var chart = this . chart , dateRangeFormat = chart . options . accessibility
544- . screenReaderSection . axisRangeDateFormat , format = function ( axisKey ) {
545- return axis . dateTime ? chart . time . dateFormat ( dateRangeFormat , axis [ axisKey ] ) : axis [ axisKey ] ;
546- } ;
547- return chart . langFormat ( 'accessibility.axis.rangeFromTo' , {
548- chart : chart ,
549- axis : axis ,
550- rangeFrom : format ( 'min' ) ,
551- rangeTo : format ( 'max' )
552- } ) ;
553- } ,
554460 /**
555461 * Remove component traces
556462 */
0 commit comments