MenubarItemLinks.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * This content is licensed according to the W3C Software License at
  3. * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
  4. */
  5. var MenubarItem = function (domNode, menuObj) {
  6. this.menu = menuObj;
  7. this.domNode = domNode;
  8. this.popupMenu = false;
  9. this.hasFocus = false;
  10. this.hasHover = false;
  11. this.isMenubarItem = true;
  12. this.keyCode = Object.freeze({
  13. 'TAB': 9,
  14. 'RETURN': 13,
  15. 'ESC': 27,
  16. 'SPACE': 32,
  17. 'PAGEUP': 33,
  18. 'PAGEDOWN': 34,
  19. 'END': 35,
  20. 'HOME': 36,
  21. 'LEFT': 37,
  22. 'UP': 38,
  23. 'RIGHT': 39,
  24. 'DOWN': 40
  25. });
  26. };
  27. MenubarItem.prototype.init = function () {
  28. this.domNode.tabIndex = -1;
  29. this.domNode.addEventListener('keydown', this.handleKeydown.bind(this));
  30. this.domNode.addEventListener('focus', this.handleFocus.bind(this));
  31. this.domNode.addEventListener('blur', this.handleBlur.bind(this));
  32. this.domNode.addEventListener('mouseover', this.handleMouseover.bind(this));
  33. this.domNode.addEventListener('mouseout', this.handleMouseout.bind(this));
  34. // Initialize pop up menus
  35. var nextElement = this.domNode.nextElementSibling;
  36. if (nextElement && nextElement.tagName === 'UL') {
  37. this.popupMenu = new PopupMenu(nextElement, this);
  38. this.popupMenu.init();
  39. }
  40. };
  41. MenubarItem.prototype.handleKeydown = function (event) {
  42. var tgt = event.currentTarget,
  43. char = event.key,
  44. flag = false,
  45. clickEvent;
  46. function isPrintableCharacter (str) {
  47. return str.length === 1 && str.match(/\S/);
  48. }
  49. switch (event.keyCode) {
  50. case this.keyCode.SPACE:
  51. case this.keyCode.RETURN:
  52. case this.keyCode.DOWN:
  53. if (this.popupMenu) {
  54. this.popupMenu.open();
  55. this.popupMenu.setFocusToFirstItem();
  56. flag = true;
  57. }
  58. break;
  59. case this.keyCode.LEFT:
  60. this.menu.setFocusToPreviousItem(this);
  61. flag = true;
  62. break;
  63. case this.keyCode.RIGHT:
  64. this.menu.setFocusToNextItem(this);
  65. flag = true;
  66. break;
  67. case this.keyCode.UP:
  68. if (this.popupMenu) {
  69. this.popupMenu.open();
  70. this.popupMenu.setFocusToLastItem();
  71. flag = true;
  72. }
  73. break;
  74. case this.keyCode.HOME:
  75. case this.keyCode.PAGEUP:
  76. this.menu.setFocusToFirstItem();
  77. flag = true;
  78. break;
  79. case this.keyCode.END:
  80. case this.keyCode.PAGEDOWN:
  81. this.menu.setFocusToLastItem();
  82. flag = true;
  83. break;
  84. case this.keyCode.TAB:
  85. this.popupMenu.close(true);
  86. break;
  87. case this.keyCode.ESC:
  88. this.popupMenu.close(true);
  89. break;
  90. default:
  91. if (isPrintableCharacter(char)) {
  92. this.menu.setFocusByFirstCharacter(this, char);
  93. flag = true;
  94. }
  95. break;
  96. }
  97. if (flag) {
  98. event.stopPropagation();
  99. event.preventDefault();
  100. }
  101. };
  102. MenubarItem.prototype.setExpanded = function (value) {
  103. if (value) {
  104. this.domNode.setAttribute('aria-expanded', 'true');
  105. }
  106. else {
  107. this.domNode.setAttribute('aria-expanded', 'false');
  108. }
  109. };
  110. MenubarItem.prototype.handleFocus = function (event) {
  111. this.menu.hasFocus = true;
  112. };
  113. MenubarItem.prototype.handleBlur = function (event) {
  114. this.menu.hasFocus = false;
  115. };
  116. MenubarItem.prototype.handleMouseover = function (event) {
  117. this.hasHover = true;
  118. this.popupMenu.open();
  119. };
  120. MenubarItem.prototype.handleMouseout = function (event) {
  121. this.hasHover = false;
  122. setTimeout(this.popupMenu.close.bind(this.popupMenu, false), 300);
  123. };