Sfoglia il codice sorgente

WIP - moving debug tools between files.

Maciej Bukowski 6 anni fa
parent
commit
2695c37005

+ 185 - 192
packages/ckeditor5-engine/src/dev-utils/enableenginedebug.js

@@ -11,26 +11,26 @@
 
 import OperationReplayer from './operationreplayer';
 
-import ModelPosition from '../model/position';
-import ModelRange from '../model/range';
-import ModelText from '../model/text';
-import ModelTextProxy from '../model/textproxy';
-import ModelElement from '../model/element';
-import Operation from '../model/operation/operation';
-import AttributeOperation from '../model/operation/attributeoperation';
-import DetachOperation from '../model/operation/detachoperation';
-import InsertOperation from '../model/operation/insertoperation';
-import MarkerOperation from '../model/operation/markeroperation';
-import MoveOperation from '../model/operation/moveoperation';
-import NoOperation from '../model/operation/nooperation';
-import RenameOperation from '../model/operation/renameoperation';
-import RootAttributeOperation from '../model/operation/rootattributeoperation';
-import SplitOperation from '../model/operation/splitoperation';
-import MergeOperation from '../model/operation/mergeoperation';
+// import ModelPosition from '../model/position';
+// import ModelRange from '../model/range';
+// import ModelText from '../model/text';
+// import ModelTextProxy from '../model/textproxy';
+// import ModelElement from '../model/element';
+// import Operation from '../model/operation/operation';
+// import AttributeOperation from '../model/operation/attributeoperation';
+// import DetachOperation from '../model/operation/detachoperation';
+// import InsertOperation from '../model/operation/insertoperation';
+// import MarkerOperation from '../model/operation/markeroperation';
+// import MoveOperation from '../model/operation/moveoperation';
+// import NoOperation from '../model/operation/nooperation';
+// import RenameOperation from '../model/operation/renameoperation';
+// import RootAttributeOperation from '../model/operation/rootattributeoperation';
+// import SplitOperation from '../model/operation/splitoperation';
+// import MergeOperation from '../model/operation/mergeoperation';
 import Model from '../model/model';
 import ModelDocument from '../model/document';
-import ModelDocumentFragment from '../model/documentfragment';
-import ModelRootElement from '../model/rootelement';
+// import ModelDocumentFragment from '../model/documentfragment';
+// import ModelRootElement from '../model/rootelement';
 
 import ViewDocument from '../view/document';
 import ViewElement from '../view/element';
