8
0
Pārlūkot izejas kodu

Changed: Simplified conversion by dropping `selectionMarker` and `selectionAttribute` model-to-view conversion events.
Changed: `view.Writer#wrap` and `view.Writer#wrapPosition` got unified.
Changed: `view.Writer#wrap` has optional, third parameter, a view selection.
Changed: `view.Writer#wrap` will modify view selection if it is collapsed and wrap is at the selection position.

Szymon Cofalik 8 gadi atpakaļ
vecāks
revīzija
1021466da7

+ 21 - 8
packages/ckeditor5-engine/src/dev-utils/model.js

@@ -22,10 +22,10 @@ import ModelDocumentFragment from '../model/documentfragment';
 import DocumentSelection from '../model/documentselection';
 
 import ViewConversionDispatcher from '../conversion/viewconversiondispatcher';
-import ViewSelection from '../view/selection';
-import ViewDocumentFragment from '../view/documentfragment';
+import ViewDocument from '../view/document';
 import ViewContainerElement from '../view/containerelement';
 import ViewAttributeElement from '../view/attributeelement';
+import ViewRootEditableElement from '../view/rooteditableelement';
 
 import Mapper from '../conversion/mapper';
 import { parse as viewParse, stringify as viewStringify } from '../../src/dev-utils/view';
@@ -190,13 +190,21 @@ export function stringify( node, selectionOrPositionOrRange = null ) {
 		selection = new ModelSelection( selectionOrPositionOrRange );
 	}
 
-	// Setup model to view converter.
-	const viewDocumentFragment = new ViewDocumentFragment();
-	const viewSelection = new ViewSelection();
-	const modelToView = new ModelConversionDispatcher( model, { mapper, viewSelection } );
+	// Set up conversion.
+	// Create a temporary view document.
+	const viewDocument = new ViewDocument();
+	const viewRoot = new ViewRootEditableElement( 'div' );
+
+	// Create a temporary root element in view document.
+	viewRoot.document = viewDocument;
+	viewRoot.rootName = 'main';
+	viewDocument.roots.add( viewRoot );
+
+	// Create and setup model to view converter.
+	const modelToView = new ModelConversionDispatcher( model, { mapper, viewSelection: viewDocument.selection } );
 
 	// Bind root elements.
-	mapper.bindElements( node.root, viewDocumentFragment );
+	mapper.bindElements( node.root, viewRoot );
 
 	modelToView.on( 'insert:$text', insertText() );
 	modelToView.on( 'attribute', wrap( ( value, data ) => {
@@ -222,7 +230,12 @@ export function stringify( node, selectionOrPositionOrRange = null ) {
 	}
 
 	// Parse view to data string.
-	const data = viewStringify( viewDocumentFragment, viewSelection, { sameSelectionCharacters: true } );
+	let data = viewStringify( viewRoot, viewDocument.selection, { sameSelectionCharacters: true } );
+
+	// Removing unneccessary <div> and </div> added because `viewRoot` was also stringified alongside input data.
+	data = data.substr( 5, data.length - 11 );
+
+	viewDocument.destroy();
 
 	// Replace valid XML `model-text-with-attributes` element name to `$text`.
 	return data.replace( new RegExp( 'model-text-with-attributes', 'g' ), '$text' );

+ 5 - 1
packages/ckeditor5-engine/src/view/writer.js

@@ -456,6 +456,7 @@ export function move( sourceRange, targetPosition ) {
 
 /**
  * Wraps elements within range with provided {@link module:engine/view/attributeelement~AttributeElement AttributeElement}.
+ * If a collapsed range is provided, it will be wrapped only if it is equal to view selection.
  *
  * If `viewSelection` was set and a collapsed range was passed, if the range is same as selection, the selection
  * will be moved to the inside of the wrapped attribute element.
@@ -467,6 +468,9 @@ export function move( sourceRange, targetPosition ) {
  * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-invalid-attribute` when passed attribute element is not
  * an instance of {module:engine/view/attributeelement~AttributeElement AttributeElement}.
  *
+ * Throws {@link module:utils/ckeditorerror~CKEditorError} `view-writer-wrap-nonselection-collapsed-range` when passed range
+ * is collapsed and different than view selection.
+ *
  * @function module:engine/view/writer~writer.wrap
  * @param {module:engine/view/range~Range} range Range to wrap.
  * @param {module:engine/view/attributeelement~AttributeElement} attribute Attribute element to use as wrapper.
@@ -496,7 +500,7 @@ export function wrap( range, attribute, viewSelection = null ) {
 
 		// If wrapping position is equal to view selection, move view selection inside wrapping attribute element.
 		if ( viewSelection && viewSelection.isCollapsed && viewSelection.getFirstPosition().isEqual( range.start ) ) {
-			viewSelection.setTo( position );
+			viewSelection.setRanges( [ new Range( position ) ] );
 		}
 
 		return new Range( position );