listview.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**
  2. * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module ui/list/listview
  7. */
  8. import View from '../view';
  9. import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
  10. import FocusCycler from '../focuscycler';
  11. import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
  12. import '../../theme/components/list/list.css';
  13. /**
  14. * The list view class.
  15. *
  16. * @extends module:ui/view~View
  17. * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable
  18. */
  19. export default class ListView extends View {
  20. /**
  21. * @inheritDoc
  22. */
  23. constructor() {
  24. super();
  25. /**
  26. * Collection of the child list views.
  27. *
  28. * @readonly
  29. * @member {module:ui/viewcollection~ViewCollection}
  30. */
  31. this.items = this.createCollection();
  32. /**
  33. * Tracks information about DOM focus in the list.
  34. *
  35. * @readonly
  36. * @member {module:utils/focustracker~FocusTracker}
  37. */
  38. this.focusTracker = new FocusTracker();
  39. /**
  40. * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
  41. *
  42. * @readonly
  43. * @member {module:utils/keystrokehandler~KeystrokeHandler}
  44. */
  45. this.keystrokes = new KeystrokeHandler();
  46. /**
  47. * Helps cycling over focusable {@link #items} in the list.
  48. *
  49. * @readonly
  50. * @protected
  51. * @member {module:ui/focuscycler~FocusCycler}
  52. */
  53. this._focusCycler = new FocusCycler( {
  54. focusables: this.items,
  55. focusTracker: this.focusTracker,
  56. keystrokeHandler: this.keystrokes,
  57. actions: {
  58. // Navigate list items backwards using the arrowup key.
  59. focusPrevious: 'arrowup',
  60. // Navigate toolbar items forwards using the arrowdown key.
  61. focusNext: 'arrowdown',
  62. }
  63. } );
  64. this.setTemplate( {
  65. tag: 'ul',
  66. attributes: {
  67. class: [
  68. 'ck',
  69. 'ck-reset',
  70. 'ck-list'
  71. ]
  72. },
  73. children: this.items
  74. } );
  75. }
  76. /**
  77. * @inheritDoc
  78. */
  79. render() {
  80. super.render();
  81. // Items added before rendering should be known to the #focusTracker.
  82. for ( const item of this.items ) {
  83. this.focusTracker.add( item.element );
  84. }
  85. this.items.on( 'add', ( evt, item ) => {
  86. this.focusTracker.add( item.element );
  87. } );
  88. this.items.on( 'remove', ( evt, item ) => {
  89. this.focusTracker.remove( item.element );
  90. } );
  91. // Start listening for the keystrokes coming from #element.
  92. this.keystrokes.listenTo( this.element );
  93. }
  94. /**
  95. * Focuses the first focusable in {@link #items}.
  96. */
  97. focus() {
  98. this._focusCycler.focusFirst();
  99. }
  100. /**
  101. * Focuses the last focusable in {@link #items}.
  102. */
  103. focusLast() {
  104. this._focusCycler.focusLast();
  105. }
  106. }