Browse Source

Using custom properties to set and remove virtual selection from view elements.

Szymon Kupś 8 years ago
parent
commit
43bbb991b1

+ 10 - 4
packages/ckeditor5-engine/src/conversion/buildmodelconverter.js

@@ -276,13 +276,18 @@ class ModelConverterBuilder {
 	 * * each {@link module:engine/view/text~Text view text node} in the marker's range will be wrapped with `span`
 	 * {@link module:engine/view/attributeelement~AttributeElement},
 	 * * each {@link module:engine/view/containerelement~ContainerElement container view element} in the marker's
-	 * range can handle the virtual selection individually by providing `setVirtualSelection` and `removeVirtualSelection` methods.
+	 * range can handle the virtual selection individually by providing `setVirtualSelection` and `removeVirtualSelection`
+	 * custom properties:
+	 *
+	 *		viewElement.setCustomProperty( 'setVirtualSelection', ( element, descriptor ) => {} );
+	 *		viewElement.setCustomProperty( 'removeVirtualSelection', ( element, descriptor ) => {} );
 	 *
 	 * {@link module:engine/conversion/buildmodelconverter~VirtualSelectionDescriptor Descriptor} will be used to create
 	 * spans over text nodes and also will be provided to `setVirtualSelection` and `removeVirtualSelection` methods
 	 * each time virtual selection should be set or removed from view elements.
-	 * NOTE: When `setVirtualSelection` and `removeVirtualSelection` methods are present, converter assumes that element
-	 * is taking care of presenting virtual selection on its child nodes, so it won't convert virtual selection on them.
+	 * NOTE: When `setVirtualSelection` and `removeVirtualSelection` custom properties are present, converter assumes
+	 * that element itself is taking care of presenting virtual selection on its child nodes, so it won't convert virtual
+	 * selection on them.
 	 *
 	 * Virtual selection descriptor can be provided as plain object:
 	 *
@@ -423,7 +428,8 @@ export default function buildModelConverter() {
  * @typedef VirtualSelectionDescriptor
  * Object describing how virtual selection should be created in the view. Each text node in virtual selection
  * will be wrapped with `span` element with CSS class, attributes and priority described by this object. Each element
- * can handle virtual selection separately by providing `setVirtualSelection` and `removeVirtualSelection` methods.
+ * can handle virtual selection separately by providing `setVirtualSelection` and `removeVirtualSelection` custom
+ * properties.
  *
  * @property {String} [class] CSS class that will be added to `span`
  * {@link module:engine/view/attributeelement~AttributeElement} wrapping each text node in the virtual selection.

+ 2 - 2
packages/ckeditor5-engine/src/conversion/model-to-view-converters.js

@@ -430,13 +430,13 @@ export function markerToVirtualSelection( selectionDescriptor ) {
 
 			const selectionHandlingMethod = addMarker ? 'setVirtualSelection' : 'removeVirtualSelection';
 
-			if ( viewElement && viewElement[ selectionHandlingMethod ] ) {
+			if ( viewElement && viewElement.getCustomProperty( selectionHandlingMethod ) ) {
 				// Virtual selection will be handled by parent element - consume all children.
 				for ( const value of ModelRange.createIn( modelItem ) ) {
 					consumable.consume( value.item, consumableType );
 				}
 
-				viewElement[ selectionHandlingMethod ]( descriptor );
+				viewElement.getCustomProperty( selectionHandlingMethod )( viewElement, descriptor );
 			}
 		}
 	};

+ 8 - 8
packages/ckeditor5-engine/tests/conversion/model-to-view-converters.js

@@ -131,21 +131,21 @@ describe( 'model-to-view-converters', () => {
 			dispatcher.on( 'addMarker:marker', markerToVirtualSelection( virtualSelectionDescriptor ) );
 			dispatcher.on( 'removeMarker:marker', markerToVirtualSelection( virtualSelectionDescriptor ) );
 			dispatcher.on( 'insert:paragraph', insertElement( () => {
-				const element = new ViewContainerElement( 'p' );
+				const viewContainer = new ViewContainerElement( 'p' );
 
-				element.setVirtualSelection = descriptor => {
+				viewContainer.setCustomProperty( 'setVirtualSelection', ( element, descriptor ) => {
 					element.addClass( 'virtual-selection-own-class' );
 
 					expect( descriptor ).to.equal( virtualSelectionDescriptor );
-				};
+				} );
 
-				element.removeVirtualSelection = descriptor => {
+				viewContainer.setCustomProperty( 'removeVirtualSelection', ( element, descriptor ) => {
 					element.removeClass( 'virtual-selection-own-class' );
 
 					expect( descriptor ).to.equal( virtualSelectionDescriptor );
-				};
+				} );
 
-				return element;
+				return viewContainer;
 			} ), { priority: 'high' } );
 
 			dispatcher.convertInsertion( markerRange );
@@ -179,8 +179,8 @@ describe( 'model-to-view-converters', () => {
 
 			dispatcher.on( 'insert:paragraph', insertElement( () => {
 				const element = new ViewContainerElement( 'p' );
-				element.setVirtualSelection = data => element.addClass( data.class );
-				element.removeVirtualSelection = data => element.removeClass( data.class );
+				element.setCustomProperty( 'setVirtualSelection', ( element, data ) => element.addClass( data.class ) );
+				element.setCustomProperty( 'removeVirtualSelection', ( element, data ) => element.removeClass( data.class ) );
 
 				return element;
 			} ), { priority: 'high' } );

+ 10 - 11
packages/ckeditor5-engine/tests/manual/virtualselection.js

@@ -43,20 +43,19 @@ class FancyWidget extends Plugin {
 		buildModelConverter().for( editing.modelToView )
 			.fromElement( 'fancywidget' )
 			.toElement( () => {
-				const text = new ViewText( 'widget' );
-				const fancyView = new ViewContainerElement( 'figure', { class: 'fancy-widget' }, text );
+				const widgetElement = new ViewContainerElement( 'figure', { class: 'fancy-widget' }, new ViewText( 'widget' ) );
 
-				fancyView.setVirtualSelection = data => {
-					text.data = 'widget - with virtual selection';
-					fancyView.addClass( data.class );
-				};
+				widgetElement.setCustomProperty( 'setVirtualSelection', ( element, data ) => {
+					element.getChild( 0 ).data = 'widget - with virtual selection';
+					element.addClass( data.class );
+				} );
 
-				fancyView.removeVirtualSelection = data => {
-					text.data = 'widget';
-					fancyView.removeClass( data.class );
-				};
+				widgetElement.setCustomProperty( 'removeVirtualSelection', ( element, data ) => {
+					element.getChild( 0 ).data = 'widget';
+					element.removeClass( data.class );
+				} );
 
-				return toWidget( fancyView );
+				return toWidget( widgetElement );
 			} );
 
 		// Build converter from view element to model element for data pipeline.