Explorar o código

Added selectionChangeHandling event to SelectionObserver and listening to it in FocusObserver.

Szymon Kupś %!s(int64=8) %!d(string=hai) anos
pai
achega
304f69c837

+ 11 - 0
packages/ckeditor5-engine/src/view/observer/focusobserver.js

@@ -8,6 +8,7 @@
  */
 
 import DomEventObserver from './domeventobserver';
+import SelectionObserver from './selectionobserver';
 
 /**
  * {@link module:engine/view/document~Document#event:focus Focus}
@@ -26,8 +27,18 @@ export default class FocusObserver extends DomEventObserver {
 		this.domEventType = [ 'focus', 'blur' ];
 		this.useCapture = true;
 
+		this.selectionObserver = document.getObserver( SelectionObserver );
+
 		document.on( 'focus', () => {
 			document.isFocused = true;
+
+			// Unfortunately native `selectionchange` event is fired asynchronously.
+			// Wait until `SelectionObserver` handle the event and then render. Otherwise rendering will overwrite new DOM
+			// selection with selection from the view.
+			// See https://github.com/ckeditor/ckeditor5-engine/issues/795 for more details.
+			this.selectionObserver.once( 'selectionChangeHandling', () => {
+				document.render();
+			}, { priority: 'low' } );
 		} );
 
 		document.on( 'blur', ( evt, data ) => {

+ 14 - 1
packages/ckeditor5-engine/src/view/observer/selectionobserver.js

@@ -85,6 +85,10 @@ export default class SelectionObserver extends Observer {
 
 		this._clearInfiniteLoopInterval = setInterval( () => this._clearInfiniteLoop(), 2000 );
 
+		this.on( 'selectionChangeHandling', ( evt, data ) => {
+			this._handleSelectionChange( data.domDocument );
+		} );
+
 		/**
 		 * Private property to store the last selection, to check if the code does not enter infinite loop.
 		 *
@@ -119,7 +123,7 @@ export default class SelectionObserver extends Observer {
 		}
 
 		this.listenTo( domDocument, 'selectionchange', () => {
-			this._handleSelectionChange( domDocument );
+			this.fire( 'selectionChangeHandling', { domDocument } );
 		} );
 
 		this._documents.add( domDocument );
@@ -270,3 +274,12 @@ export default class SelectionObserver extends Observer {
  * @param {module:engine/view/selection~Selection} data.newSelection New View selection which is converted DOM selection.
  * @param {Selection} data.domSelection Native DOM selection.
  */
+
+/**
+ * Fired when selection change is being handled.
+ *
+ * @event module:engine/view/observer/selectionobserver~SelectionObserver#event:selectionChangeHandling
+ * @param {Object} data
+ * @param {Document} domDocument DOM document on which selectionchange event was fired.
+ */
+