Browse Source

Refactor and document MouseSelectionHandler.

Maciej Gołaszewski 6 years ago
parent
commit
3f819c0cca
1 changed files with 129 additions and 57 deletions
  1. 129 57
      packages/ckeditor5-table/src/tableselection/mouseselectionhandler.js

+ 129 - 57
packages/ckeditor5-table/src/tableselection/mouseselectionhandler.js

@@ -13,75 +13,147 @@ import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
 import { findAncestor } from '../commands/utils';
 import { findAncestor } from '../commands/utils';
 import MouseEventsObserver from './mouseeventsobserver';
 import MouseEventsObserver from './mouseeventsobserver';
 
 
+/**
+ * A mouse selection handler for table selection.
+ *
+ * It observes view document mouse events and invokes proper {@link module:table/tableselection~TableSelection} actions.
+ */
 export default class MouseSelectionHandler {
 export default class MouseSelectionHandler {
+	/**
+	 * Creates instance of `MouseSelectionHandler`.
+	 *
+	 * @param {module:table/tableselection~TableSelection} tableSelection
+	 * @param {module:engine/controller/editingcontroller~EditingController} editing
+	 */
 	constructor( tableSelection, editing ) {
 	constructor( tableSelection, editing ) {
+		/**
+		 * Table selection.
+		 *
+		 * @private
+		 * @readonly
+		 * @member {module:table/tableselection~TableSelection}
+		 */
+		this._tableSelection = tableSelection;
+
+		/**
+		 * Editing mapper.
+		 *
+		 * @private
+		 * @readonly
+		 * @member {module:engine/conversion/mapper~Mapper}
+		 */
+		this._mapper = editing.mapper;
+
 		const view = editing.view;
 		const view = editing.view;
-		const viewDocument = view.document;
-		const mapper = editing.mapper;
 
 
+		// Currently the MouseObserver only handles `mouseup` events.
 		view.addObserver( MouseEventsObserver );
 		view.addObserver( MouseEventsObserver );
 
 
-		this.listenTo( viewDocument, 'mousedown', ( eventInfo, domEventData ) => {
-			const tableCell = getModelTableCellFromViewEvent( domEventData, mapper );
-
-			if ( !tableCell ) {
-				tableSelection.stopSelection();
-				tableSelection.clearSelection();
-
-				return;
-			}
-
-			tableSelection.startSelectingFrom( tableCell );
-		} );
-
-		this.listenTo( viewDocument, 'mousemove', ( eventInfo, domEventData ) => {
-			if ( !tableSelection._isSelecting ) {
-				return;
-			}
-
-			const tableCell = getModelTableCellFromViewEvent( domEventData, mapper );
-
-			if ( !tableCell ) {
-				return;
-			}
-
-			tableSelection.setSelectingTo( tableCell );
-		} );
-
-		this.listenTo( viewDocument, 'mouseup', ( eventInfo, domEventData ) => {
-			if ( !tableSelection._isSelecting ) {
-				return;
-			}
-
-			const tableCell = getModelTableCellFromViewEvent( domEventData, mapper );
-
-			tableSelection.stopSelection( tableCell );
-		} );
-
-		this.listenTo( viewDocument, 'mouseleave', () => {
-			if ( !tableSelection._isSelecting ) {
-				return;
-			}
-
-			tableSelection.stopSelection();
-		} );
+		this.listenTo( view.document, 'mousedown', ( eventInfo, domEventData ) => this._handleMouseDown( domEventData ) );
+		this.listenTo( view.document, 'mousemove', ( eventInfo, domEventData ) => this._handleMouseMove( domEventData ) );
+		this.listenTo( view.document, 'mouseup', ( eventInfo, domEventData ) => this._handleMouseUp( domEventData ) );
+		this.listenTo( view.document, 'mouseleave', () => this._handleMouseLeave() );
 	}
 	}
-}
 
 
-mix( MouseSelectionHandler, ObservableMixin );
+	/**
+	 * Handles starting a selection when "mousedown" event has table cell target.
+	 *
+	 * If no table cell in event target it will clear previous selection.
+	 *
+	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
+	 * @private
+	 */
+	_handleMouseDown( domEventData ) {
+		const tableCell = this._getModelTableCellFromDomEvent( domEventData );
+
+		if ( !tableCell ) {
+			this._tableSelection.stopSelection();
+			this._tableSelection.clearSelection();
+
+			return;
+		}
+
+		this._tableSelection.startSelectingFrom( tableCell );
+	}
 
 
-// Finds model table cell for given DOM event - ie. for 'mousedown'.
-function getModelTableCellFromViewEvent( domEventData, mapper ) {
-	const viewTargetElement = domEventData.target;
-	const modelElement = mapper.toModelElement( viewTargetElement );
+	/**
+	 * Handles updating table selection when "mousemove" event has a table cell target.
+	 *
+	 * Does nothing if no table cell in event target or selection is not started.
+	 *
+	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
+	 * @private
+	 */
+	_handleMouseMove( domEventData ) {
+		if ( !this._tableSelection._isSelecting ) {
+			return;
+		}
+
+		const tableCell = this._getModelTableCellFromDomEvent( domEventData );
+
+		if ( !tableCell ) {
+			return;
+		}
+
+		this._tableSelection.setSelectingTo( tableCell );
+	}
 
 
-	if ( !modelElement ) {
-		return;
+	/**
+	 * Handles ending (not clearing) table selection on "mouseup" event.
+	 *
+	 * Does nothing if selection is not started.
+	 *
+	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
+	 * @private
+	 */
+	_handleMouseUp( domEventData ) {
+		if ( !this._tableSelection._isSelecting ) {
+			return;
+		}
+
+		const tableCell = this._getModelTableCellFromDomEvent( domEventData );
+
+		// Selection can be stopped if table cell is undefined.
+		this._tableSelection.stopSelection( tableCell );
 	}
 	}
 
 
-	if ( modelElement.is( 'tableCell' ) ) {
-		return modelElement;
+	/**
+	 * Handles stopping a selection on "mouseleave" event.
+	 *
+	 * Does nothing if selection is not started.
+	 *
+	 * @private
+	 */
+	_handleMouseLeave() {
+		if ( !this._tableSelection._isSelecting ) {
+			return;
+		}
+
+		this._tableSelection.stopSelection();
 	}
 	}
 
 
-	return findAncestor( 'tableCell', modelElement );
+	/**
+	 * Finds model table cell for given DOM event.
+	 *
+	 * @private
+	 * @param {module:engine/view/observer/domeventdata~DomEventData} domEventData
+	 * @returns {module:engine/model/element~Element|undefined} Returns model table cell or undefined event target is not
+	 * a mapped table cell.
+	 */
+	_getModelTableCellFromDomEvent( domEventData ) {
+		const viewTargetElement = domEventData.target;
+		const modelElement = this._mapper.toModelElement( viewTargetElement );
+
+		if ( !modelElement ) {
+			return;
+		}
+
+		if ( modelElement.is( 'tableCell' ) ) {
+			return modelElement;
+		}
+
+		return findAncestor( 'tableCell', modelElement );
+	}
 }
 }
+
+mix( MouseSelectionHandler, ObservableMixin );