utils.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module ui/dropdown/utils
  7. */
  8. /* global document */
  9. /**
  10. * Adds a behavior to a dropdownView that focuses dropdown panel view contents on keystrokes.
  11. *
  12. * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView
  13. * @param {module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable} panelViewContents
  14. */
  15. export function focusDropdownContentsOnArrows( dropdownView, panelViewContents ) {
  16. // If the dropdown panel is already open, the arrow down key should
  17. // focus the first element in list.
  18. dropdownView.keystrokes.set( 'arrowdown', ( data, cancel ) => {
  19. if ( dropdownView.isOpen ) {
  20. panelViewContents.focus();
  21. cancel();
  22. }
  23. } );
  24. // If the dropdown panel is already open, the arrow up key should
  25. // focus the last element in the list.
  26. dropdownView.keystrokes.set( 'arrowup', ( data, cancel ) => {
  27. if ( dropdownView.isOpen ) {
  28. panelViewContents.focusLast();
  29. cancel();
  30. }
  31. } );
  32. }
  33. /**
  34. * Adds a behavior to a dropdownView that closes dropdown view on any view collection item's "execute" event.
  35. *
  36. * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView
  37. * @param {module:ui/viewcollection~ViewCollection} viewCollection
  38. */
  39. export function closeDropdownOnExecute( dropdownView, viewCollection ) {
  40. // TODO: Delegate all events instead of just execute.
  41. viewCollection.delegate( 'execute' ).to( dropdownView );
  42. // Close the dropdown when one of the list items has been executed.
  43. dropdownView.on( 'execute', () => {
  44. dropdownView.isOpen = false;
  45. } );
  46. }
  47. /**
  48. * Adds a behavior to a dropdownView that closes opened dropdown on user click outside the dropdown.
  49. *
  50. * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView
  51. */
  52. export function closeDropdownOnBlur( dropdownView ) {
  53. dropdownView.on( 'change:isOpen', ( evt, name, value ) => {
  54. if ( value ) {
  55. attachDocumentClickListener( document, dropdownView );
  56. } else {
  57. dropdownView.stopListening( document );
  58. }
  59. } );
  60. }
  61. // Attaches a "click" listener in DOM to check if any element outside
  62. // the dropdown has been clicked.
  63. //
  64. // @private
  65. // @param {module:ui/dropdown/listdropdownview~ListDropdownView} dropdownView
  66. function attachDocumentClickListener( document, dropdownView ) {
  67. // TODO: It will probably be focus/blur-based rather than click. It should be bound
  68. // to focusmanager of some sort.
  69. dropdownView.listenTo( document, 'click', ( evtInfo, { target: domEvtTarget } ) => {
  70. // Collapse the dropdown when the webpage outside of the component is clicked.
  71. if ( dropdownView.element != domEvtTarget && !dropdownView.element.contains( domEvtTarget ) ) {
  72. dropdownView.isOpen = false;
  73. }
  74. } );
  75. }