maidr 2.17.3 → 2.19.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
 
3
- <img src="logo/logo.svg" width="350px" alt="A stylized MAIDR logo, with curved characters for M A, a hand pointing for an I, the D character, and R represented in braille."/>
3
+ <img src="assets/logo.svg" width="350px" alt="A stylized MAIDR logo, with curved characters for M A, a hand pointing for an I, the D character, and R represented in braille."/>
4
4
 
5
5
  <hr style="color:transparent" />
6
6
  <br />
package/dist/maidr.js CHANGED
@@ -129,6 +129,7 @@ class Constants {
129
129
  * @default 'verbose'
130
130
  */
131
131
  textMode = 'verbose';
132
+
132
133
  /**
133
134
  * The current braille mode. Can be 'off' or 'on'.
134
135
  * @type {("off"|"on")}
@@ -296,7 +297,7 @@ class Constants {
296
297
  * @default 5000
297
298
  * @memberof AudioProperties
298
299
  */
299
- AUTOPLAY_DURATION = 5000; // 5s
300
+ AUTOPLAY_DURATION = 2000; // 5s
300
301
 
301
302
  // user settings
302
303
  /**
@@ -438,7 +439,7 @@ class Constants {
438
439
  'colorSelected',
439
440
  'MIN_FREQUENCY',
440
441
  'MAX_FREQUENCY',
441
- 'keypressInterval',
442
+ 'AUTOPLAY_DURATION',
442
443
  'ariaMode',
443
444
  'openAIAuthKey',
444
445
  'geminiAuthKey',
@@ -605,10 +606,13 @@ class Constants {
605
606
  * @memberof PlatformControls
606
607
  */
607
608
  end = this.isMac ? 'fn + Right arrow' : 'End';
609
+ /**
610
+ * The interval we wait for an L + X prefix event
611
+ */
612
+ keypressInterval = 2000; // ms or 2s
608
613
 
609
614
  // internal controls
610
615
  // todo: are these even used? Sean doesn't think so (May 2024)
611
- keypressInterval = 2000; // ms or 2s
612
616
  tabMovement = null;
613
617
 
614
618
  // debug stuff
@@ -944,7 +948,11 @@ class Menu {
944
948
  <td>Auto-play speed down</td>
945
949
  <td>Comma (,)</td>
946
950
  </tr>
947
- <tr>
951
+ <tr>
952
+ <td>Auto-play speed reset</td>
953
+ <td>Slash (/)</td>
954
+ </tr>
955
+ <tr>
948
956
  <td>Check label for the title of current plot</td>
949
957
  <td>l t</td>
950
958
  </tr>
@@ -987,16 +995,11 @@ class Menu {
987
995
  <h5 class="modal-title">Settings</h5>
988
996
  <p><input type="range" id="vol" name="vol" min="0" max="1" step=".05"><label for="vol">Volume</label></p>
989
997
  <!-- <p><input type="checkbox" id="show_rect" name="show_rect"><label for="show_rect">Show Outline</label></p> //-->
990
- <p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>
991
- <p><input type="number" min="${
992
- constants.MIN_SPEED
993
- }" max="500" step="${
994
- constants.INTERVAL
995
- }" id="autoplay_rate" name="autoplay_rate"><label for="autoplay_rate">Autoplay Rate</label></p>
996
998
  <p><input type="color" id="color_selected" name="color_selected"><label for="color_selected">Outline Color</label></p>
999
+ <p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>
997
1000
  <p><input type="number" min="10" max="2000" step="10" id="min_freq" name="min_freq"><label for="min_freq">Min Frequency (Hz)</label></p>
998
1001
  <p><input type="number" min="20" max="2010" step="10" id="max_freq" name="max_freq"><label for="max_freq">Max Frequency (Hz)</label></p>
999
- <p><input type="number" min="500" max="5000" step="500" id="keypress_interval" name="keypress_interval"><label for="keypress_interval">Keypress Interval (ms)</label></p>
1002
+ <p> <p><input type="number" min="500" max="500000" step="500" id="AUTOPLAY_DURATION">Autoplay Duration (ms)</label></p>
1000
1003
  <div><fieldset>
1001
1004
  <legend>Aria Mode</legend>
1002
1005
  <p><input type="radio" id="aria_mode_assertive" name="aria_mode" value="assertive" ${
@@ -1262,14 +1265,13 @@ class Menu {
1262
1265
  */
1263
1266
  PopulateData() {
1264
1267
  document.getElementById('vol').value = constants.vol;
1265
- document.getElementById('autoplay_rate').value = constants.autoPlayRate;
1266
1268
  document.getElementById('braille_display_length').value =
1267
1269
  constants.brailleDisplayLength;
1268
1270
  document.getElementById('color_selected').value = constants.colorSelected;
1269
1271
  document.getElementById('min_freq').value = constants.MIN_FREQUENCY;
1270
1272
  document.getElementById('max_freq').value = constants.MAX_FREQUENCY;
1271
- document.getElementById('keypress_interval').value =
1272
- constants.keypressInterval;
1273
+ document.getElementById('AUTOPLAY_DURATION').value =
1274
+ constants.AUTOPLAY_DURATION;
1273
1275
  if (typeof constants.openAIAuthKey == 'string') {
1274
1276
  document.getElementById('openai_auth_key').value =
1275
1277
  constants.openAIAuthKey;
@@ -1355,15 +1357,14 @@ class Menu {
1355
1357
  let shouldReset = this.ShouldLLMReset();
1356
1358
 
1357
1359
  constants.vol = document.getElementById('vol').value;
1358
- constants.autoPlayRate = document.getElementById('autoplay_rate').value;
1359
1360
  constants.brailleDisplayLength = document.getElementById(
1360
1361
  'braille_display_length'
1361
1362
  ).value;
1362
1363
  constants.colorSelected = document.getElementById('color_selected').value;
1363
1364
  constants.MIN_FREQUENCY = document.getElementById('min_freq').value;
1364
1365
  constants.MAX_FREQUENCY = document.getElementById('max_freq').value;
1365
- constants.keypressInterval =
1366
- document.getElementById('keypress_interval').value;
1366
+ constants.AUTOPLAY_DURATION =
1367
+ document.getElementById('AUTOPLAY_DURATION').value;
1367
1368
 
1368
1369
  constants.openAIAuthKey = document.getElementById('openai_auth_key').value;
1369
1370
  constants.geminiAuthKey = document.getElementById('gemini_auth_key').value;
@@ -1517,7 +1518,8 @@ class Menu {
1517
1518
  if (data) {
1518
1519
  for (let i = 0; i < constants.userSettingsKeys.length; i++) {
1519
1520
  constants[constants.userSettingsKeys[i]] =
1520
- data[constants.userSettingsKeys[i]];
1521
+ data[constants.userSettingsKeys[i]] ||
1522
+ constants[constants.userSettingsKeys[i]];
1521
1523
  }
1522
1524
  }
1523
1525
  this.PopulateData();
@@ -2846,9 +2848,6 @@ class Tracker {
2846
2848
  if (!this.isUndefinedOrNull(constants.vol)) {
2847
2849
  eventToLog.volume = Object.assign(constants.vol);
2848
2850
  }
2849
- if (!this.isUndefinedOrNull(constants.autoPlayRate)) {
2850
- eventToLog.autoplay_rate = Object.assign(constants.autoPlayRate);
2851
- }
2852
2851
  if (!this.isUndefinedOrNull(constants.colorSelected)) {
2853
2852
  eventToLog.color = Object.assign(constants.colorSelected);
2854
2853
  }
@@ -2860,6 +2859,9 @@ class Tracker {
2860
2859
  if (!this.isUndefinedOrNull(constants.duration)) {
2861
2860
  eventToLog.tone_duration = Object.assign(constants.duration);
2862
2861
  }
2862
+ if (!this.isUndefinedOrNull(constants.AUTOPLAY_DURATION)) {
2863
+ eventToLog.AUTOPLAY_DURATION = Object.assign(constants.AUTOPLAY_DURATION);
2864
+ }
2863
2865
  if (!this.isUndefinedOrNull(constants.autoPlayOutlierRate)) {
2864
2866
  eventToLog.autoplay_outlier_rate = Object.assign(
2865
2867
  constants.autoPlayOutlierRate
@@ -3967,10 +3969,6 @@ class Display {
3967
3969
  let targetLabel = this.boxplotGridPlaceholders[sectionPos];
3968
3970
  let haveTargetLabel = false;
3969
3971
  let adjustedPos = 0;
3970
- // bookmark: shiny issue: this is being called twice??
3971
- // and the issue happens on 2nd call, sometimes it skips like 75% or whatever
3972
- //
3973
- // on first call, we might call it multiple as we're setting up, I care but let's check that later
3974
3972
 
3975
3973
  if (constants.brailleData) {
3976
3974
  for (let i = 0; i < constants.brailleData.length; i++) {
@@ -4673,6 +4671,10 @@ class Display {
4673
4671
 
4674
4672
  // Step 2: normalize and allocate remaining characters and add to our main braille array
4675
4673
  let charsAvailable = constants.brailleDisplayLength - numAllocatedChars;
4674
+ // Bug happened here: if our numAllocatedChars is bigger than brailleDisplayLength, it cuts off chars
4675
+ // temp fix: just let it overflow by setting charsAvailable to positive if it's below 0. Or maybe 5 to still give us some play
4676
+ // todo: real solution should probably be to kill outliers that are too close together
4677
+ if (charsAvailable < 5) charsAvailable = 5;
4676
4678
  let allocateCharacters = this.AllocateCharacters(lenData, charsAvailable);
4677
4679
  // apply allocation
4678
4680
  let brailleData = lenData;
@@ -5086,9 +5088,8 @@ class BarChart {
5086
5088
  }
5087
5089
  }
5088
5090
  constants.maxX = this.columnLabels.length;
5089
- constants.autoPlayRate = Math.min(
5090
- Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
5091
- constants.MAX_SPEED
5091
+ constants.autoPlayRate = Math.ceil(
5092
+ constants.AUTOPLAY_DURATION / this.plotData.length
5092
5093
  );
5093
5094
  constants.DEFAULT_SPEED = constants.autoPlayRate;
5094
5095
  if (constants.autoPlayRate < constants.MIN_SPEED) {
@@ -5419,10 +5420,7 @@ class BoxPlot {
5419
5420
  constants.minY = 0;
5420
5421
  constants.maxY = this.plotData.length - 1;
5421
5422
  }
5422
- constants.autoPlayRate = Math.min(
5423
- Math.ceil(constants.AUTOPLAY_DURATION / this.plotData.length),
5424
- constants.MAX_SPEED
5425
- );
5423
+ constants.autoPlayRate = Math.ceil(constants.AUTOPLAY_DURATION / 7);
5426
5424
  constants.DEFAULT_SPEED = constants.autoPlayRate;
5427
5425
  if (constants.autoPlayRate < constants.MIN_SPEED) {
5428
5426
  constants.MIN_SPEED = constants.autoPlayRate;
@@ -6123,9 +6121,8 @@ class HeatMap {
6123
6121
  constants.maxX = this.data[0].length - 1;
6124
6122
  constants.minY = Math.min(...this.data.map((row) => Math.min(...row)));
6125
6123
  constants.maxY = Math.max(...this.data.map((row) => Math.max(...row)));
6126
- constants.autoPlayRate = Math.min(
6127
- Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
6128
- constants.MAX_SPEED
6124
+ constants.autoPlayRate = Math.ceil(
6125
+ constants.AUTOPLAY_DURATION / (constants.maxX + 1)
6129
6126
  );
6130
6127
  constants.DEFAULT_SPEED = constants.autoPlayRate;
6131
6128
  if (constants.autoPlayRate < constants.MIN_SPEED) {
@@ -6797,9 +6794,8 @@ class ScatterPlot {
6797
6794
  constants.minY = Math.min(...yValues);
6798
6795
  constants.maxY = Math.max(...yValues);
6799
6796
 
6800
- constants.autoPlayRate = Math.min(
6801
- Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
6802
- constants.MAX_SPEED
6797
+ constants.autoPlayRate = Math.ceil(
6798
+ constants.AUTOPLAY_DURATION / (constants.maxX + 1)
6803
6799
  );
6804
6800
  constants.DEFAULT_SPEED = constants.autoPlayRate;
6805
6801
  if (constants.autoPlayRate < constants.MIN_SPEED) {
@@ -7349,9 +7345,8 @@ class Histogram {
7349
7345
  }
7350
7346
  }
7351
7347
  }
7352
- constants.autoPlayRate = Math.min(
7353
- Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
7354
- constants.MAX_SPEED
7348
+ constants.autoPlayRate = Math.ceil(
7349
+ constants.AUTOPLAY_DURATION / this.plotData.length
7355
7350
  );
7356
7351
  constants.DEFAULT_SPEED = constants.autoPlayRate;
7357
7352
  if (constants.autoPlayRate < constants.MIN_SPEED) {
@@ -7372,13 +7367,13 @@ class Histogram {
7372
7367
  this.activeElementColor = this.activeElement.getAttribute('fill');
7373
7368
  // Get new color to highlight and replace fill value
7374
7369
  this.activeElement.setAttribute(
7375
- 'fill',
7376
- constants.GetBetterColor(this.activeElementColor)
7370
+ 'fill',
7371
+ constants.GetBetterColor(this.activeElementColor)
7377
7372
  );
7378
7373
  // Case where fill is within the style attribute
7379
7374
  } else if (
7380
- this.activeElement.hasAttribute('style') &&
7381
- this.activeElement.getAttribute('style').indexOf('fill') !== -1
7375
+ this.activeElement.hasAttribute('style') &&
7376
+ this.activeElement.getAttribute('style').indexOf('fill') !== -1
7382
7377
  ) {
7383
7378
  let styleString = this.activeElement.getAttribute('style');
7384
7379
  // Extract all style attributes and values
@@ -7386,7 +7381,7 @@ class Histogram {
7386
7381
  this.activeElementColor = styleArray[styleArray.indexOf('fill') + 1];
7387
7382
  // Get new color to highlight and replace fill value in style array
7388
7383
  styleArray[styleArray.indexOf('fill') + 1] = constants.GetBetterColor(
7389
- this.activeElementColor
7384
+ this.activeElementColor
7390
7385
  );
7391
7386
  // Recreate style string and set style attribute
7392
7387
  styleString = constants.GetStyleStringFromArray(styleArray);
@@ -7411,8 +7406,8 @@ class Histogram {
7411
7406
  this.activeElement.setAttribute('fill', this.activeElementColor);
7412
7407
  this.activeElement = null;
7413
7408
  } else if (
7414
- this.activeElement.hasAttribute('style') &&
7415
- this.activeElement.getAttribute('style').indexOf('fill') !== -1
7409
+ this.activeElement.hasAttribute('style') &&
7410
+ this.activeElement.getAttribute('style').indexOf('fill') !== -1
7416
7411
  ) {
7417
7412
  let styleString = this.activeElement.getAttribute('style');
7418
7413
  let styleArray = constants.GetStyleArrayFromString(styleString);
@@ -7487,9 +7482,8 @@ class LinePlot {
7487
7482
  singleMaidr.data[0].y
7488
7483
  );
7489
7484
 
7490
- constants.autoPlayRate = Math.min(
7491
- Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
7492
- constants.MAX_SPEED
7485
+ constants.autoPlayRate = Math.ceil(
7486
+ constants.AUTOPLAY_DURATION / (constants.maxX + 1)
7493
7487
  );
7494
7488
  constants.DEFAULT_SPEED = constants.autoPlayRate;
7495
7489
  if (constants.autoPlayRate < constants.MIN_SPEED) {
@@ -7991,9 +7985,8 @@ class Segmented {
7991
7985
  }
7992
7986
  }
7993
7987
  constants.maxX = this.level.length;
7994
- constants.autoPlayRate = Math.min(
7995
- Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
7996
- constants.MAX_SPEED
7988
+ constants.autoPlayRate = Math.ceil(
7989
+ constants.AUTOPLAY_DURATION / this.plotData.length
7997
7990
  );
7998
7991
  constants.DEFAULT_SPEED = constants.autoPlayRate;
7999
7992
  if (constants.autoPlayRate < constants.MIN_SPEED) {
@@ -11201,41 +11194,52 @@ function InitMaidr(thisMaidr) {
11201
11194
  // actually do eventlisteners for all events
11202
11195
  this.SetEvents();
11203
11196
 
11197
+ // Set img role for chart
11198
+ constants.chart.setAttribute('role', 'img');
11199
+
11204
11200
  // once everything is set up, announce the chart name (or title as a backup) to the user
11205
- setTimeout(function () {
11206
- if ('name' in singleMaidr) {
11207
- display.announceText(singleMaidr.name);
11208
- } else if (
11209
- 'title' in singleMaidr ||
11210
- ('labels' in singleMaidr && 'title' in singleMaidr.labels)
11211
- ) {
11212
- let title =
11213
- 'title' in singleMaidr ? singleMaidr.title : singleMaidr.labels.title;
11201
+ // setTimeout(function () {
11202
+ if ('name' in singleMaidr) {
11203
+ // Add the aria-label and title attributes to the chart
11204
+ constants.chart.setAttribute('aria-label', announceText);
11205
+ constants.chart.setAttribute('title', announceText);
11206
+
11207
+ // display.announceText(singleMaidr.name);
11208
+ } else if (
11209
+ 'title' in singleMaidr ||
11210
+ ('labels' in singleMaidr && 'title' in singleMaidr.labels)
11211
+ ) {
11212
+ let title =
11213
+ 'title' in singleMaidr ? singleMaidr.title : singleMaidr.labels.title;
11214
11214
 
11215
- // Determine whether type is multiple or single. If multiple, put commas and "and" in between. If single, just put the type.
11216
- let plotTypeString = Array.isArray(singleMaidr.type)
11217
- ? singleMaidr.type.slice(0, -1).join(', ') +
11218
- ' and ' +
11219
- singleMaidr.type.slice(-1)
11220
- : singleMaidr.type;
11215
+ // Determine whether type is multiple or single. If multiple, put commas and "and" in between. If single, just put the type.
11216
+ let plotTypeString = Array.isArray(singleMaidr.type)
11217
+ ? singleMaidr.type.slice(0, -1).join(', ') +
11218
+ ' and ' +
11219
+ singleMaidr.type.slice(-1)
11220
+ : singleMaidr.type;
11221
11221
 
11222
- // Prepare the instruction text for multi-layered plot
11223
- let multiLayerInstruction =
11224
- 'This is a multi-layered plot. Use PageUp and PageDown to switch between layers.';
11222
+ // Prepare the instruction text for multi-layered plot
11223
+ let multiLayerInstruction =
11224
+ 'This is a multi-layered plot. Use PageUp and PageDown to switch between layers.';
11225
11225
 
11226
- // Check if plotTypeString has multiple types
11227
- let isMultiLayered =
11228
- Array.isArray(singleMaidr.type) && singleMaidr.type.length > 1;
11226
+ // Check if plotTypeString has multiple types
11227
+ let isMultiLayered =
11228
+ Array.isArray(singleMaidr.type) && singleMaidr.type.length > 1;
11229
11229
 
11230
- // Construct the final announceText string
11231
- let announceText = `${plotTypeString} plot of ${title}: Use Arrows to navigate data points. ${
11232
- isMultiLayered ? multiLayerInstruction : ' '
11233
- }Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`;
11230
+ // Construct the final announceText string
11231
+ let announceText = `${plotTypeString} plot of ${title}: Use Arrows to navigate data points. ${
11232
+ isMultiLayered ? multiLayerInstruction : ' '
11233
+ }Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`;
11234
11234
 
11235
- // Display the announcement text
11236
- display.announceText(announceText);
11237
- }
11238
- }, 100);
11235
+ // Add the aria-label and title attributes to the chart
11236
+ constants.chart.setAttribute('aria-label', announceText);
11237
+ constants.chart.setAttribute('title', announceText);
11238
+
11239
+ // Display the announcement text
11240
+ // display.announceText(announceText);
11241
+ }
11242
+ // }, 100);
11239
11243
  }
11240
11244
  }
11241
11245
 
@@ -11514,7 +11518,7 @@ function CreateChartComponents() {
11514
11518
  constants.review_id_container +
11515
11519
  '" class="hidden sr-only sr-only-focusable"><input id="' +
11516
11520
  constants.review_id +
11517
- '" type="text" size="50" /></div>'
11521
+ '" type="text" size="50" autocomplete="off" /></div>'
11518
11522
  );
11519
11523
 
11520
11524
  // some tweaks