focusobserver.js 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /**
  2. * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md.
  4. */
  5. /**
  6. * @module engine/view/observer/focusobserver
  7. */
  8. import DomEventObserver from './domeventobserver';
  9. import SelectionObserver from './selectionobserver';
  10. /**
  11. * {@link module:engine/view/document~Document#event:focus Focus}
  12. * and {@link module:engine/view/document~Document#event:blur blur} events observer.
  13. * Focus observer handle also {@link module:engine/view/rooteditableelement~RootEditableElement#isFocused isFocused} property of the
  14. * {@link module:engine/view/rooteditableelement~RootEditableElement root elements}.
  15. *
  16. * Note that this observer is attached by the {@link module:engine/view/document~Document} and is available by default.
  17. *
  18. * @extends module:engine/view/observer/domeventobserver~DomEventObserver
  19. */
  20. export default class FocusObserver extends DomEventObserver {
  21. constructor( document ) {
  22. super( document );
  23. this.domEventType = [ 'focus', 'blur' ];
  24. this.useCapture = true;
  25. this.selectionObserver = document.getObserver( SelectionObserver );
  26. document.on( 'focus', () => {
  27. document.isFocused = true;
  28. // Unfortunately native `selectionchange` event is fired asynchronously.
  29. // We need to wait until `SelectionObserver` handle the event and then render. Otherwise rendering will
  30. // overwrite new DOM selection with selection from the view.
  31. // See https://github.com/ckeditor/ckeditor5-engine/issues/795 for more details.
  32. this.selectionObserver.once( 'selectionChangeHandling', () => {
  33. document.render();
  34. }, { priority: 'low' } );
  35. } );
  36. document.on( 'blur', ( evt, data ) => {
  37. const selectedEditable = document.selection.editableElement;
  38. if ( selectedEditable === null || selectedEditable === data.target ) {
  39. document.isFocused = false;
  40. // Re-render the document to update view elements.
  41. document.render();
  42. }
  43. } );
  44. }
  45. onDomEvent( domEvent ) {
  46. this.fire( domEvent.type, domEvent );
  47. }
  48. }
  49. /**
  50. * Fired when one of the editables gets focus.
  51. *
  52. * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.
  53. *
  54. * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the
  55. * {@link module:engine/view/document~Document}
  56. * this event is available by default.
  57. *
  58. * @see module:engine/view/observer/focusobserver~FocusObserver
  59. * @event module:engine/view/document~Document#event:focus
  60. * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.
  61. */
  62. /**
  63. * Fired when one of the editables loses focus.
  64. *
  65. * Introduced by {@link module:engine/view/observer/focusobserver~FocusObserver}.
  66. *
  67. * Note that because {@link module:engine/view/observer/focusobserver~FocusObserver} is attached by the
  68. * {@link module:engine/view/document~Document}
  69. * this event is available by default.
  70. *
  71. * @see module:engine/view/observer/focusobserver~FocusObserver
  72. * @event module:engine/view/document~Document#event:blur
  73. * @param {module:engine/view/observer/domeventdata~DomEventData} data Event data.
  74. */