@@ -46,7 +46,7 @@ export default class Document {
4646 * The {@link module:engine/model/model~Model model} that the document is a part of.
4747 *
4848 * @readonly
49- * @member {module:engine/model/model~Model}
49+ * @type {module:engine/model/model~Model }
5050 */
5151 this . model = model ;
5252
@@ -58,23 +58,23 @@ export default class Document {
5858 * a {@link module:utils/ckeditorerror~CKEditorError model-document-applyOperation-wrong-version} error is thrown.
5959 *
6060 * @readonly
61- * @member {Number}
61+ * @type {Number }
6262 */
6363 this . version = 0 ;
6464
6565 /**
6666 * The document's history.
6767 *
6868 * @readonly
69- * @member {module:engine/model/history~History}
69+ * @type {module:engine/model/history~History }
7070 */
7171 this . history = new History ( this ) ;
7272
7373 /**
7474 * The selection in this document.
7575 *
7676 * @readonly
77- * @member {module:engine/model/documentselection~DocumentSelection}
77+ * @type {module:engine/model/documentselection~DocumentSelection }
7878 */
7979 this . selection = new DocumentSelection ( this ) ;
8080
@@ -83,26 +83,34 @@ export default class Document {
8383 * {@link #getRoot} to manipulate it.
8484 *
8585 * @readonly
86- * @member {module:utils/collection~Collection}
86+ * @type {module:utils/collection~Collection }
8787 */
8888 this . roots = new Collection ( { idProperty : 'rootName' } ) ;
8989
9090 /**
9191 * The model differ object. Its role is to buffer changes done on the model document and then calculate a diff of those changes.
9292 *
9393 * @readonly
94- * @member {module:engine/model/differ~Differ}
94+ * @type {module:engine/model/differ~Differ }
9595 */
9696 this . differ = new Differ ( model . markers ) ;
9797
9898 /**
9999 * Post-fixer callbacks registered to the model document.
100100 *
101101 * @private
102- * @member {Set}
102+ * @type {Set.<Function> }
103103 */
104104 this . _postFixers = new Set ( ) ;
105105
106+ /**
107+ * A boolean indicates whether the selection has changed until
108+ *
109+ * @private
110+ * @type {Boolean }
111+ */
112+ this . _hasSelectionChangedFromTheLastChangeBlock = false ;
113+
106114 // Graveyard tree root. Document always have a graveyard root, which stores removed nodes.
107115 this . createRoot ( '$root' , graveyardName ) ;
108116
@@ -144,29 +152,8 @@ export default class Document {
144152 } , { priority : 'low' } ) ;
145153
146154 // Listen to selection changes. If selection changed, mark it.
147- let hasSelectionChanged = false ;
148-
149155 this . listenTo ( this . selection , 'change' , ( ) => {
150- hasSelectionChanged = true ;
151- } ) ;
152-
153- // Wait for `_change` event from model, which signalizes that outermost change block has finished.
154- // When this happens, check if there were any changes done on document, and if so, call post-fixers,
155- // fire `change` event for features and conversion and then reset the differ.
156- // Fire `change:data` event when at least one operation or buffered marker changes the data.
157- this . listenTo ( model , '_change' , ( evt , writer ) => {
158- if ( ! this . differ . isEmpty || hasSelectionChanged ) {
159- this . _callPostFixers ( writer ) ;
160-
161- if ( this . differ . hasDataChanges ( ) ) {
162- this . fire ( 'change:data' , writer . batch ) ;
163- } else {
164- this . fire ( 'change' , writer . batch ) ;
165- }
166-
167- this . differ . reset ( ) ;
168- hasSelectionChanged = false ;
169- }
156+ this . _hasSelectionChangedFromTheLastChangeBlock = true ;
170157 } ) ;
171158
172159 // Buffer marker changes.
@@ -306,6 +293,44 @@ export default class Document {
306293 return json ;
307294 }
308295
296+ /**
297+ * Check if there were any changes done on document, and if so, call post-fixers,
298+ * fire `change` event for features and conversion and then reset the differ.
299+ * Fire `change:data` event when at least one operation or buffered marker changes the data.
300+ *
301+ * @protected
302+ * @fires change
303+ * @fires change:data
304+ * @param {module:engine/model/writer~Writer writer } writer The writer on which post-fixers will be called.
305+ */
306+ _handleChangeBlock ( writer ) {
307+ if ( this . _hasDocumentChangedFromTheLastChangeBlock ( ) ) {
308+ this . _callPostFixers ( writer ) ;
309+
310+ if ( this . differ . hasDataChanges ( ) ) {
311+ this . fire ( 'change:data' , writer . batch ) ;
312+ } else {
313+ this . fire ( 'change' , writer . batch ) ;
314+ }
315+
316+ this . differ . reset ( ) ;
317+ }
318+
319+ this . _hasSelectionChangedFromTheLastChangeBlock = false ;
320+ }
321+
322+ /**
323+ * Returns whether there is a buffered change or if the selection has changed from the last
324+ * {@link module:engine/model/model~Model#enqueueChange `enqueueChange()` block}
325+ * or {@link module:engine/model/model~Model#change `change()` block}.
326+ *
327+ * @protected
328+ * @returns {Boolean } Returns `true` if document has changed from the last `change()` or `enqueueChange()` block.
329+ */
330+ _hasDocumentChangedFromTheLastChangeBlock ( ) {
331+ return ! this . differ . isEmpty || this . _hasSelectionChangedFromTheLastChangeBlock ;
332+ }
333+
309334 /**
310335 * Returns the default root for this document which is either the first root that was added to the document using
311336 * {@link #createRoot} or the {@link #graveyard graveyard root} if no other roots were created.
@@ -359,6 +384,7 @@ export default class Document {
359384 * Performs post-fixer loops. Executes post-fixer callbacks as long as none of them has done any changes to the model.
360385 *
361386 * @private
387+ * @param {module:engine/model/writer~Writer writer } writer The writer on which post-fixer callbacks will be called.
362388 */
363389 _callPostFixers ( writer ) {
364390 let wasFixed = false ;
0 commit comments