8
0
Pārlūkot izejas kodu

Merge branch 'master' into t/1626

Krzysztof Krztoń 7 gadi atpakaļ
vecāks
revīzija
a848218c7b

+ 43 - 37
packages/ckeditor5-engine/src/conversion/downcasthelpers.js

@@ -490,30 +490,33 @@ export function wrap( elementCreator ) {
 	};
 }
 
-// Function factory that creates a converter which converts node insertion changes from the model to the view.
-// The function passed will be provided with all the parameters of the dispatcher's
-// {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert` event}.
-// It is expected that the function returns an {@link module:engine/view/element~Element}.
-// The result of the function will be inserted into the view.
-//
-// The converter automatically consumes the corresponding value from the consumables list, stops the event (see
-// {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}) and binds the model and view elements.
-//
-//		downcastDispatcher.on(
-//			'insert:myElem',
-//			insertElement( ( modelItem, viewWriter ) => {
-//				const text = viewWriter.createText( 'myText' );
-//				const myElem = viewWriter.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );
-//
-//				// Do something fancy with `myElem` using `modelItem` or other parameters.
-//
-//				return myElem;
-//			}
-//		) );
-//
-// @param {Function} elementCreator Function returning a view element, which will be inserted.
-// @returns {Function} Insert element event converter.
-function insertElement( elementCreator ) {
+/**
+ * Function factory that creates a converter which converts node insertion changes from the model to the view.
+ * The function passed will be provided with all the parameters of the dispatcher's
+ * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert` event}.
+ * It is expected that the function returns an {@link module:engine/view/element~Element}.
+ * The result of the function will be inserted into the view.
+ *
+ * The converter automatically consumes the corresponding value from the consumables list, stops the event (see
+ * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}) and binds the model and view elements.
+ *
+ *		downcastDispatcher.on(
+ *			'insert:myElem',
+ *			insertElement( ( modelItem, viewWriter ) => {
+ *				const text = viewWriter.createText( 'myText' );
+ *				const myElem = viewWriter.createElement( 'myElem', { myAttr: 'my-' + modelItem.getAttribute( 'myAttr' ) }, text );
+ *
+ *				// Do something fancy with `myElem` using `modelItem` or other parameters.
+ *
+ *				return myElem;
+ *			}
+ *		) );
+ *
+ * @protected
+ * @param {Function} elementCreator Function returning a view element, which will be inserted.
+ * @returns {Function} Insert element event converter.
+ */
+export function insertElement( elementCreator ) {
 	return ( evt, data, conversionApi ) => {
 		const viewElement = elementCreator( data.item, conversionApi.writer );
 
@@ -532,19 +535,22 @@ function insertElement( elementCreator ) {
 	};
 }
 
-// Function factory that creates a converter which converts marker adding change to the
-// {@link module:engine/view/uielement~UIElement view UI element}.
-//
-// The view UI element that will be added to the view depends on the passed parameter. See {@link ~insertElement}.
-// In case of a non-collapsed range, the UI element will not wrap nodes but separate elements will be placed at the beginning
-// and at the end of the range.
-//
-// This converter binds created UI elements with the marker name using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.
-//
-// @param {module:engine/view/uielement~UIElement|Function} elementCreator A view UI element or a function returning the view element
-// that will be inserted.
-// @returns {Function} Insert element event converter.
-function insertUIElement( elementCreator ) {
+/**
+ * Function factory that creates a converter which converts marker adding change to the
+ * {@link module:engine/view/uielement~UIElement view UI element}.
+ *
+ * The view UI element that will be added to the view depends on the passed parameter. See {@link ~insertElement}.
+ * In case of a non-collapsed range, the UI element will not wrap nodes but separate elements will be placed at the beginning
+ * and at the end of the range.
+ *
+ * This converter binds created UI elements with the marker name using {@link module:engine/conversion/mapper~Mapper#bindElementToMarker}.
+ *
+ * @protected
+ * @param {module:engine/view/uielement~UIElement|Function} elementCreator A view UI element or a function returning the view element
+ * that will be inserted.
+ * @returns {Function} Insert element event converter.
+ */
+export function insertUIElement( elementCreator ) {
 	return ( evt, data, conversionApi ) => {
 		// Create two view elements. One will be inserted at the beginning of marker, one at the end.
 		// If marker is collapsed, only "opening" element will be inserted.

+ 10 - 49
packages/ckeditor5-engine/src/dev-utils/model.js

@@ -32,7 +32,7 @@ import {
 	convertRangeSelection,
 	convertCollapsedSelection,
 } from '../conversion/downcast-selection-converters';
-import { insertText, wrap } from '../conversion/downcasthelpers';
+import { insertElement, insertText, insertUIElement, wrap } from '../conversion/downcasthelpers';
 
 import { isPlainObject } from 'lodash-es';
 import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
@@ -225,59 +225,20 @@ export function stringify( node, selectionOrPositionOrRange = null, markers = nu
 			converter( evt, data, conversionApi );
 		}
 	} );
-	downcastDispatcher.on( 'insert', ( evt, data, conversionApi ) => {
-		const attributes = convertAttributes( data.item.getAttributes(), stringifyAttributeValue );
-		const viewElement = new ViewContainerElement( data.item.name, attributes );
+	downcastDispatcher.on( 'insert', insertElement( modelItem => {
+		// Stringify object types values for properly display as an output string.
+		const attributes = convertAttributes( modelItem.getAttributes(), stringifyAttributeValue );
 
-		if ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {
-			return;
-		}
-
-		const viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
-
-		conversionApi.mapper.bindElements( data.item, viewElement );
-		conversionApi.writer.insert( viewPosition, viewElement );
-	} );
+		return new ViewContainerElement( modelItem.name, attributes );
+	} ) );
 
 	downcastDispatcher.on( 'selection', convertRangeSelection() );
 	downcastDispatcher.on( 'selection', convertCollapsedSelection() );
-	downcastDispatcher.on( 'addMarker', ( evt, data, conversionApi ) => {
-		const elementCreator = ( data, writer ) => {
-			const name = data.markerName + ':' + ( data.isOpening ? 'start' : 'end' );
-
-			return writer.createUIElement( name );
-		};
-
-		// Create two view elements. One will be inserted at the beginning of marker, one at the end.
-		// If marker is collapsed, only "opening" element will be inserted.
-		data.isOpening = true;
-		const viewStartElement = elementCreator( data, conversionApi.writer );
-
-		data.isOpening = false;
-		const viewEndElement = elementCreator( data, conversionApi.writer );
-
-		const markerRange = data.markerRange;
+	downcastDispatcher.on( 'addMarker', insertUIElement( ( data, writer ) => {
+		const name = data.markerName + ':' + ( data.isOpening ? 'start' : 'end' );
 
-		// If marker's range is not collapsed - consume all items inside.
-		for ( const value of markerRange ) {
-			conversionApi.consumable.consume( value.item, evt.name );
-		}
-
-		const mapper = conversionApi.mapper;
-		const viewWriter = conversionApi.writer;
-
-		// Add "opening" element.
-		viewWriter.insert( mapper.toViewPosition( markerRange.start ), viewStartElement );
-		conversionApi.mapper.bindElementToMarker( viewStartElement, data.markerName );
-
-		// Add "closing" element only if range is not collapsed.
-		if ( !markerRange.isCollapsed ) {
-			viewWriter.insert( mapper.toViewPosition( markerRange.end ), viewEndElement );
-			conversionApi.mapper.bindElementToMarker( viewEndElement, data.markerName );
-		}
-
-		evt.stop();
-	} );
+		return writer.createUIElement( name );
+	} ) );
 
 	// Convert model to view.
 	const writer = view._writer;