block-navigation.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. var jumpToCode = (function init() {
  2. // Classes of code we would like to highlight in the file view
  3. var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
  4. // Elements to highlight in the file listing view
  5. var fileListingElements = ['td.pct.low'];
  6. // We don't want to select elements that are direct descendants of another match
  7. var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
  8. // Selecter that finds elements on the page to which we can jump
  9. var selector =
  10. fileListingElements.join(', ') +
  11. ', ' +
  12. notSelector +
  13. missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
  14. // The NodeList of matching elements
  15. var missingCoverageElements = document.querySelectorAll(selector);
  16. var currentIndex;
  17. function toggleClass(index) {
  18. missingCoverageElements
  19. .item(currentIndex)
  20. .classList.remove('highlighted');
  21. missingCoverageElements.item(index).classList.add('highlighted');
  22. }
  23. function makeCurrent(index) {
  24. toggleClass(index);
  25. currentIndex = index;
  26. missingCoverageElements.item(index).scrollIntoView({
  27. behavior: 'smooth',
  28. block: 'center',
  29. inline: 'center'
  30. });
  31. }
  32. function goToPrevious() {
  33. var nextIndex = 0;
  34. if (typeof currentIndex !== 'number' || currentIndex === 0) {
  35. nextIndex = missingCoverageElements.length - 1;
  36. } else if (missingCoverageElements.length > 1) {
  37. nextIndex = currentIndex - 1;
  38. }
  39. makeCurrent(nextIndex);
  40. }
  41. function goToNext() {
  42. var nextIndex = 0;
  43. if (
  44. typeof currentIndex === 'number' &&
  45. currentIndex < missingCoverageElements.length - 1
  46. ) {
  47. nextIndex = currentIndex + 1;
  48. }
  49. makeCurrent(nextIndex);
  50. }
  51. return function jump(event) {
  52. if (
  53. document.getElementById('fileSearch') === document.activeElement &&
  54. document.activeElement != null
  55. ) {
  56. // if we're currently focused on the search input, we don't want to navigate
  57. return;
  58. }
  59. switch (event.which) {
  60. case 78: // n
  61. case 74: // j
  62. goToNext();
  63. break;
  64. case 66: // b
  65. case 75: // k
  66. case 80: // p
  67. goToPrevious();
  68. break;
  69. }
  70. };
  71. })();
  72. window.addEventListener('keydown', jumpToCode);