8
0
Quellcode durchsuchen

Docs for model, document, writer and batch.

Piotr Jasiun vor 8 Jahren
Ursprung
Commit
5a1ca265b4

+ 9 - 13
packages/ckeditor5-engine/src/model/batch.js

@@ -10,25 +10,21 @@
 /**
  * `Batch` instance groups model changes ({@link module:engine/model/delta/delta~Delta deltas}). All deltas grouped in a single `Batch`
  * can be reverted together, so you can think about `Batch` as of a single undo step. If you want to extend given undo step you
- * can call another method on the same `Batch` object. If you want to create a separate undo step you can create a new `Batch`.
+ * can add more changes to the batch using {@link module:engine/model~model#enqueueChange}:
  *
- * For example to create two separate undo steps you can call:
- *
- *		doc.batch().insert( 'foo', firstPosition );
- *		doc.batch().insert( 'bar', secondPosition );
- *
- * To create a single undo step:
- *
- *		const batch = doc.batch();
- *		batch.insert( 'foo', firstPosition );
- *		batch.insert( 'bar', secondPosition );
+ *		model.enqueueChange( batch, writer => {
+ *			writer.insertText( 'foo', paragraph, 'end' );
+ *		} );
  *
+ * @see module:engine/model~model#enqueueChange
+ * @see module:engine/model~model#change
  */
 export default class Batch {
 	/**
-	 * Creates `Batch` instance. Not recommended to use directly, use {@link module:engine/model~model#change} or
-	 * {@link module:engine/model~model#enqueueChanges} instead.
+	 * Creates `Batch` instance.
 	 *
+	 * @see module:engine/model~model#enqueueChange
+	 * @see module:engine/model~model#change
 	 * @param {'transparent'|'default'} [type='default'] Type of the batch.
 	 */
 	constructor( type = 'default' ) {

+ 6 - 8
packages/ckeditor5-engine/src/model/document.js

@@ -31,14 +31,6 @@ const graveyardName = '$graveyard';
  * {@link module:engine/model/document~Document#roots root elements}, for example if the editor have multiple editable areas,
  * each area will be represented by the separate root.
  *
- * All changes in the document are done by {@link module:engine/model/operation/operation~Operation operations}. To create operations in
- * a simple way, use the {@link module:engine/model/batch~Batch} API, for example:
- *
- *		const batch = doc.batch();
- *		batch.insert( node, position );
- *		batch.split( otherPosition );
- *
- * @see module:engine/model/document~Document#batch
  * @mixes module:utils/emittermixin~EmitterMixin
  */
 export default class Document {
@@ -47,6 +39,12 @@ export default class Document {
 	 * the {@link #graveyard graveyard root}).
 	 */
 	constructor( model ) {
+		/**
+		 * {@link module:engine/model/model~Model} the document is part of.
+		 *
+		 * @readonly
+		 * @member {module:engine/model/model~Model}
+		 */
 		this.model = model;
 
 		/**

+ 123 - 2
packages/ckeditor5-engine/src/model/model.js

@@ -15,21 +15,38 @@ import MarkerCollection from './markercollection';
 import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
 import mix from '@ckeditor/ckeditor5-utils/src/mix';
 
+/**
+ * Editors data model class. Model defines all data: either nodes users see in editable roots, grouped as the
+ * {@link #document}, and all detached nodes, used to data manipulation. All of them are
+ * created and modified by the {@link module:engine/model/model~Writer}, which can be get using
+ * {@link #change} or {@link #enqueueChange} methods.
+ */
 export default class Model {
 	constructor() {
+		/**
+		 * All callbacks added by {@link #change} or {@link #enqueueChange} methods waiting to be executed.
+		 *
+		 * @private
+		 * @type {Array.<Function>}
+		 */
 		this._pendingChanges = [];
 
+		/**
+		 * Editors document model.
+		 *
+		 * @member {module:engine/model/document~Document}
+		 */
 		this.document = new Document( this );
 
 		/**
-		 * Schema for this document.
+		 * Schema for editors model.
 		 *
 		 * @member {module:engine/model/schema~Schema}
 		 */
 		this.schema = new Schema();
 
 		/**
-		 * Document's markers' collection.
+		 * Models markers' collection.
 		 *
 		 * @readonly
 		 * @member {module:engine/model/markercollection~MarkerCollection}
@@ -39,6 +56,43 @@ export default class Model {
 		this.decorate( 'applyOperation' );
 	}
 
+	/**
+	 * Change method is the primary way of changing the model. You should use it to modify any node, including detached
+	 * nodes, not added to the {@link #document}.
+	 *
+	 *		model.change( writer => {
+	 *			writer.insertText( 'foo', paragraph, 'end' );
+	 *		} );
+	 *
+	 * All changes inside the change block use the same {@link module:engine/model/batch~Batch} so share the same
+	 * undo step.
+	 *
+	 *		model.change( writer => {
+	 *			writer.insertText( 'foo', paragraph, 'end' ); // foo
+	 *
+	 *			model.change( writer => {
+	 *				writer.insertText( 'bar', paragraph, 'end' ); // foobar
+	 *			} );
+	 *
+	 * 			writer.insertText( 'bom', paragraph, 'end' ); // foobarbom
+	 *		} );
+	 *
+	 * Change block is executed imminently.
+	 *
+	 * You can also return a value from the change block.
+	 *
+	 *		const img = model.change( writer => {
+	 *			return writer.createElement( 'img' );
+	 *		} );
+	 *
+	 * When the outermost block is done the {@link #event:change} event is fired.
+	 *
+	 * @see #enqueueChange
+	 * @fires event:change
+	 * @fires event:changesDone
+	 * @param {Function} callback Callback function which may modify the model.
+	 * @returns {*} Value returned by the callback
+	 */
 	change( callback ) {
 		if ( this._pendingChanges.length === 0 ) {
 			this._pendingChanges.push( { batch: new Batch(), callback } );
@@ -49,6 +103,39 @@ export default class Model {
 		}
 	}
 
+	/**
+	 * `enqueueChange` method is very similar to the {@link #change change method}, with two major differences.
+	 *
+	 * First, the callback of the `enqueueChange` is executed when all other changes are done. It might be executed
+	 * imminently if it is not nested in any other change block, but if it is nested in another change it will be delayed
+	 * and executed after the outermost block. If will be also executed after all previous `enqueueChange` blocks.
+	 *
+	 *		model.change( writer => {
+	 *			console.log( 1 );
+	 *
+	 *			model.enqueueChange( writer => {
+	 *				console.log( 3 );
+	 *			} );
+	 *
+	 * 			console.log( 2 );
+	 *		} );
+	 *
+	 * Second, it let you define the {@link module:engine/model/batch~Batch} to which you want to add your changes.
+	 * By default it creates a new batch, note that in the sample above `change` and `enqueueChange` blocks use a different
+	 * batch (and different {@link module:engine/model/writer~Writer} since each of them operates on the separate batch).
+	 *
+	 * Using `enqueueChange` block you can also add some changes to the batch you used before.
+	 *
+	 *		model.enqueueChange( batch, writer => {
+	 *			writer.insertText( 'foo', paragraph, 'end' );
+	 *		} );
+	 *
+	 * @fires event:change
+	 * @fires event:changesDone
+	 * @param {[<module:engine/model/batch~Batch|String>]} batchOrType Batch or batch type should be used in the callback.
+	 * If not defined new batch will be created.
+	 * @param {Function} callback Callback function which may modify the model.
+	 */
 	enqueueChange( batchOrType, callback ) {
 		if ( typeof batchOrType === 'string' ) {
 			batchOrType = new Batch( batchOrType );
@@ -64,6 +151,13 @@ export default class Model {
 		}
 	}
 
+	/**
+	 * Common part of {@link #change} and {@link #enqueueChange} which calls callbacks and returns array of values
+	 * returned by these callbacks.
+	 *
+	 * @private
+	 * @returns {Array.<*>} Array of values returned by callbacks.
+	 */
 	_runPendingChanges() {
 		const ret = [];
 
@@ -84,6 +178,14 @@ export default class Model {
 		return ret;
 	}
 
+	/**
+	 * {@link #decorate Decorated} function to apply {@link module:engine/model/operation/operation~Operation operations}
+	 * on the model.
+	 *
+	 * @param {module:engine/model/operation/operation~Operation} operation Operation to apply
+	 * @returns {Object} Object with additional information about the applied changes. It properties depends on the
+	 * operation type.
+	 */
 	applyOperation( operation ) {
 		return operation._execute();
 	}
@@ -95,6 +197,25 @@ export default class Model {
 		this.document.destroy();
 		this.stopListening();
 	}
+
+	/**
+	 * Fires after leaving each {@link #enqueueChange} block or outermost {@link #change} block.
+	 * Have the same parameters as {@link module:engine/model/document~Document#change}.
+	 *
+	 * @event change
+	 */
+
+	/**
+	 * Fires when all queued model changes are done.
+	 *
+	 * @see #change
+	 * @see #enqueueChange
+	 * @event changesDone
+	 */
+
+	/**
+	 * @event applyOperation
+	 */
 }
 
 mix( Model, ObservableMixin );

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

@@ -1,8 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/**
- * @module engine/model/model
- */

+ 16 - 12
packages/ckeditor5-engine/src/model/writer.js

@@ -41,24 +41,28 @@ import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
- * `Batch` instance groups document changes ({@link module:engine/model/delta/delta~Delta deltas}). All deltas grouped in a single `Batch`
- * can be reverted together, so you can think about `Batch` as of a single undo step. If you want to extend given undo step you
- * can call another method on the same `Batch` object. If you want to create a separate undo step you can create a new `Batch`.
+ * Model writer it the proper way of modifying model. It should be used whenever you wants to create node, modify
+ * child nodes, attributes or text. To get writer use {@link module:engine/model~model#change} or
+ * {@link @see module:engine/model~model#enqueueChange}.
  *
- * For example to create two separate undo steps you can call:
+ *		model.change( writer => {
+ *			writer.insertText( 'foo', paragraph, 'end' );
+ *		} );
  *
- *		doc.batch().insert( 'foo', firstPosition );
- *		doc.batch().insert( 'bar', secondPosition );
- *
- * To create a single undo step:
- *
- *		const batch = doc.batch();
- *		writer.insert( 'foo', firstPosition );
- *		writer.insert( 'bar', secondPosition );
+ * Note that writer can be passed to a nested function but you should never store and use it outside the `change` or
+ * `enqueueChange` block.
  *
+ * @see module:engine/model~model#change
+ * @see module:engine/model~model#enqueueChange
  */
 export default class Writer {
 	/**
+	 * Writer class constructor.
+	 *
+	 * It is not recommended to use it directly, use {@link module:engine/model~model#change} or
+	 * {@link module:engine/model~model#enqueueChanges} instead.
+	 *
+	 * @protected
 	 * @param {module:engine/model~Model} model
 	 * @param {module:engine/model/batch~Batch} batch
 	 */