maidr 2.19.1 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/maidr.js CHANGED
@@ -11102,9 +11102,13 @@ document.addEventListener('DOMContentLoaded', function (e) {
11102
11102
  // set focus events for all maidr ids
11103
11103
  DestroyMaidr(); // just in case
11104
11104
  window.maidrIds = [];
11105
+ let firstMaidr;
11105
11106
  for (let i = 0; i < maidrObjects.length; i++) {
11106
11107
  let maidrId = maidrObjects[i].id;
11107
11108
  maidrIds.push(maidrId);
11109
+ if (!firstMaidr && maidrObjects[i]) {
11110
+ firstMaidr = maidrObjects[i];
11111
+ }
11108
11112
  let maidrElemn = document.getElementById(maidrId);
11109
11113
  if (maidrElemn) {
11110
11114
  maidrElemn.setAttribute('tabindex', '0');
@@ -11115,6 +11119,9 @@ document.addEventListener('DOMContentLoaded', function (e) {
11115
11119
  }
11116
11120
  }
11117
11121
 
11122
+ // init components like alt text on just the first chart
11123
+ CreateChartComponents(firstMaidr, true);
11124
+
11118
11125
  // events etc for user study page
11119
11126
  // run tracker stuff only on user study page
11120
11127
  if (constants.canTrack) {
@@ -11172,7 +11179,11 @@ function InitMaidr(thisMaidr) {
11172
11179
  } else {
11173
11180
  constants.chartType = singleMaidr.type;
11174
11181
  }
11182
+ DestroyChartComponents(); // destroy so that we start fresh, in case we've created on the wrong chart
11175
11183
  CreateChartComponents(singleMaidr);
11184
+
11185
+ window.menu = new Menu();
11186
+ window.chatLLM = new ChatLLM();
11176
11187
  window.control = new Control(); // this inits the actual chart object and Position
11177
11188
  window.review = new Review();
11178
11189
  window.display = new Display();
@@ -11228,7 +11239,7 @@ function InitMaidr(thisMaidr) {
11228
11239
  Array.isArray(singleMaidr.type) && singleMaidr.type.length > 1;
11229
11240
 
11230
11241
  // Construct the final announceText string
11231
- let announceText = `${plotTypeString} plot of ${title}: Use Arrows to navigate data points. ${
11242
+ let announceText = `${plotTypeString} plot of ${title}: Click to activate. Use Arrows to navigate data points. ${
11232
11243
  isMultiLayered ? multiLayerInstruction : ' '
11233
11244
  }Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`;
11234
11245
 
@@ -11447,11 +11458,11 @@ function SetEvents() {
11447
11458
  * - Also sets the constants associated with these elements
11448
11459
  *
11449
11460
  */
11450
- function CreateChartComponents() {
11461
+ function CreateChartComponents(thisMaidr, chartOnly = false) {
11451
11462
  // init html stuff. aria live regions, braille input, etc
11452
11463
 
11453
11464
  // core chart
11454
- let chart = document.getElementById(singleMaidr.id);
11465
+ let chart = document.getElementById(thisMaidr.id);
11455
11466
 
11456
11467
  // we create a structure with a main container, and a chart container
11457
11468
  let main_container = document.createElement('div');
@@ -11463,91 +11474,116 @@ function CreateChartComponents() {
11463
11474
  main_container.appendChild(chart);
11464
11475
  chart.parentNode.replaceChild(chart_container, chart);
11465
11476
  chart_container.appendChild(chart);
11466
- chart.focus(); // focus used to be on chart and just got lost as we rearranged, so redo focus
11477
+ if (!chartOnly) chart.focus(); // focus used to be on chart and just got lost as we rearranged, so redo focus
11467
11478
 
11468
11479
  constants.chart = chart;
11469
11480
  constants.chart_container = chart_container;
11470
11481
  constants.main_container = main_container;
11471
11482
 
11472
- // braille input, pre sibling of chart container
11473
- constants.chart_container.insertAdjacentHTML(
11474
- 'beforebegin',
11475
- '<div class="hidden" id="' +
11476
- constants.braille_container_id +
11477
- '">\n<input id="' +
11478
- constants.braille_input_id +
11479
- '" class="braille-input" type="text" size="' +
11480
- constants.brailleDisplayLength +
11481
- '" ' +
11482
- 'aria-brailleroledescription="" ' + // this kills the 2 char 'edit' that screen readers add
11483
- 'autocomplete="off" ' +
11484
- '/>\n</div>\n'
11485
- );
11486
-
11487
- // info aria live, next sibling of chart container
11488
- constants.chart_container.insertAdjacentHTML(
11489
- 'afterend',
11490
- '<br>\n<div id="' +
11491
- constants.info_id +
11492
- '" aria-live="assertive" aria-atomic="true">\n<p id="x"></p>\n<p id="y"></p>\n</div>\n'
11493
- );
11494
-
11495
- // announcements, next sibling of info
11496
- document
11497
- .getElementById(constants.info_id)
11498
- .insertAdjacentHTML(
11483
+ if (!chartOnly) {
11484
+ // braille input, pre sibling of chart container
11485
+ constants.chart_container.insertAdjacentHTML(
11486
+ 'beforebegin',
11487
+ '<div class="hidden" id="' +
11488
+ constants.braille_container_id +
11489
+ '">\n<input id="' +
11490
+ constants.braille_input_id +
11491
+ '" class="braille-input" type="text" size="' +
11492
+ constants.brailleDisplayLength +
11493
+ '" ' +
11494
+ 'aria-brailleroledescription="" ' + // this kills the 2 char 'edit' that screen readers add
11495
+ 'autocomplete="off" ' +
11496
+ '/>\n</div>\n'
11497
+ );
11498
+
11499
+ // info aria live, next sibling of chart container
11500
+ constants.chart_container.insertAdjacentHTML(
11499
11501
  'afterend',
11500
- '<div id="announcements" aria-live="assertive" aria-atomic="true" class="mb-3"></div>\n'
11502
+ '<br>\n<div id="' +
11503
+ constants.info_id +
11504
+ '" aria-live="assertive" aria-atomic="true">\n<p id="x"></p>\n<p id="y"></p>\n</div>\n'
11501
11505
  );
11502
11506
 
11503
- // end chime audio element
11504
- // TODO: external media file is not working as a stereo audio so commenting this out until we find a solution
11505
- // document
11506
- // .getElementById(constants.info_id)
11507
- // .insertAdjacentHTML(
11508
- // 'afterend',
11509
- // '<div class="hidden"> <audio src="../src/terminalBell.mp3" id="end_chime"></audio> </div>'
11510
- // );
11511
-
11512
- // review mode form field
11513
- document
11514
- .getElementById(constants.info_id)
11515
- .insertAdjacentHTML(
11516
- 'beforebegin',
11517
- '<div id="' +
11518
- constants.review_id_container +
11519
- '" class="hidden sr-only sr-only-focusable"><input id="' +
11520
- constants.review_id +
11521
- '" type="text" size="50" autocomplete="off" /></div>'
11507
+ // announcements, next sibling of info
11508
+ document
11509
+ .getElementById(constants.info_id)
11510
+ .insertAdjacentHTML(
11511
+ 'afterend',
11512
+ '<div id="announcements" aria-live="assertive" aria-atomic="true" class="mb-3"></div>\n'
11513
+ );
11514
+
11515
+ // review mode form field
11516
+ document
11517
+ .getElementById(constants.info_id)
11518
+ .insertAdjacentHTML(
11519
+ 'beforebegin',
11520
+ '<div id="' +
11521
+ constants.review_id_container +
11522
+ '" class="hidden sr-only sr-only-focusable"><input id="' +
11523
+ constants.review_id +
11524
+ '" type="text" size="50" autocomplete="off" /></div>'
11525
+ );
11526
+
11527
+ // some tweaks
11528
+ constants.chart_container.setAttribute('role', 'application');
11529
+
11530
+ // set page elements
11531
+ constants.brailleContainer = document.getElementById(
11532
+ constants.braille_container_id
11533
+ );
11534
+ constants.brailleInput = document.getElementById(
11535
+ constants.braille_input_id
11522
11536
  );
11537
+ constants.infoDiv = document.getElementById(constants.info_id);
11538
+ constants.announceContainer = document.getElementById(
11539
+ constants.announcement_container_id
11540
+ );
11541
+ constants.nonMenuFocus = constants.chart;
11542
+ constants.endChime = document.getElementById(constants.end_chime_id);
11543
+ constants.review_container = document.querySelector(
11544
+ '#' + constants.review_id_container
11545
+ );
11546
+ constants.review = document.querySelector('#' + constants.review_id);
11547
+ //window.description = new Description(); // developement on hold
11548
+ }
11549
+
11550
+ // set screen reader text and attributes
11551
+ let altText = '';
11552
+ // set role of main chart
11553
+ document.getElementById(thisMaidr.id).setAttribute('role', 'img');
11554
+ if ('name' in thisMaidr) {
11555
+ altText = thisMaidr.name;
11556
+ } else if (
11557
+ 'title' in thisMaidr ||
11558
+ ('labels' in thisMaidr && 'title' in thisMaidr.labels)
11559
+ ) {
11560
+ let title = 'title' in thisMaidr ? thisMaidr.title : thisMaidr.labels.title;
11523
11561
 
11524
- // some tweaks
11525
- constants.chart_container.setAttribute('role', 'application');
11526
-
11527
- // set page elements
11528
- constants.brailleContainer = document.getElementById(
11529
- constants.braille_container_id
11530
- );
11531
- constants.brailleInput = document.getElementById(constants.braille_input_id);
11532
- constants.infoDiv = document.getElementById(constants.info_id);
11533
- constants.announceContainer = document.getElementById(
11534
- constants.announcement_container_id
11535
- );
11536
- constants.nonMenuFocus = constants.chart;
11537
- constants.endChime = document.getElementById(constants.end_chime_id);
11538
- constants.review_container = document.querySelector(
11539
- '#' + constants.review_id_container
11540
- );
11541
- constants.review = document.querySelector('#' + constants.review_id);
11542
-
11543
- // help menu
11544
- window.menu = new Menu();
11545
-
11546
- // LLM question modal
11547
- window.chatLLM = new ChatLLM();
11548
-
11549
- // Description modal
11550
- window.description = new Description(); // developement on hold
11562
+ // Determine whether type is multiple or single. If multiple, put commas and "and" in between. If single, just put the type.
11563
+ let plotTypeString = Array.isArray(thisMaidr.type)
11564
+ ? thisMaidr.type.slice(0, -1).join(', ') +
11565
+ ' and ' +
11566
+ thisMaidr.type.slice(-1)
11567
+ : thisMaidr.type;
11568
+
11569
+ // Prepare the instruction text for multi-layered plot
11570
+ let multiLayerInstruction =
11571
+ 'This is a multi-layered plot. Use PageUp and PageDown to switch between layers.';
11572
+
11573
+ // Check if plotTypeString has multiple types
11574
+ let isMultiLayered =
11575
+ Array.isArray(thisMaidr.type) && thisMaidr.type.length > 1;
11576
+
11577
+ // Construct the final announceText string
11578
+ altText = `${plotTypeString} plot of ${title}: Click to activate. Use Arrows to navigate data points. ${
11579
+ isMultiLayered ? multiLayerInstruction : ' '
11580
+ }Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`;
11581
+ }
11582
+ if (altText.length > 0) {
11583
+ // Add the aria-label and title attributes to the chart
11584
+ document.getElementById(thisMaidr.id).setAttribute('aria-label', altText);
11585
+ document.getElementById(thisMaidr.id).setAttribute('title', altText);
11586
+ }
11551
11587
  }
11552
11588
 
11553
11589
  /**
@@ -11585,13 +11621,13 @@ function DestroyChartComponents() {
11585
11621
  constants.review_container.remove();
11586
11622
  }
11587
11623
 
11588
- if (typeof menu != 'undefined') {
11624
+ if (typeof menu !== 'undefined' && menu !== null) {
11589
11625
  menu.Destroy();
11590
11626
  }
11591
- if (typeof description != 'undefined') {
11627
+ if (typeof description !== 'undefined' && description !== null) {
11592
11628
  description.Destroy();
11593
11629
  }
11594
- if (typeof chatLLM != 'undefined') {
11630
+ if (typeof chatLLM !== 'undefined' && chatLLM !== null) {
11595
11631
  chatLLM.Destroy();
11596
11632
  }
11597
11633