toolbarview.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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/toolbar/toolbarview
  7. */
  8. /* globals console */
  9. import View from '../view';
  10. import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
  11. import FocusCycler from '../focuscycler';
  12. import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
  13. import ToolbarSeparatorView from './toolbarseparatorview';
  14. import preventDefault from '../bindings/preventdefault.js';
  15. import '../../theme/components/toolbar/toolbar.css';
  16. import { attachLinkToDocumentation } from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
  17. /**
  18. * The toolbar view class.
  19. *
  20. * @extends module:ui/view~View
  21. * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable
  22. */
  23. export default class ToolbarView extends View {
  24. /**
  25. * @inheritDoc
  26. */
  27. constructor( locale ) {
  28. super( locale );
  29. const bind = this.bindTemplate;
  30. /**
  31. * Collection of the toolbar items (like buttons).
  32. *
  33. * @readonly
  34. * @member {module:ui/viewcollection~ViewCollection}
  35. */
  36. this.items = this.createCollection();
  37. /**
  38. * Tracks information about DOM focus in the list.
  39. *
  40. * @readonly
  41. * @member {module:utils/focustracker~FocusTracker}
  42. */
  43. this.focusTracker = new FocusTracker();
  44. /**
  45. * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
  46. *
  47. * @readonly
  48. * @member {module:utils/keystrokehandler~KeystrokeHandler}
  49. */
  50. this.keystrokes = new KeystrokeHandler();
  51. /**
  52. * Controls the orientation of toolbar items.
  53. *
  54. * @observable
  55. * @member {Boolean} #isVertical
  56. */
  57. this.set( 'isVertical', false );
  58. /**
  59. * An additional CSS class added to the {@link #element}.
  60. *
  61. * @observable
  62. * @member {String} #class
  63. */
  64. this.set( 'class' );
  65. /**
  66. * Helps cycling over focusable {@link #items} in the toolbar.
  67. *
  68. * @readonly
  69. * @protected
  70. * @member {module:ui/focuscycler~FocusCycler}
  71. */
  72. this._focusCycler = new FocusCycler( {
  73. focusables: this.items,
  74. focusTracker: this.focusTracker,
  75. keystrokeHandler: this.keystrokes,
  76. actions: {
  77. // Navigate toolbar items backwards using the arrow[left,up] keys.
  78. focusPrevious: [ 'arrowleft', 'arrowup' ],
  79. // Navigate toolbar items forwards using the arrow[right,down] keys.
  80. focusNext: [ 'arrowright', 'arrowdown' ]
  81. }
  82. } );
  83. this.setTemplate( {
  84. tag: 'div',
  85. attributes: {
  86. class: [
  87. 'ck',
  88. 'ck-toolbar',
  89. bind.if( 'isVertical', 'ck-toolbar_vertical' ),
  90. bind.to( 'class' )
  91. ]
  92. },
  93. children: this.items,
  94. on: {
  95. // https://github.com/ckeditor/ckeditor5-ui/issues/206
  96. mousedown: preventDefault( this )
  97. }
  98. } );
  99. }
  100. /**
  101. * @inheritDoc
  102. */
  103. render() {
  104. super.render();
  105. // Items added before rendering should be known to the #focusTracker.
  106. for ( const item of this.items ) {
  107. this.focusTracker.add( item.element );
  108. }
  109. this.items.on( 'add', ( evt, item ) => {
  110. this.focusTracker.add( item.element );
  111. } );
  112. this.items.on( 'remove', ( evt, item ) => {
  113. this.focusTracker.remove( item.element );
  114. } );
  115. // Start listening for the keystrokes coming from #element.
  116. this.keystrokes.listenTo( this.element );
  117. }
  118. /**
  119. * Focuses the first focusable in {@link #items}.
  120. */
  121. focus() {
  122. this._focusCycler.focusFirst();
  123. }
  124. /**
  125. * Focuses the last focusable in {@link #items}.
  126. */
  127. focusLast() {
  128. this._focusCycler.focusLast();
  129. }
  130. /**
  131. * A utility which expands a plain toolbar configuration into
  132. * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.
  133. *
  134. * @param {Array.<String>} config The toolbar items config.
  135. * @param {module:ui/componentfactory~ComponentFactory} factory A factory producing toolbar items.
  136. */
  137. fillFromConfig( config, factory ) {
  138. config.map( name => {
  139. if ( name == '|' ) {
  140. this.items.add( new ToolbarSeparatorView() );
  141. } else if ( factory.has( name ) ) {
  142. this.items.add( factory.create( name ) );
  143. } else {
  144. /**
  145. * There was a problem processing the configuration of the toolbar. The item with the given
  146. * name does not exist so it was omitted when rendering the toolbar.
  147. *
  148. * This warning usually shows up when the {@link module:core/plugin~Plugin} which is supposed
  149. * to provide a toolbar item has not been loaded or there is a typo in the configuration.
  150. *
  151. * Make sure the plugin responsible for this toolbar item is loaded and the toolbar configuration
  152. * is correct, e.g. {@link module:basic-styles/bold~Bold} is loaded for the `'bold'` toolbar item.
  153. *
  154. * You can use the following snippet to retrieve all available toolbar items:
  155. *
  156. * Array.from( editor.ui.componentFactory.names() );
  157. *
  158. * @error toolbarview-item-unavailable
  159. * @param {String} name The name of the component.
  160. */
  161. console.warn( attachLinkToDocumentation(
  162. 'toolbarview-item-unavailable: The requested toolbar item is unavailable.', { name } ) );
  163. }
  164. } );
  165. }
  166. }