Explorar o código

Selection converter working only on view elements. Added utils.js file to share isImageWidget method.

Szymon Kupś %!s(int64=9) %!d(string=hai) anos
pai
achega
00a096985e

+ 16 - 18
packages/ckeditor5-image/src/converters.js

@@ -6,6 +6,7 @@
 import ViewContainerElement from '../engine/view/containerelement.js';
 import ViewEmptyElement from '../engine/view/emptyelement.js';
 import ModelElement from '../engine/model/element.js';
+import { isImageWidget } from './utils.js';
 
 const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';
 
@@ -20,33 +21,30 @@ const WIDGET_SELECTED_CLASS_NAME = 'ck-widget_selected';
  * @returns {Function}
  */
 export function modelToViewSelection( t ) {
-	let selected;
+	let previouslySelected;
 
 	return ( evt, data, consumable, conversionApi ) => {
 		const viewSelection = conversionApi.viewSelection;
-		const modelSelection = data.selection;
+		const selectedElement = viewSelection.getSelectedElement();
 
-		const nodeAfter = modelSelection.anchor.nodeAfter;
-		const nodeBefore = modelSelection.focus.nodeBefore;
-
-		if ( selected && selected.hasClass( WIDGET_SELECTED_CLASS_NAME ) ) {
-			selected.removeClass( WIDGET_SELECTED_CLASS_NAME );
+		if ( !selectedElement || !isImageWidget( selectedElement ) ) {
+			return;
 		}
 
-		// Check if model selection is over image and create fake selection in the view.
-		if ( !modelSelection.isCollapsed && nodeAfter && nodeAfter.name == 'image' && nodeAfter == nodeBefore ) {
-			let fakeSelectionLabel = t( 'image widget' );
-			const altText = nodeAfter.getAttribute( 'alt' );
+		if ( previouslySelected && previouslySelected.hasClass( WIDGET_SELECTED_CLASS_NAME ) ) {
+			previouslySelected.removeClass( WIDGET_SELECTED_CLASS_NAME );
+		}
 
-			if ( altText ) {
-				fakeSelectionLabel = `${ altText } ${ fakeSelectionLabel }`;
-			}
+		let fakeSelectionLabel = t( 'image widget' );
+		const altText = selectedElement.getAttribute( 'alt' );
 
-			viewSelection.setFake( true, { label: fakeSelectionLabel } );
-			const viewElement = conversionApi.mapper.toViewElement( nodeAfter );
-			viewElement.addClass( WIDGET_SELECTED_CLASS_NAME );
-			selected = viewElement;
+		if ( altText ) {
+			fakeSelectionLabel = `${ altText } ${ fakeSelectionLabel }`;
 		}
+
+		viewSelection.setFake( true, { label: fakeSelectionLabel } );
+		selectedElement.addClass( WIDGET_SELECTED_CLASS_NAME );
+		previouslySelected = selectedElement;
 	};
 }
 

+ 18 - 20
packages/ckeditor5-image/src/image.js

@@ -6,7 +6,8 @@
 import Feature from '../core/feature.js';
 import ImageEngine from './imageengine.js';
 import ModelRange from '../engine/model/range.js';
-import MouseDownObserver from './mousedownobserver.js';
+import MouseObserver from '../engine/view/observer/mouseobserver.js';
+import { isImageWidget } from './utils.js';
 
 /**
  * The image feature.
@@ -31,42 +32,39 @@ export default class Image extends Feature {
 		const viewDocument = this.editor.editing.view;
 
 		// If mouse down is pressed create selection over whole view element.
-		viewDocument.addObserver( MouseDownObserver );
+		viewDocument.addObserver( MouseObserver );
 		this.listenTo( viewDocument, 'mousedown', ( ...args ) => this._onMousedown( ...args ) );
 	}
 
 	/**
-	 * Handles `mousedown` event. If image widget is event's target then new selection in model is created around that
-	 * element.
+	 * Handles `mousedown` event.
 	 *
 	 * @private
 	 * @param {utils.EventInfo} eventInfo
 	 * @param {envine.view.observer.DomEventData} domEventData
 	 */
 	_onMousedown( eventInfo, domEventData ) {
-		const target = domEventData.target;
+		let widgetElement = domEventData.target;
 		const viewDocument = this.editor.editing.view;
 
-		if ( isImageWidget( target ) ) {
-			domEventData.preventDefault();
+		// If target is not a widgetElement - check if one of the parents is.
+		if ( !isImageWidget( widgetElement ) ) {
+			widgetElement = widgetElement.findAncestor( element => isImageWidget( element ) );
 
-			// Focus editor if is not focused already.
-			if ( !viewDocument.isFocused ) {
-				viewDocument.focus();
+			if ( !widgetElement ) {
+				return;
 			}
+		}
+
+		domEventData.preventDefault();
 
-			createModelSelectionOverElement( this.editor, target );
+		// Focus editor if is not focused already.
+		if ( !viewDocument.isFocused ) {
+			viewDocument.focus();
 		}
-	}
-}
 
-// Checks if provided {@link engine.view.Element} is instance of image widget.
-//
-// @private
-// @param {engine.view.Element} viewElement
-// @returns {Boolean}
-function isImageWidget( viewElement ) {
-	return viewElement.isWidget && viewElement.name == 'figure' && viewElement.hasClass( 'image' );
+		createModelSelectionOverElement( this.editor, widgetElement );
+	}
 }
 
 // Creates model selection over provided {@link engine.view.Element view Element} and calls

+ 0 - 40
packages/ckeditor5-image/src/mousedownobserver.js

@@ -1,40 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import DomEventObserver from '../engine/view/observer/domeventobserver.js';
-
-/**
- * {@link engine.view.Document#mousedown} event observer.
- *
- * Note that this observer is not available by default. To make it available it needs to be added to {@link engine.view.Document}
- * by {@link engine.view.Document#addObserver} method.
- *
- * @memberOf image
- * @extends engine.view.observer.DomEventObserver
- */
-export default class MouseDownObserver extends DomEventObserver {
-	constructor( document ) {
-		super( document );
-
-		this.domEventType = 'mousedown';
-	}
-
-	onDomEvent( domEvent ) {
-		this.fire( domEvent.type, domEvent );
-	}
-}
-
-/**
- * Fired when mouse button is pressed down on one of the editables.
- *
- * Introduced by {@link image.MouseDownObserver}.
- *
- * Note that this event is not available by default. To make it available {@link image.MouseDownObserver} needs to be added
- * to {@link engine.view.Document} by a {@link engine.view.Document#addObserver} method.
- *
- * @see image.MouseDownObserver
- * @event engine.view.Document#mousedown
- * @param {engine.view.observer.DomEventData} data Event data.
- */

+ 14 - 0
packages/ckeditor5-image/src/utils.js

@@ -0,0 +1,14 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * Checks if provided {@link engine.view.Element} is instance of image widget.
+ *
+ * @param {engine.view.Element} viewElement
+ * @returns {Boolean}
+ */
+export function isImageWidget( viewElement ) {
+	return viewElement.isWidget && viewElement.name == 'figure' && viewElement.hasClass( 'image' );
+}

+ 0 - 38
packages/ckeditor5-image/tests/mousedownobserver.js

@@ -1,38 +0,0 @@
-/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/* globals document */
-/* bender-tags: view, browser-only */
-
-import MouseDownObserver from 'ckeditor5/image/mousedownobserver.js';
-import ViewDocument from 'ckeditor5/engine/view/document.js';
-
-describe( 'MouseDownObserver', () => {
-	let viewDocument, observer;
-
-	beforeEach( () => {
-		viewDocument = new ViewDocument();
-		observer = viewDocument.addObserver( MouseDownObserver );
-	} );
-
-	it( 'should define domEventType', () => {
-		expect( observer.domEventType ).to.equal( 'mousedown' );
-	} );
-
-	describe( 'onDomEvent', () => {
-		it( 'should fire mousedown with the right event data', () => {
-			const spy = sinon.spy();
-
-			viewDocument.on( 'mousedown', spy );
-
-			observer.onDomEvent( { type: 'mousedown', target: document.body } );
-
-			expect( spy.calledOnce ).to.be.true;
-
-			const data = spy.args[ 0 ][ 1 ];
-			expect( data.domTarget ).to.equal( document.body );
-		} );
-	} );
-} );