maidr 2.13.0 → 2.14.1

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
@@ -397,22 +397,19 @@ To learn more about the theoretical background and user study results, we recomm
397
397
  }
398
398
  ```
399
399
 
400
- 1. [Born Accessible Data Science and Visualization Courses: Challenges of Developing Curriculum to be Taught by Blind Instructors to Blind Students](https://arxiv.org/abs/2403.02568v1):
400
+ 2. [Designing Born-Accessible Courses in Data Science and Visualization: Challenges and Opportunities of a Remote Curriculum Taught by Blind Instructors to Blind Students](https://diglib.eg.org:8443/server/api/core/bitstreams/6d392735-a045-46bb-867c-90b0a538b1b7/content):
401
401
 
402
402
  ```tex
403
- @misc{seoBornAccessibleData2024,
404
- title = {Born {{Accessible Data Science}} and {{Visualization Courses}}: {{Challenges}} of {{Developing Curriculum}} to Be {{Taught}} by {{Blind Instructors}} to {{Blind Students}}},
405
- shorttitle = {Born {{Accessible Data Science}} and {{Visualization Courses}}},
406
- author = {Seo, JooYoung and O'Modhrain, Sile and Xia, Yilin and Kamath, Sanchita and Lee, Bongshin and Coughlan, James M.},
407
- year = {2024},
408
- month = mar,
409
- number = {arXiv:2403.02568},
410
- eprint = {2403.02568},
411
- primaryclass = {cs},
412
- publisher = {{arXiv}},
413
- urldate = {2024-03-08},
414
- archiveprefix = {arxiv},
415
- keywords = {Computer Science - Human-Computer Interaction}
403
+ @inproceedings{10.2312:eved.20241053,
404
+ booktitle = {EuroVis 2024 - Education Papers},
405
+ editor = {Firat, Elif E. and Laramee, Robert S. and Andersen, Nicklas Sindelv},
406
+ title = {{Designing Born-Accessible Courses in Data Science and Visualization: Challenges and Opportunities of a Remote Curriculum Taught by Blind Instructors
407
+ to Blind Students}},
408
+ author = {JooYoung Seo and Sile O'Modhrain and Yilin Xia and Sanchita Kamath and Bongshin Lee and James M. Coughlan},
409
+ year = {2024},
410
+ publisher = {The Eurographics Association},
411
+ isbn = {978-3-03868-257-8},
412
+ doi = {10.2312/eved.20241053}
416
413
  }
417
414
  ```
418
415
 
package/dist/maidr.js CHANGED
@@ -396,7 +396,7 @@ class Constants {
396
396
  * @default 1
397
397
  * @memberof AdvancedUserSettings
398
398
  */
399
- isTracking = 1;
399
+ isTracking = 0;
400
400
  /**
401
401
  * How are we representing braille? like, is it 1:1 with the chart, or do we do some compression and try to represent as accuratly as we can? Not currently in use.
402
402
  * @type {boolean}
@@ -1662,6 +1662,16 @@ class ChatLLM {
1662
1662
  ]);
1663
1663
  }
1664
1664
 
1665
+ /**
1666
+ * Copies the chat history to the clipboard in markdown format.
1667
+ * We do this by running on any click or keyup event on the chatLLM modal so we can handle all the cases.
1668
+ * If e is undefined, the entire chat history is copied.
1669
+ * If e.type is click, we see what button was clicked and copy just that block or the entire thing
1670
+ * If e.type is keyup, we check for alt shift c or ctrl shift c and copy the last message,
1671
+ * or ctrl shift a for the entire chat history
1672
+ *
1673
+ * @param {Event|undefined} e - The event that triggered the copy action. If undefined, the entire chat history is copied.
1674
+ */
1665
1675
  CopyChatHistory(e) {
1666
1676
  let text = '';
1667
1677
  if (typeof e == 'undefined') {
@@ -1708,9 +1718,9 @@ class ChatLLM {
1708
1718
  let removeThese = cleanElems.querySelectorAll('.chatLLM_message_copy');
1709
1719
  removeThese.forEach((elem) => elem.remove());
1710
1720
 
1711
- // convert to markdown
1721
+ // convert from html to markdown
1712
1722
  let markdown = this.htmlToMarkdown(cleanElems);
1713
- // kill more than 2 newlines in a row
1723
+ // this messes up a bit with spacing, so kill more than 2 newlines in a row
1714
1724
  markdown = markdown.replace(/\n{3,}/g, '\n\n');
1715
1725
 
1716
1726
  try {
@@ -4433,6 +4443,11 @@ class Display {
4433
4443
  globalMax = constants.maxX;
4434
4444
  }
4435
4445
 
4446
+ // exception: return if we're out of bounds
4447
+ if (plotPos < 0 || plotPos >= plot.plotData.length) {
4448
+ return;
4449
+ }
4450
+
4436
4451
  // We convert main plot data to array of values and types, including min and max, and seperating outliers and removing nulls
4437
4452
  let valData = [];
4438
4453
  valData.push({ type: 'global_min', value: globalMin });
@@ -4698,8 +4713,6 @@ class Display {
4698
4713
  }
4699
4714
  }
4700
4715
 
4701
- constants.brailleInput.value = brailleArray.join('');
4702
-
4703
4716
  constants.brailleInput.value = brailleArray.join('');
4704
4717
  if (constants.debugLevel > 5) {
4705
4718
  console.log('braille:', constants.brailleInput.value);
@@ -8210,35 +8223,30 @@ class Control {
8210
8223
  constants.lastx = 0;
8211
8224
  let lastPlayed = '';
8212
8225
 
8213
- // testing for braille cursor routing
8214
- /*
8226
+ // braille cursor routing
8215
8227
  document.addEventListener('selectionchange', function (e) {
8216
- // notes:
8217
- // this basically works
8218
- // constants.braillInput.selectionStart is the key, and is the position,
8219
- // but it starts at 1, so we need to subtract 1 to get the actual position
8220
- // hard part is that we need to wire this through the whole script
8221
- // event is selectionchange, so we'll either need to refactor and do separate events + functions for this,
8222
- // or pull UpdateAll() etc into their own area so it can be triggered from anywhere
8223
- // ... ideally let's do that. Better yet, have a global UpdateAll, not per chart
8224
-
8225
- const selection = document.getSelection();
8226
- console.log('Testing cursor routing', new Date().toLocaleTimeString());
8227
- console.log('selection: ', selection);
8228
- let pos = constants.brailleInput.selectionStart;
8229
- console.log('Position: ', pos);
8230
- position.x = pos - 1; // selection starts at 1, so we subtract 1 to get the actual position
8231
- let testEnd = lockPosition();
8232
-
8233
- // update display / text / audio
8234
- if (testEnd) {
8235
- UpdateAll();
8236
- }
8237
- if (testEnd) {
8238
- audio.playEnd();
8228
+ if (constants.brailleMode == 'on') {
8229
+ let pos = constants.brailleInput.selectionStart;
8230
+ // we're using braille cursor, update the selection from what was clicked
8231
+ pos = constants.brailleInput.selectionStart;
8232
+ if (pos < 0) {
8233
+ pos = 0;
8234
+ }
8235
+ position.x = pos;
8236
+ lockPosition();
8237
+ let testEnd = true;
8238
+
8239
+ // update display / text / audio
8240
+ if (testEnd) {
8241
+ UpdateAll();
8242
+ }
8243
+ if (testEnd) {
8244
+ audio.playEnd();
8245
+ }
8246
+ } else {
8247
+ // we're using normal cursor, let the default handle it
8239
8248
  }
8240
8249
  });
8241
- */
8242
8250
 
8243
8251
  // control eventlisteners
8244
8252
  constants.events.push([
@@ -8417,17 +8425,19 @@ class Control {
8417
8425
  function lockPosition() {
8418
8426
  // lock to min / max postions
8419
8427
  let didLockHappen = false;
8420
- // if (!constants.hasRect) {
8421
- // return didLockHappen;
8422
- // }
8423
8428
 
8424
8429
  if (position.x < 0) {
8425
8430
  position.x = 0;
8426
8431
  didLockHappen = true;
8432
+ if (constants.brailleMode != 'off') {
8433
+ // change selection to match postion as well
8434
+ constants.brailleInput.selectionEnd = 0;
8435
+ }
8427
8436
  }
8428
8437
  if (position.x > plot.plotData.length - 1) {
8429
8438
  position.x = plot.plotData.length - 1;
8430
8439
  didLockHappen = true;
8440
+ constants.brailleInput.selectionEnd = plot.plotData.length - 1;
8431
8441
  }
8432
8442
 
8433
8443
  return didLockHappen;
@@ -8514,6 +8524,59 @@ class Control {
8514
8524
  }
8515
8525
  let lastPlayed = '';
8516
8526
 
8527
+ // braille cursor routing
8528
+ // bug: still not working. Not really sure what's going on but the tethering is now totally broken
8529
+ // like, it doesn't even seem to be on the right plot
8530
+ document.addEventListener('selectionchange', function (e) {
8531
+ e.preventDefault();
8532
+ if (
8533
+ constants.brailleMode == 'on' &&
8534
+ constants.brailleInput.selectionStart
8535
+ ) {
8536
+ let cursorPos = constants.brailleInput.selectionStart;
8537
+ // we're using braille cursor, update the selection from what was clicked
8538
+ cursorPos = constants.brailleInput.selectionStart;
8539
+ if (cursorPos < 0) {
8540
+ pos = 0;
8541
+ }
8542
+ // convert braille position to start of whatever section we're in
8543
+ let walk = 0;
8544
+ let posType = '';
8545
+ if (constants.brailleData) {
8546
+ for (let i = 0; i < constants.brailleData.length; i++) {
8547
+ walk += constants.brailleData[i].numChars;
8548
+ if (walk > cursorPos) {
8549
+ if (constants.brailleData[i].type == 'blank') {
8550
+ posType = constants.brailleData[i + 1].type;
8551
+ } else {
8552
+ posType = constants.brailleData[i].type;
8553
+ }
8554
+ break;
8555
+ }
8556
+ }
8557
+ }
8558
+ let pos = plot.sections.indexOf(posType);
8559
+
8560
+ if (posType.length > 0) {
8561
+ if (constants.plotOrientation == 'vert') {
8562
+ position.y = pos;
8563
+ } else {
8564
+ position.x = pos;
8565
+ }
8566
+ lockPosition();
8567
+ let testEnd = true;
8568
+
8569
+ // update display / text / audio
8570
+ if (testEnd) {
8571
+ UpdateAll();
8572
+ }
8573
+ if (testEnd) {
8574
+ audio.playEnd();
8575
+ }
8576
+ }
8577
+ }
8578
+ });
8579
+
8517
8580
  // control eventlisteners
8518
8581
  constants.events.push([
8519
8582
  constants.chart,
@@ -8526,12 +8589,14 @@ class Control {
8526
8589
  if (e.key == 'ArrowRight') {
8527
8590
  if (constants.isMac ? e.metaKey : e.ctrlKey) {
8528
8591
  if (e.shiftKey) {
8592
+ // autoplay
8529
8593
  if (constants.plotOrientation == 'vert') {
8530
8594
  Autoplay('right', position.x, plot.plotData.length - 1);
8531
8595
  } else {
8532
8596
  Autoplay('right', position.x, plot.sections.length - 1);
8533
8597
  }
8534
8598
  } else {
8599
+ // move to end
8535
8600
  isAtEnd = lockPosition();
8536
8601
  if (constants.plotOrientation == 'vert') {
8537
8602
  position.x = plot.plotData.length - 1;
@@ -8550,6 +8615,7 @@ class Control {
8550
8615
  lastY = position.y;
8551
8616
  Autoplay('reverse-right', plot.plotData.length - 1, position.x);
8552
8617
  } else {
8618
+ // normal movement
8553
8619
  if (position.x == -1 && position.y == plot.sections.length) {
8554
8620
  position.y -= 1;
8555
8621
  }
@@ -9122,6 +9188,45 @@ class Control {
9122
9188
  let lastPlayed = '';
9123
9189
  constants.lastx = 0;
9124
9190
 
9191
+ document.addEventListener('selectionchange', function (e) {
9192
+ if (constants.brailleMode == 'on') {
9193
+ let pos = constants.brailleInput.selectionStart;
9194
+
9195
+ // exception: don't let users click the seperator char
9196
+ let seperatorPositions = constants.brailleInput.value
9197
+ .split('')
9198
+ .reduce((positions, char, index) => {
9199
+ if (char === '⠳') positions.push(index);
9200
+ return positions;
9201
+ }, []);
9202
+ if (seperatorPositions.includes(pos)) {
9203
+ return;
9204
+ }
9205
+
9206
+ // we're using braille cursor, update the selection from what was clicked
9207
+ pos = constants.brailleInput.selectionStart;
9208
+ if (pos < 0) {
9209
+ pos = 0;
9210
+ }
9211
+
9212
+ // actual position is based on num_cols and num_rows and the spacer
9213
+ position.y = Math.floor(pos / (plot.num_cols + 1));
9214
+ position.x = pos % (plot.num_cols + 1);
9215
+ lockPosition();
9216
+ let testEnd = true;
9217
+
9218
+ // update display / text / audio
9219
+ if (testEnd) {
9220
+ UpdateAll();
9221
+ }
9222
+ if (testEnd) {
9223
+ audio.playEnd();
9224
+ }
9225
+ } else {
9226
+ // we're using normal cursor, let the default handle it
9227
+ }
9228
+ });
9229
+
9125
9230
  // control eventlisteners
9126
9231
  constants.events.push([
9127
9232
  constants.chart,
@@ -9228,6 +9333,8 @@ class Control {
9228
9333
  constants.navigation = 0;
9229
9334
  }
9230
9335
 
9336
+ console.log('position: ' + position.x + ', ' + position.y);
9337
+
9231
9338
  // update text, display, and audio
9232
9339
  if (updateInfoThisRound && !isAtEnd) {
9233
9340
  UpdateAll();
@@ -9747,6 +9854,32 @@ class Control {
9747
9854
  }
9748
9855
  }
9749
9856
 
9857
+ // todo / bug: does'nt work at all on just line (in gallery)
9858
+ // it sorta works in scatter (in gallery), visual highlight changes, but sonify and text don't update
9859
+ document.addEventListener('selectionchange', function (e) {
9860
+ if (constants.brailleMode == 'on') {
9861
+ let pos = constants.brailleInput.selectionStart;
9862
+ // we're using braille cursor, update the selection from what was clicked
9863
+ pos = constants.brailleInput.selectionStart;
9864
+ if (pos < 0) {
9865
+ pos = 0;
9866
+ }
9867
+ positionL1.x = pos;
9868
+ lockPosition();
9869
+ let testEnd = true;
9870
+
9871
+ // update display / text / audio
9872
+ if (testEnd) {
9873
+ UpdateAllBraille();
9874
+ }
9875
+ if (testEnd) {
9876
+ audio.playEnd();
9877
+ }
9878
+ } else {
9879
+ // we're using normal cursor, let the default handle it
9880
+ }
9881
+ });
9882
+
9750
9883
  constants.events.push([
9751
9884
  constants.brailleInput,
9752
9885
  'keydown',
@@ -10048,6 +10181,30 @@ class Control {
10048
10181
  let lastPlayed = '';
10049
10182
  constants.lastx = 0;
10050
10183
 
10184
+ document.addEventListener('selectionchange', function (e) {
10185
+ if (constants.brailleMode == 'on') {
10186
+ let pos = constants.brailleInput.selectionStart;
10187
+ // we're using braille cursor, update the selection from what was clicked
10188
+ pos = constants.brailleInput.selectionStart;
10189
+ if (pos < 0) {
10190
+ pos = 0;
10191
+ }
10192
+ position.x = pos;
10193
+ lockPosition();
10194
+ let testEnd = true;
10195
+
10196
+ // update display / text / audio
10197
+ if (testEnd) {
10198
+ UpdateAll();
10199
+ }
10200
+ if (testEnd) {
10201
+ audio.playEnd();
10202
+ }
10203
+ } else {
10204
+ // we're using normal cursor, let the default handle it
10205
+ }
10206
+ });
10207
+
10051
10208
  // control eventlisteners
10052
10209
  constants.events.push([
10053
10210
  [constants.chart, constants.brailleInput],
@@ -10294,6 +10451,32 @@ class Control {
10294
10451
  let lastPlayed = '';
10295
10452
  constants.lastx = 0;
10296
10453
 
10454
+ // todo bug, forgot about all mode
10455
+ // bug: you can click 1 past end (for all chart types). Make sure we're lockign and then resetting the selectionStart
10456
+ document.addEventListener('selectionchange', function (e) {
10457
+ if (constants.brailleMode == 'on') {
10458
+ let pos = constants.brailleInput.selectionStart;
10459
+ // we're using braille cursor, update the selection from what was clicked
10460
+ pos = constants.brailleInput.selectionStart;
10461
+ if (pos < 0) {
10462
+ pos = 0;
10463
+ }
10464
+ position.x = pos;
10465
+ lockPosition();
10466
+ let testEnd = true;
10467
+
10468
+ // update display / text / audio
10469
+ if (testEnd) {
10470
+ UpdateAll();
10471
+ }
10472
+ if (testEnd) {
10473
+ audio.playEnd();
10474
+ }
10475
+ } else {
10476
+ // we're using normal cursor, let the default handle it
10477
+ }
10478
+ });
10479
+
10297
10480
  // control eventlisteners
10298
10481
  constants.events.push([
10299
10482
  [constants.chart, constants.brailleInput],
@@ -10651,6 +10834,29 @@ class Control {
10651
10834
  let lastPlayed = '';
10652
10835
  constants.lastx = 0;
10653
10836
 
10837
+ // braille cursor routing
10838
+ document.addEventListener('selectionchange', function (e) {
10839
+ if (constants.brailleMode == 'on') {
10840
+ let pos = constants.brailleInput.selectionStart;
10841
+ // we're using braille cursor, update the selection from what was clicked
10842
+ pos = constants.brailleInput.selectionStart;
10843
+ if (pos < 0) {
10844
+ pos = 0;
10845
+ }
10846
+ position.x = pos;
10847
+ lockPosition();
10848
+ let testEnd = true;
10849
+
10850
+ // update display / text / audio
10851
+ if (testEnd) {
10852
+ UpdateAll();
10853
+ }
10854
+ if (testEnd) {
10855
+ audio.playEnd();
10856
+ }
10857
+ }
10858
+ });
10859
+
10654
10860
  // control eventlisteners
10655
10861
  constants.events.push([
10656
10862
  constants.chart,
@@ -11540,6 +11746,7 @@ function CreateChartComponents() {
11540
11746
  constants.brailleDisplayLength +
11541
11747
  '" ' +
11542
11748
  'aria-brailleroledescription="" ' + // this kills the 2 char 'edit' that screen readers add
11749
+ 'autocomplete="off" ' +
11543
11750
  '/>\n</div>\n'
11544
11751
  );
11545
11752