@@ -156,208 +156,208 @@ export function disableEngineDebug() {
 }
 
 function enableLoggingTools() {
-	sandbox.mock( ModelPosition.prototype, 'toString', function() {
-		return `${ this.root } [ ${ this.path.join( ', ' ) } ]`;
-	} );
+	// sandbox.mock( ModelPosition.prototype, 'toString', function() {
+	// 	return `${ this.root } [ ${ this.path.join( ', ' ) } ]`;
+	// } );
 
-	sandbox.mock( ModelPosition.prototype, 'log', function() {
-		logger.log( 'ModelPosition: ' + this );
-	} );
+	// sandbox.mock( ModelPosition.prototype, 'log', function() {
+	// 	logger.log( 'ModelPosition: ' + this );
+	// } );
 
-	sandbox.mock( ModelRange.prototype, 'toString', function() {
-		return `${ this.root } [ ${ this.start.path.join( ', ' ) } ] - [ ${ this.end.path.join( ', ' ) } ]`;
-	} );
+	// sandbox.mock( ModelRange.prototype, 'toString', function() {
+	// 	return `${ this.root } [ ${ this.start.path.join( ', ' ) } ] - [ ${ this.end.path.join( ', ' ) } ]`;
+	// } );
 
-	sandbox.mock( ModelRange.prototype, 'log', function() {
-		logger.log( 'ModelRange: ' + this );
-	} );
+	// sandbox.mock( ModelRange.prototype, 'log', function() {
+	// 	logger.log( 'ModelRange: ' + this );
+	// } );
 
-	sandbox.mock( ModelText.prototype, 'toString', function() {
-		return `#${ this.data }`;
-	} );
+	// sandbox.mock( ModelText.prototype, 'toString', function() {
+	// 	return `#${ this.data }`;
+	// } );
 
-	sandbox.mock( ModelText.prototype, 'logExtended', function() {
-		logger.log( `ModelText: ${ this }, attrs: ${ mapString( this.getAttributes() ) }` );
-	} );
+	// sandbox.mock( ModelText.prototype, 'logExtended', function() {
+	// 	logger.log( `ModelText: ${ this }, attrs: ${ mapString( this.getAttributes() ) }` );
+	// } );
 
-	sandbox.mock( ModelText.prototype, 'log', function() {
-		logger.log( 'ModelText: ' + this );
-	} );
+	// sandbox.mock( ModelText.prototype, 'log', function() {
+	// 	logger.log( 'ModelText: ' + this );
+	// } );
 
-	sandbox.mock( ModelTextProxy.prototype, 'toString', function() {
-		return `#${ this.data }`;
-	} );
+	// sandbox.mock( ModelTextProxy.prototype, 'toString', function() {
+	// 	return `#${ this.data }`;
+	// } );
 
-	sandbox.mock( ModelTextProxy.prototype, 'logExtended', function() {
-		logger.log( `ModelTextProxy: ${ this }, attrs: ${ mapString( this.getAttributes() ) }` );
-	} );
+	// sandbox.mock( ModelTextProxy.prototype, 'logExtended', function() {
+	// 	logger.log( `ModelTextProxy: ${ this }, attrs: ${ mapString( this.getAttributes() ) }` );
+	// } );
 
-	sandbox.mock( ModelTextProxy.prototype, 'log', function() {
-		logger.log( 'ModelTextProxy: ' + this );
-	} );
+	// sandbox.mock( ModelTextProxy.prototype, 'log', function() {
+	// 	logger.log( 'ModelTextProxy: ' + this );
+	// } );
 
-	sandbox.mock( ModelElement.prototype, 'toString', function() {
-		return `<${ this.rootName || this.name }>`;
-	} );
+	// sandbox.mock( ModelElement.prototype, 'toString', function() {
+	// 	return `<${ this.rootName || this.name }>`;
+	// } );
 
-	sandbox.mock( ModelElement.prototype, 'log', function() {
-		logger.log( 'ModelElement: ' + this );
-	} );
+	// sandbox.mock( ModelElement.prototype, 'log', function() {
+	// 	logger.log( 'ModelElement: ' + this );
+	// } );
 
-	sandbox.mock( ModelElement.prototype, 'logExtended', function() {
-		logger.log( `ModelElement: ${ this }, ${ this.childCount } children, attrs: ${ mapString( this.getAttributes() ) }` );
-	} );
+	// sandbox.mock( ModelElement.prototype, 'logExtended', function() {
+	// 	logger.log( `ModelElement: ${ this }, ${ this.childCount } children, attrs: ${ mapString( this.getAttributes() ) }` );
+	// } );
 
-	sandbox.mock( ModelElement.prototype, 'logAll', function() {
-		logger.log( '--------------------' );
+	// sandbox.mock( ModelElement.prototype, 'logAll', function() {
+	// 	logger.log( '--------------------' );
 
-		this.logExtended();
-		logger.log( 'List of children:' );
+	// 	this.logExtended();
+	// 	logger.log( 'List of children:' );
 
-		for ( const child of this.getChildren() ) {
-			child.log();
-		}
-	} );
+	// 	for ( const child of this.getChildren() ) {
+	// 		child.log();
+	// 	}
+	// } );
 
-	sandbox.mock( ModelElement.prototype, 'printTree', function( level = 0 ) {
-		let string = '';
+	// sandbox.mock( ModelElement.prototype, 'printTree', function( level = 0 ) {
+	// 	let string = '';
 
-		string += '\t'.repeat( level ) + `<${ this.rootName || this.name }${ mapToTags( this.getAttributes() ) }>`;
+	// 	string += '\t'.repeat( level ) + `<${ this.rootName || this.name }${ mapToTags( this.getAttributes() ) }>`;
 
-		for ( const child of this.getChildren() ) {
-			string += '\n';
+	// 	for ( const child of this.getChildren() ) {
+	// 		string += '\n';
 
-			if ( child.is( 'text' ) ) {
-				const textAttrs = mapToTags( child._attrs );
+	// 		if ( child.is( 'text' ) ) {
+	// 			const textAttrs = mapToTags( child._attrs );
 
-				string += '\t'.repeat( level + 1 );
+	// 			string += '\t'.repeat( level + 1 );
 
-				if ( textAttrs !== '' ) {
-					string += `<$text${ textAttrs }>` + child.data + '</$text>';
-				} else {
-					string += child.data;
-				}
-			} else {
-				string += child.printTree( level + 1 );
-			}
-		}
+	// 			if ( textAttrs !== '' ) {
+	// 				string += `<$text${ textAttrs }>` + child.data + '</$text>';
+	// 			} else {
+	// 				string += child.data;
+	// 			}
+	// 		} else {
+	// 			string += child.printTree( level + 1 );
+	// 		}
+	// 	}
 
-		if ( this.childCount ) {
-			string += '\n' + '\t'.repeat( level );
-		}
+	// 	if ( this.childCount ) {
+	// 		string += '\n' + '\t'.repeat( level );
+	// 	}
 
-		string += `</${ this.rootName || this.name }>`;
+	// 	string += `</${ this.rootName || this.name }>`;
 
-		return string;
-	} );
+	// 	return string;
+	// } );
 
-	sandbox.mock( ModelElement.prototype, 'logTree', function() {
-		logger.log( this.printTree() );
-	} );
+	// sandbox.mock( ModelElement.prototype, 'logTree', function() {
+	// 	logger.log( this.printTree() );
+	// } );
 
-	sandbox.mock( ModelRootElement.prototype, 'toString', function() {
-		return this.rootName;
-	} );
+	// sandbox.mock( ModelRootElement.prototype, 'toString', function() {
+	// 	return this.rootName;
+	// } );
 
-	sandbox.mock( ModelRootElement.prototype, 'log', function() {
-		logger.log( 'ModelRootElement: ' + this );
-	} );
+	// sandbox.mock( ModelRootElement.prototype, 'log', function() {
+	// 	logger.log( 'ModelRootElement: ' + this );
+	// } );
 
-	sandbox.mock( ModelDocumentFragment.prototype, 'toString', function() {
-		return 'documentFragment';
-	} );
+	// sandbox.mock( ModelDocumentFragment.prototype, 'toString', function() {
+	// 	return 'documentFragment';
+	// } );
 
-	sandbox.mock( ModelDocumentFragment.prototype, 'log', function() {
-		logger.log( 'ModelDocumentFragment: ' + this );
-	} );
+	// sandbox.mock( ModelDocumentFragment.prototype, 'log', function() {
+	// 	logger.log( 'ModelDocumentFragment: ' + this );
+	// } );
 
-	sandbox.mock( ModelDocumentFragment.prototype, 'printTree', function() {
-		let string = 'ModelDocumentFragment: [';
+	// sandbox.mock( ModelDocumentFragment.prototype, 'printTree', function() {
+	// 	let string = 'ModelDocumentFragment: [';
 
-		for ( const child of this.getChildren() ) {
-			string += '\n';
+	// 	for ( const child of this.getChildren() ) {
+	// 		string += '\n';
 
-			if ( child.is( 'text' ) ) {
-				const textAttrs = mapToTags( child._attrs );
+	// 		if ( child.is( 'text' ) ) {
+	// 			const textAttrs = mapToTags( child._attrs );
 
-				string += '\t'.repeat( 1 );
+	// 			string += '\t'.repeat( 1 );
 
-				if ( textAttrs !== '' ) {
-					string += `<$text${ textAttrs }>` + child.data + '</$text>';
-				} else {
-					string += child.data;
-				}
-			} else {
-				string += child.printTree( 1 );
-			}
-		}
+	// 			if ( textAttrs !== '' ) {
+	// 				string += `<$text${ textAttrs }>` + child.data + '</$text>';
+	// 			} else {
+	// 				string += child.data;
+	// 			}
+	// 		} else {
+	// 			string += child.printTree( 1 );
+	// 		}
+	// 	}
 
-		string += '\n]';
+	// 	string += '\n]';
 
-		return string;
-	} );
+	// 	return string;
+	// } );
 
-	sandbox.mock( ModelDocumentFragment.prototype, 'logTree', function() {
-		logger.log( this.printTree() );
-	} );
+	// sandbox.mock( ModelDocumentFragment.prototype, 'logTree', function() {
+	// 	logger.log( this.printTree() );
+	// } );
 
-	sandbox.mock( Operation.prototype, 'log', function() {
-		logger.log( this.toString() );
-	} );
+	// sandbox.mock( Operation.prototype, 'log', function() {
+	// 	logger.log( this.toString() );
+	// } );
 
-	sandbox.mock( AttributeOperation.prototype, 'toString', function() {
-		return getClassName( this ) + `( ${ this.baseVersion } ): ` +
-			`"${ this.key }": ${ JSON.stringify( this.oldValue ) } -> ${ JSON.stringify( this.newValue ) }, ${ this.range }`;
-	} );
+	// sandbox.mock( AttributeOperation.prototype, 'toString', function() {
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ` +
+	// 		`"${ this.key }": ${ JSON.stringify( this.oldValue ) } -> ${ JSON.stringify( this.newValue ) }, ${ this.range }`;
+	// } );
 
-	sandbox.mock( DetachOperation.prototype, 'toString', function() {
-		const range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );
-		const nodes = Array.from( range.getItems() );
-		const nodeString = nodes.length > 1 ? `[ ${ nodes.length } ]` : nodes[ 0 ];
+	// sandbox.mock( DetachOperation.prototype, 'toString', function() {
+	// 	const range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );
+	// 	const nodes = Array.from( range.getItems() );
+	// 	const nodeString = nodes.length > 1 ? `[ ${ nodes.length } ]` : nodes[ 0 ];
 
-		return getClassName( this ) + `( ${ this.baseVersion } ): ${ nodeString } -> ${ range }`;
-	} );
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ${ nodeString } -> ${ range }`;
+	// } );
 
-	sandbox.mock( InsertOperation.prototype, 'toString', function() {
-		const nodeString = this.nodes.length > 1 ? `[ ${ this.nodes.length } ]` : this.nodes.getNode( 0 );
+	// sandbox.mock( InsertOperation.prototype, 'toString', function() {
+	// 	const nodeString = this.nodes.length > 1 ? `[ ${ this.nodes.length } ]` : this.nodes.getNode( 0 );
 
-		return getClassName( this ) + `( ${ this.baseVersion } ): ${ nodeString } -> ${ this.position }`;
-	} );
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ${ nodeString } -> ${ this.position }`;
+	// } );
 
-	sandbox.mock( MarkerOperation.prototype, 'toString', function() {
-		return getClassName( this ) + `( ${ this.baseVersion } ): ` +
-			`"${ this.name }": ${ this.oldRange } -> ${ this.newRange }`;
-	} );
+	// sandbox.mock( MarkerOperation.prototype, 'toString', function() {
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ` +
+	// 		`"${ this.name }": ${ this.oldRange } -> ${ this.newRange }`;
+	// } );
 
-	sandbox.mock( MoveOperation.prototype, 'toString', function() {
-		const range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );
+	// sandbox.mock( MoveOperation.prototype, 'toString', function() {
+	// 	const range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );
 
-		return getClassName( this ) + `( ${ this.baseVersion } ): ${ range } -> ${ this.targetPosition }`;
-	} );
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ${ range } -> ${ this.targetPosition }`;
+	// } );
 
-	sandbox.mock( NoOperation.prototype, 'toString', function() {
-		return `NoOperation( ${ this.baseVersion } )`;
-	} );
+	// sandbox.mock( NoOperation.prototype, 'toString', function() {
+	// 	return `NoOperation( ${ this.baseVersion } )`;
+	// } );
 
-	sandbox.mock( RenameOperation.prototype, 'toString', function() {
-		return getClassName( this ) + `( ${ this.baseVersion } ): ` +
-			`${ this.position }: "${ this.oldName }" -> "${ this.newName }"`;
-	} );
+	// sandbox.mock( RenameOperation.prototype, 'toString', function() {
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ` +
+	// 		`${ this.position }: "${ this.oldName }" -> "${ this.newName }"`;
+	// } );
 
