smart-keyboard-handler.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /**
  2. * Copyright © Magento, Inc. All rights reserved.
  3. * See COPYING.txt for license details.
  4. */
  5. define([
  6. 'jquery'
  7. ], function ($) {
  8. 'use strict';
  9. /**
  10. * @return {Object}
  11. * @constructor
  12. */
  13. function KeyboardHandler() {
  14. var body = $('body'),
  15. focusState = false,
  16. tabFocusClass = '_keyfocus',
  17. productsGrid = '[data-container="product-grid"]',
  18. catalogProductsGrid = $(productsGrid),
  19. CODE_TAB = 9;
  20. /**
  21. * Handle logic, when onTabKeyPress fired at first.
  22. * Then it changes state.
  23. */
  24. function onFocusInHandler() {
  25. focusState = true;
  26. body.addClass(tabFocusClass)
  27. .off('focusin.keyboardHandler', onFocusInHandler);
  28. }
  29. /**
  30. * Handle logic to remove state after onTabKeyPress to normal.
  31. */
  32. function onClickHandler() {
  33. focusState = false;
  34. body.removeClass(tabFocusClass)
  35. .off('click', onClickHandler);
  36. }
  37. /**
  38. * Tab key onKeypress handler. Apply main logic:
  39. * - call differ actions onTabKeyPress and onClick
  40. */
  41. function smartKeyboardFocus() {
  42. $(document).on('keydown keypress', function (event) {
  43. if (event.which === CODE_TAB && !focusState) {
  44. body
  45. .on('focusin.keyboardHandler', onFocusInHandler)
  46. .on('click', onClickHandler);
  47. }
  48. });
  49. // ARIA support for catalog grid products
  50. if (catalogProductsGrid.length) {
  51. body.on('focusin.gridProducts', productsGrid, function () {
  52. if (body.hasClass(tabFocusClass)) {
  53. $(this).addClass('active');
  54. }
  55. });
  56. body.on('focusout.gridProducts', productsGrid, function () {
  57. $(this).removeClass('active');
  58. });
  59. }
  60. }
  61. /**
  62. * Attach smart focus on specific element.
  63. * @param {jQuery} element
  64. */
  65. function handleFocus(element) {
  66. element.on('focusin.emulateTabFocus', function () {
  67. focusState = true;
  68. body.addClass(tabFocusClass);
  69. element.off();
  70. });
  71. element.on('focusout.emulateTabFocus', function () {
  72. focusState = false;
  73. body.removeClass(tabFocusClass);
  74. element.off();
  75. });
  76. }
  77. return {
  78. apply: smartKeyboardFocus,
  79. focus: handleFocus
  80. };
  81. }
  82. return new KeyboardHandler;
  83. });