classiceditorui.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module editor-classic/classiceditorui
  7. */
  8. import ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory';
  9. import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
  10. import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
  11. /**
  12. * The classic editor UI class.
  13. */
  14. export default class ClassicEditorUI {
  15. /**
  16. * Creates an instance of the editor UI class.
  17. *
  18. * @param {module:core/editor/editor~Editor} editor The editor instance.
  19. * @param {module:ui/editorui/editoruiview~EditorUIView} view View of the ui.
  20. */
  21. constructor( editor, view ) {
  22. /**
  23. * Editor that the UI belongs to.
  24. *
  25. * @readonly
  26. * @member {module:core/editor/editor~Editor}
  27. */
  28. this.editor = editor;
  29. /**
  30. * View of the ui.
  31. *
  32. * @readonly
  33. * @member {module:ui/editorui/editoruiview~EditorUIView}
  34. */
  35. this.view = view;
  36. /**
  37. * Instance of the {@link module:ui/componentfactory~ComponentFactory}.
  38. *
  39. * @readonly
  40. * @member {module:ui/componentfactory~ComponentFactory}
  41. */
  42. this.componentFactory = new ComponentFactory( editor );
  43. /**
  44. * Keeps information about editor focus.
  45. *
  46. * @readonly
  47. * @member {module:utils/focustracker~FocusTracker}
  48. */
  49. this.focusTracker = new FocusTracker();
  50. /**
  51. * Instance of the {@link module:core/keystrokehandler~KeystrokeHandler}.
  52. * Unlike {@link core/editor/standardeditor~StandardEditor#keystrokes}, this
  53. * keystroke handler is focused on keystrokes associated exclusively with the
  54. * user interface, not edited content. It takes care of accessibility–related
  55. * keystrokes (i.e. focus the toolbar) and similar, leaving content
  56. * keystrokes (i.e. bold text, insert link) to aforementioned instance
  57. * in `StandardEditor`.
  58. *
  59. * @readonly
  60. * @member {module:core/keystrokehandler~KeystrokeHandler}
  61. */
  62. this.keystrokes = new KeystrokeHandler();
  63. // Set–up the view.
  64. view.set( 'width', editor.config.get( 'ui.width' ) );
  65. view.set( 'height', editor.config.get( 'ui.height' ) );
  66. // Set–up the toolbar.
  67. view.toolbar.bind( 'isActive' ).to( this.focusTracker, 'isFocused' );
  68. view.toolbar.limiterElement = view.element;
  69. // Setup the editable.
  70. const editingRoot = editor.editing.createRoot( 'div' );
  71. view.editable.bind( 'isReadOnly', 'isFocused' ).to( editingRoot );
  72. view.editable.name = editingRoot.rootName;
  73. this.focusTracker.add( view.editableElement );
  74. }
  75. /**
  76. * Initializes the UI.
  77. *
  78. * @returns {Promise} A Promise resolved when the initialization process is finished.
  79. */
  80. init() {
  81. const editor = this.editor;
  82. return this.view.init()
  83. .then( () => {
  84. const toolbarConfig = editor.config.get( 'toolbar' );
  85. const promises = [];
  86. if ( toolbarConfig ) {
  87. for ( let name of toolbarConfig ) {
  88. promises.push( this.view.toolbar.items.add( this.componentFactory.create( name ) ) );
  89. }
  90. }
  91. return Promise.all( promises );
  92. } )
  93. .then( () => {
  94. const toolbarFocusTracker = this.view.toolbar.focusTracker;
  95. // Because toolbar items can get focus, the overall state of
  96. // the toolbar must also be tracked.
  97. this.focusTracker.add( this.view.toolbar.element );
  98. // Listen on the keystrokes from the main UI.
  99. this.keystrokes.listenTo( this.view.element );
  100. // Listen on the keystrokes from the floating panels, toolbars and the such.
  101. this.keystrokes.listenTo( this.view._bodyCollectionContainer );
  102. // Focus the toolbar on the keystroke, if not already focused.
  103. this.keystrokes.set( 'alt + f10', ( data, cancel ) => {
  104. if ( this.focusTracker.isFocused && !toolbarFocusTracker.isFocused ) {
  105. this.view.toolbar.focus();
  106. cancel();
  107. }
  108. } );
  109. // Blur the toolbar and bring the focus back to editable on the keystroke.
  110. this.keystrokes.set( 'esc', ( data, cancel ) => {
  111. if ( toolbarFocusTracker.isFocused ) {
  112. editor.editing.view.focus();
  113. cancel();
  114. }
  115. } );
  116. } );
  117. }
  118. /**
  119. * Destroys the UI.
  120. *
  121. * @returns {Promise} A Promise resolved when the destruction process is finished.
  122. */
  123. destroy() {
  124. return this.view.destroy();
  125. }
  126. }