-	sandbox.mock( RootAttributeOperation.prototype, 'toString', function() {
-		return getClassName( this ) + `( ${ this.baseVersion } ): ` +
-			`"${ this.key }": ${ JSON.stringify( this.oldValue ) } -> ${ JSON.stringify( this.newValue ) }, ${ this.root.rootName }`;
-	} );
+	// sandbox.mock( RootAttributeOperation.prototype, 'toString', function() {
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ` +
+	// 		`"${ this.key }": ${ JSON.stringify( this.oldValue ) } -> ${ JSON.stringify( this.newValue ) }, ${ this.root.rootName }`;
+	// } );
 
-	sandbox.mock( MergeOperation.prototype, 'toString', function() {
-		return getClassName( this ) + `( ${ this.baseVersion } ): ` +
-			`${ this.sourcePosition } -> ${ this.targetPosition } ( ${ this.howMany } ), ${ this.graveyardPosition }`;
-	} );
+	// sandbox.mock( MergeOperation.prototype, 'toString', function() {
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ` +
+	// 		`${ this.sourcePosition } -> ${ this.targetPosition } ( ${ this.howMany } ), ${ this.graveyardPosition }`;
+	// } );
 
-	sandbox.mock( SplitOperation.prototype, 'toString', function() {
-		return getClassName( this ) + `( ${ this.baseVersion } ): ${ this.splitPosition } ` +
-			`( ${ this.howMany } ) -> ${ this.insertionPosition }${ this.graveyardPosition ? ' with ' + this.graveyardPosition : '' }`;
-	} );
+	// sandbox.mock( SplitOperation.prototype, 'toString', function() {
+	// 	return getClassName( this ) + `( ${ this.baseVersion } ): ${ this.splitPosition } ` +
+	// 		`( ${ this.howMany } ) -> ${ this.insertionPosition }${ this.graveyardPosition ? ' with ' + this.graveyardPosition : '' }`;
+	// } );
 
 	sandbox.mock( ViewText.prototype, 'toString', function() {
 		return `#${ this.data }`;
@@ -457,19 +457,19 @@ function enableReplayerTools() {
 }
 
 function enableDocumentTools() {
-	const _modelApplyOperation = Model.prototype.applyOperation;
+	// const _modelApplyOperation = Model.prototype.applyOperation;
 
-	sandbox.mock( Model.prototype, 'applyOperation', function( operation ) {
-		logger.log( 'Applying ' + operation );
+	// sandbox.mock( Model.prototype, 'applyOperation', function( operation ) {
+	// 	logger.log( 'Applying ' + operation );
 
-		if ( !this._operationLogs ) {
-			this._operationLogs = [];
-		}
+	// 	if ( !this._operationLogs ) {
+	// 		this._operationLogs = [];
+	// 	}
 
-		this._operationLogs.push( JSON.stringify( operation ) );
+	// 	this._operationLogs.push( JSON.stringify( operation ) );
 
-		return _modelApplyOperation.call( this, operation );
-	} );
+	// 	return _modelApplyOperation.call( this, operation );
+	// } );
 
 	sandbox.mock( ModelDocument.prototype, 'log', function( version = null ) {
 		version = version === null ? this.version : version;
@@ -554,25 +554,18 @@ function dumpTrees( document, version ) {
 	}
 }
 
-// Helper function, returns the class name of a given `Operation`.
-// @param {module:engine/model/operation/operation~Operation}
-// @returns {String} Class name.
-function getClassName( obj ) {
-	return obj.constructor.className;
-}
-
 // Helper function, converts a map to the {"key1":"value1","key2":"value2"} format.
 // @param {Map} map Map to convert.
 // @returns {String} Converted map.
-function mapString( map ) {
-	const obj = {};
+// function mapString( map ) {
+// 	const obj = {};
 
-	for ( const entry of map ) {
-		obj[ entry[ 0 ] ] = entry[ 1 ];
-	}
+// 	for ( const entry of map ) {
+// 		obj[ entry[ 0 ] ] = entry[ 1 ];
+// 	}
 
-	return JSON.stringify( obj );
-}
+// 	return JSON.stringify( obj );
+// }
 
 // Helper function, converts a map to the key1="value1" key2="value1" format.
 // @param {Map} map Map to convert.

+ 42 - 0
packages/ckeditor5-engine/src/dev-utils/utils.js

@@ -0,0 +1,42 @@
+/**
+ * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+/**
+ * @module engine/dev-utils/utils
+ */
+
+/**
+ * Helper function, converts a map to the 'key1="value1" key2="value1"' format.
+ *
+ * @private
+ * @param {Map} map Map to convert.
+ * @returns {String} Converted map.
+ */
+export function convertMapToTags( map ) {
+	let string = '';
+
+	for ( const entry of map ) {
+		string += ` ${ entry[ 0 ] }=${ JSON.stringify( entry[ 1 ] ) }`;
+	}
+
+	return string;
+}
+
+/**
+ * Helper function, converts a map to the '{"key1":"value1","key2":"value2"}' format.
+ *
+ * @private
+ * @param {Map} map Map to convert.
+ * @returns {String} Converted map.
+ */
+export function convertMapToStringifiedObject( map ) {
+	const obj = {};
+
+	for ( const entry of map ) {
+		obj[ entry[ 0 ] ] = entry[ 1 ];
+	}
+
+	return JSON.stringify( obj );
+}

+ 40 - 0
packages/ckeditor5-engine/src/model/documentfragment.js

@@ -13,6 +13,8 @@ import Text from './text';
 import TextProxy from './textproxy';
 import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';
 
+// @if CK_DEBUG_ENGINE // const { stringifyMap } = require( '../dev-utils/utils' );
+
 /**
  * DocumentFragment represents a part of model which does not have a common root but it's top-level nodes
  * can be seen as siblings. In other words, it is a detached part of model tree, without a root.
@@ -318,6 +320,44 @@ export default class DocumentFragment {
 
 		return nodes;
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return 'documentFragment';
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( 'ModelDocumentFragment: ' + this );
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // printTree() {
+	// @if CK_DEBUG_ENGINE //	let string = 'ModelDocumentFragment: [';
+
+	// @if CK_DEBUG_ENGINE //	for ( const child of this.getChildren() ) {
+	// @if CK_DEBUG_ENGINE //		string += '\n';
+
+	// @if CK_DEBUG_ENGINE //		if ( child.is( 'text' ) ) {
+	// @if CK_DEBUG_ENGINE //			const textAttrs = stringifyMap( child._attrs );
+
+	// @if CK_DEBUG_ENGINE //			string += '\t'.repeat( 1 );
+
+	// @if CK_DEBUG_ENGINE //			if ( textAttrs !== '' ) {
+	// @if CK_DEBUG_ENGINE //				string += `<$text${ textAttrs }>` + child.data + '</$text>';
+	// @if CK_DEBUG_ENGINE //			} else {
+	// @if CK_DEBUG_ENGINE //				string += child.data;
+	// @if CK_DEBUG_ENGINE //			}
+	// @if CK_DEBUG_ENGINE //		} else {
+	// @if CK_DEBUG_ENGINE //			string += child.printTree( 1 );
+	// @if CK_DEBUG_ENGINE //		}
+	// @if CK_DEBUG_ENGINE //	}
+
+	// @if CK_DEBUG_ENGINE //	string += '\n]';
+
+	// @if CK_DEBUG_ENGINE //	return string;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // logTree() {
+	// @if CK_DEBUG_ENGINE // 	console.log( this.printTree() );
+	// @if CK_DEBUG_ENGINE // }
 }
 
 // Converts strings to Text and non-iterables to arrays.

+ 63 - 0
packages/ckeditor5-engine/src/model/element.js

@@ -13,6 +13,8 @@ import Text from './text';
 import TextProxy from './textproxy';
 import isIterable from '@ckeditor/ckeditor5-utils/src/isiterable';
 
+// @if CK_DEBUG_ENGINE // const { stringifyMap, convertMapToStringifiedObject } = require( '../dev-utils/utils' );
+
 /**
  * Model element. Type of {@link module:engine/model/node~Node node} that has a {@link module:engine/model/element~Element#name name} and
  * {@link module:engine/model/element~Element#getChildren child nodes}.
@@ -322,6 +324,67 @@ export default class Element extends Node {
 
 		return new Element( json.name, json.attributes, children );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `<${ this.rootName || this.name }>`;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( 'ModelElement: ' + this );
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // logExtended() {
+	// @if CK_DEBUG_ENGINE // 	console.log( `ModelElement: ${ this }, ${ this.childCount } children,
+	// @if CK_DEBUG_ENGINE //		attrs: ${ convertMapToStringifiedObject( this.getAttributes() ) }` );
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // logAll() {
+	// @if CK_DEBUG_ENGINE // 	console.log( '--------------------' );
+	// @if CK_DEBUG_ENGINE //
+	// @if CK_DEBUG_ENGINE // 	this.logExtended();
+	// @if CK_DEBUG_ENGINE //	console.log( 'List of children:' );
+	// @if CK_DEBUG_ENGINE //
+	// @if CK_DEBUG_ENGINE // 	for ( const child of this.getChildren() ) {
+	// @if CK_DEBUG_ENGINE // 		child.log();
+	// @if CK_DEBUG_ENGINE // 	}
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // printTree() {
+	// @if CK_DEBUG_ENGINE // 	let string = '';
+
+	// @if CK_DEBUG_ENGINE // 	string += '\t'.repeat( level );
+	// @if CK_DEBUG_ENGINE // 	string += `<${ this.rootName || this.name }${ convertMapToTags( this.getAttributes() ) }>`;
+
+	// @if CK_DEBUG_ENGINE // 	for ( const child of this.getChildren() ) {
+	// @if CK_DEBUG_ENGINE // 		string += '\n';
+
+	// @if CK_DEBUG_ENGINE // 		if ( child.is( 'text' ) ) {
+	// @if CK_DEBUG_ENGINE // 			const textAttrs = convertMapToTags( child._attrs );
+
+	// @if CK_DEBUG_ENGINE // 			string += '\t'.repeat( level + 1 );
+
+	// @if CK_DEBUG_ENGINE // 			if ( textAttrs !== '' ) {
+	// @if CK_DEBUG_ENGINE // 				string += `<$text${ textAttrs }>` + child.data + '</$text>';
+	// @if CK_DEBUG_ENGINE // 			} else {
+	// @if CK_DEBUG_ENGINE // 				string += child.data;
+	// @if CK_DEBUG_ENGINE // 			}
+	// @if CK_DEBUG_ENGINE // 		} else {
+	// @if CK_DEBUG_ENGINE // 			string += child.printTree( level + 1 );
+	// @if CK_DEBUG_ENGINE // 		}
+	// @if CK_DEBUG_ENGINE // 	}
+
+	// @if CK_DEBUG_ENGINE // 	if ( this.childCount ) {
+	// @if CK_DEBUG_ENGINE // 		string += '\n' + '\t'.repeat( level );
+	// @if CK_DEBUG_ENGINE // 	}
+
+	// @if CK_DEBUG_ENGINE // 	string += `</${ this.rootName || this.name }>`;
+
+	// @if CK_DEBUG_ENGINE // 	return string;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // logTree() {
+	// @if CK_DEBUG_ENGINE // 	console.log( this.printTree() );
+	// @if CK_DEBUG_ENGINE // }
 }
 
 // Converts strings to Text and non-iterables to arrays.

+ 8 - 0
packages/ckeditor5-engine/src/model/model.js

@@ -233,6 +233,14 @@ export default class Model {
 	 * @param {module:engine/model/operation/operation~Operation} operation The operation to apply.
 	 */
 	applyOperation( operation ) {
+		// @if CK_DEBUG_ENGINE // console.log( 'Applying ' + operation );
+
+		// @if CK_DEBUG_ENGINE // if ( !this._operationLogs ) {
+		// @if CK_DEBUG_ENGINE //	this._operationLogs = [];
+		// @if CK_DEBUG_ENGINE // }
+
+		// @if CK_DEBUG_ENGINE // this._operationLogs.push( JSON.stringify( operation ) );
+
 		operation._execute();
 	}
 

+ 6 - 0
packages/ckeditor5-engine/src/model/operation/attributeoperation.js

@@ -194,4 +194,10 @@ export default class AttributeOperation extends Operation {
 	static fromJSON( json, document ) {
 		return new AttributeOperation( Range.fromJSON( json.range, document ), json.key, json.oldValue, json.newValue, json.baseVersion );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `AttributeOperation( ${ this.baseVersion } ): ` +
+	// @if CK_DEBUG_ENGINE //		`"${ this.key }": ${ JSON.stringify( this.oldValue ) }` +
+	// @if CK_DEBUG_ENGINE //		` -> ${ JSON.stringify( this.newValue ) }, ${ this.range }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 8 - 0
packages/ckeditor5-engine/src/model/operation/detachoperation.js

@@ -90,4 +90,12 @@ export default class DetachOperation extends Operation {
 	static get className() {
 		return 'DetachOperation';
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // const range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );
+	// @if CK_DEBUG_ENGINE //	const nodes = Array.from( range.getItems() );
+	// @if CK_DEBUG_ENGINE //	const nodeString = nodes.length > 1 ? `[ ${ nodes.length } ]` : nodes[ 0 ];
+
+	// @if CK_DEBUG_ENGINE //	return `DetachOperation( ${ this.baseVersion } ): ${ nodeString } -> ${ range }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 6 - 0
packages/ckeditor5-engine/src/model/operation/insertoperation.js

@@ -179,4 +179,10 @@ export default class InsertOperation extends Operation {
 
 		return insert;
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	const nodeString = this.nodes.length > 1 ? `[ ${ this.nodes.length } ]` : this.nodes.getNode( 0 );
+
+	// @if CK_DEBUG_ENGINE //	return `InsertOperation( ${ this.baseVersion } ): ${ nodeString } -> ${ this.position }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 5 - 0
packages/ckeditor5-engine/src/model/operation/markeroperation.js

@@ -146,4 +146,9 @@ export default class MarkerOperation extends Operation {
 			json.baseVersion
 		);
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `MarkerOperation( ${ this.baseVersion } ): ` +
+	// @if CK_DEBUG_ENGINE //		`"${ this.name }": ${ this.oldRange } -> ${ this.newRange }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 6 - 0
packages/ckeditor5-engine/src/model/operation/mergeoperation.js

@@ -210,4 +210,10 @@ export default class MergeOperation extends Operation {
 
 		return new this( sourcePosition, json.howMany, targetPosition, graveyardPosition, json.baseVersion );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `MergeOperation( ${ this.baseVersion } ): ` +
+	// @if CK_DEBUG_ENGINE //		`${ this.sourcePosition } -> ${ this.targetPosition }` +
+	// @if CK_DEBUG_ENGINE //		` ( ${ this.howMany } ), ${ this.graveyardPosition }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 6 - 0
packages/ckeditor5-engine/src/model/operation/moveoperation.js

@@ -198,4 +198,10 @@ export default class MoveOperation extends Operation {
 
 		return new this( sourcePosition, json.howMany, targetPosition, json.baseVersion );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	const range = ModelRange._createFromPositionAndShift( this.sourcePosition, this.howMany );
+
+	// @if CK_DEBUG_ENGINE //	return `MoveOperation( ${ this.baseVersion } ): ${ range } -> ${ this.targetPosition }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 4 - 0
packages/ckeditor5-engine/src/model/operation/nooperation.js

@@ -51,4 +51,8 @@ export default class NoOperation extends Operation {
 	static get className() {
 		return 'NoOperation';
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `NoOperation( ${ this.baseVersion } )`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 4 - 0
packages/ckeditor5-engine/src/model/operation/operation.js

@@ -132,4 +132,8 @@ export default class Operation {
 	static fromJSON( json ) {
 		return new this( json.baseVersion );
 	}
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( this.toString() );
+	// @if CK_DEBUG_ENGINE // }
 }

+ 6 - 0
packages/ckeditor5-engine/src/model/operation/rootattributeoperation.js

@@ -207,4 +207,10 @@ export default class RootAttributeOperation extends Operation {
 
 		return new RootAttributeOperation( document.getRoot( json.root ), json.key, json.oldValue, json.newValue, json.baseVersion );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `RootAttributeOperation( ${ this.baseVersion } ): ` +
+	// @if CK_DEBUG_ENGINE //		`"${ this.key }": ${ JSON.stringify( this.oldValue ) }` +
+	// @if CK_DEBUG_ENGINE //		` -> ${ JSON.stringify( this.newValue ) }, ${ this.root.rootName }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 6 - 0
packages/ckeditor5-engine/src/model/operation/splitoperation.js

@@ -250,4 +250,10 @@ export default class SplitOperation extends Operation {
 
 		return split;
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `SplitOperation( ${ this.baseVersion } ): ${ this.splitPosition } ` +
+	// @if CK_DEBUG_ENGINE //		`( ${ this.howMany } ) -> ${ this.insertionPosition }` +
+	// @if CK_DEBUG_ENGINE //		`${ this.graveyardPosition ? ' with ' + this.graveyardPosition : '' }`;
+	// @if CK_DEBUG_ENGINE // }
 }

+ 8 - 0
packages/ckeditor5-engine/src/model/position.js

@@ -1014,6 +1014,14 @@ export default class Position {
 
 		return new Position( doc.getRoot( json.root ), json.path, json.stickiness );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `${ this.root } [ ${ this.path.join( ', ' ) } ]`;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( 'ModelPosition: ' + this );
+	// @if CK_DEBUG_ENGINE // }
 }
 
 /**

+ 8 - 0
packages/ckeditor5-engine/src/model/range.js

@@ -958,4 +958,12 @@ export default class Range {
 	static fromJSON( json, doc ) {
 		return new this( Position.fromJSON( json.start, doc ), Position.fromJSON( json.end, doc ) );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `${ this.root } [ ${ this.start.path.join( ', ' ) } ] - [ ${ this.end.path.join( ', ' ) } ]`;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( 'ModelPosition: ' + this );
+	// @if CK_DEBUG_ENGINE // }
 }

+ 8 - 0
packages/ckeditor5-engine/src/model/rootelement.js

@@ -98,4 +98,12 @@ export default class RootElement extends Element {
 	toJSON() {
 		return this.rootName;
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return this.rootName;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( 'ModelRootElement: ' + this );
+	// @if CK_DEBUG_ENGINE // }
 }

+ 14 - 0
packages/ckeditor5-engine/src/model/text.js

@@ -9,6 +9,8 @@
 
 import Node from './node';
 
+// @if CK_DEBUG_ENGINE // const { convertMapToStringifiedObject } = require( '../dev-tools/utils' );
+
 /**
  * Model text node. Type of {@link module:engine/model/node~Node node} that contains {@link module:engine/model/text~Text#data text data}.
  *
@@ -115,4 +117,16 @@ export default class Text extends Node {
 	static fromJSON( json ) {
 		return new Text( json.data, json.attributes );
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `#${ this.data }`;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // logExtended() {
+	// @if CK_DEBUG_ENGINE // 	console.log( `ModelText: ${ this }, attrs: ${ convertMapToStringifiedObject( this.getAttributes() ) }` );
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( 'ModelText: ' + this );
+	// @if CK_DEBUG_ENGINE // }
 }

+ 15 - 0
packages/ckeditor5-engine/src/model/textproxy.js

@@ -9,6 +9,8 @@
 
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
+// @if CK_DEBUG_ENGINE // const { convertMapToStringifiedObject } = require( '../dev-tools/utils' );
+
 /**
  * `TextProxy` represents a part of {@link module:engine/model/text~Text text node}.
  *
@@ -267,4 +269,17 @@ export default class TextProxy {
 	getAttributeKeys() {
 		return this.textNode.getAttributeKeys();
 	}
+
+	// @if CK_DEBUG_ENGINE // toString() {
+	// @if CK_DEBUG_ENGINE // 	return `#${ this.data }`;
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // log() {
+	// @if CK_DEBUG_ENGINE // 	console.log( 'ModelTextProxy: ' + this );
+	// @if CK_DEBUG_ENGINE // }
+
+	// @if CK_DEBUG_ENGINE // logExtended() {
+	// @if CK_DEBUG_ENGINE // 	console.log( `ModelTextProxy: ${ this }, ` +
+	// @if CK_DEBUG_ENGINE // 		`attrs: ${ convertMapToStringifiedObject( this.getAttributes() ) }` );
+	// @if CK_DEBUG_ENGINE // }
 }