Skip to content

Commit be2605c

Browse files
committed
Merge branch 't/9230b'
2 parents 741c93d + a1c2575 commit be2605c

File tree

2 files changed

+91
-19
lines changed

2 files changed

+91
-19
lines changed

core/editable.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,7 @@
720720
blockLimit = path.blockLimit,
721721
selection = evt.data.selection,
722722
range = selection.getRanges()[ 0 ],
723-
enterMode = editor.config.enterMode,
724-
domChanged = 0;
723+
enterMode = editor.config.enterMode;
725724

726725
if ( CKEDITOR.env.gecko ) {
727726
// v3: check if this is needed.
@@ -735,9 +734,11 @@
735734
// 1. It is really displayed as block; (#7221)
736735
// 2. It doesn't end with one inner block; (#7467)
737736
// 3. It doesn't have bogus br yet.
738-
if ( pathBlock && pathBlock.isBlockBoundary() && !( lastNode && lastNode.type == CKEDITOR.NODE_ELEMENT && lastNode.isBlockBoundary() ) && !pathBlock.is( 'pre' ) && !pathBlock.getBogus() ) {
737+
if ( pathBlock && pathBlock.isBlockBoundary() &&
738+
!( lastNode && lastNode.type == CKEDITOR.NODE_ELEMENT && lastNode.isBlockBoundary() ) &&
739+
!pathBlock.is( 'pre' ) && !pathBlock.getBogus() ) {
740+
739741
pathBlock.appendBogus();
740-
domChanged = 1;
741742
}
742743
}
743744

@@ -768,7 +769,6 @@
768769
var first = fixedBlock.getFirst( isNotEmpty );
769770
if ( first && isNbsp( first ) ) {
770771
first.remove();
771-
domChanged = 1;
772772
}
773773
}
774774

@@ -777,8 +777,6 @@
777777
evt.cancel();
778778
}
779779
}
780-
781-
return domChanged;
782780
}
783781

784782
function blockInputClick( evt ) {
@@ -845,10 +843,13 @@
845843
// Do it only when selection is not locked. (#8222)
846844
if ( sel && !sel.isLocked ) {
847845
var isDirty = editor.checkDirty();
848-
editor.fire( 'saveSnapshot', { contentOnly:1 } );
849-
// Notify undoManager that dom was fixed, so it can update the latest snapshot.
850-
if ( fixDom( evt ) )
851-
editor.fire( 'updateSnapshot' );
846+
847+
// Lock undoM before touching DOM to prevent
848+
// recording these changes as separate snapshot.
849+
editor.fire( 'lockSnapshot' );
850+
fixDom( evt );
851+
editor.fire( 'unlockSnapshot' );
852+
852853
!isDirty && editor.resetDirty();
853854
}
854855
});

plugins/undo/plugin.js

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@
9898
});
9999
}
100100

101+
/**
102+
* Reset undo stack.
103+
*
104+
* @member CKEDITOR.editor
105+
*/
101106
editor.resetUndo = function() {
102107
// Reset the undo stack.
103108
undoManager.reset();
@@ -124,6 +129,27 @@
124129
if ( undoManager.currentImage )
125130
undoManager.update();
126131
});
132+
133+
/**
134+
* Lock manager to prevent any save/update operations.
135+
*
136+
* It's convenient to lock manager before doing DOM operations
137+
* that shouldn't be recored (e.g. auto paragraphing).
138+
*
139+
* See {@link CKEDITOR.plugins.undo.UndoManager#lock} for more details.
140+
*
141+
* @event lockSnapshot
142+
* @member CKEDITOR.editor
143+
*/
144+
editor.on( 'lockSnapshot', undoManager.lock, undoManager );
145+
146+
/**
147+
* Unlock manager and update latest snapshot.
148+
*
149+
* @event unlockSnapshot
150+
* @member CKEDITOR.editor
151+
*/
152+
editor.on( 'unlockSnapshot', undoManager.unlock, undoManager );
127153
}
128154
});
129155

@@ -218,6 +244,16 @@
218244
navigationKeyCodes = { 37:1,38:1,39:1,40:1 }; // Arrows: L, T, R, B
219245

220246
UndoManager.prototype = {
247+
/**
248+
* When `locked` property is not `null` manager is locked, so
249+
* operations like `save` or `update` are forbidden.
250+
*
251+
* Manager can be locked/unlocked by {@link #lock} and {@link #unlock} methods.
252+
*
253+
* @private
254+
* @property {Object} [locked=null]
255+
*/
256+
221257
/**
222258
* Process undo system regard keystrikes.
223259
* @param {CKEDITOR.dom.event} event
@@ -322,9 +358,7 @@
322358

323359
this.hasUndo = false;
324360
this.hasRedo = false;
325-
326-
// Finish transaction.
327-
this.isLocked = false;
361+
this.locked = null;
328362

329363
this.resetType();
330364
},
@@ -354,7 +388,7 @@
354388
*/
355389
save: function( onContentOnly, image, autoFireChange ) {
356390
// Do not change snapshots stack when locked.
357-
if ( this.isLocked )
391+
if ( this.locked )
358392
return false;
359393

360394
var snapshots = this.snapshots;
@@ -402,7 +436,7 @@
402436
// Start transaction - do not allow any mutations to the
403437
// snapshots stack done when selecting bookmarks (much probably
404438
// by selectionChange listener).
405-
this.isLocked = true;
439+
this.locked = 1;
406440

407441
this.editor.loadSnapshot( image.contents );
408442

@@ -417,7 +451,7 @@
417451
$range.select();
418452
}
419453

420-
this.isLocked = false;
454+
this.locked = 0;
421455

422456
this.index = image.index;
423457

@@ -514,9 +548,46 @@
514548
* Update the last snapshot of the undo stack with the current editor content.
515549
*/
516550
update: function() {
517-
// Do not change snapshots stack when locked.
518-
if ( !this.isLocked )
551+
// Do not change snapshots stack is locked.
552+
if ( !this.locked )
519553
this.snapshots.splice( this.index, 1, ( this.currentImage = new Image( this.editor ) ) );
554+
},
555+
556+
/**
557+
* Lock the snapshot stack to prevent any save/update operations, and additionally
558+
* update the tip snapshot with the DOM changes during the locked period when necessary,
559+
* after the {@link #unlock} method is called.
560+
*
561+
* It's mainly used for ensure any DOM operations that shouldn't be recorded (e.g. auto paragraphing).
562+
*/
563+
lock: function() {
564+
if ( !this.locked ) {
565+
var snapBefore = this.editor.getSnapshot();
566+
567+
// If current editor content matches the tip of snapshot stack,
568+
// the stack tip must be updated by unlock, to include any changes made
569+
// during this period.
570+
var matchedTip = this.currentImage && snapBefore == this.currentImage.contents;
571+
572+
this.locked = { update: matchedTip ? snapBefore : null };
573+
}
574+
},
575+
576+
/**
577+
* Unlock the snapshot stack and check to amend the last snapshot.
578+
*
579+
* See {@link #lock} for more details.
580+
*/
581+
unlock: function() {
582+
if ( this.locked ) {
583+
var update = this.locked.update,
584+
snap = this.editor.getSnapshot();
585+
586+
this.locked = null;
587+
588+
if ( typeof update == 'string' && snap != update )
589+
this.update();
590+
}
520591
}
521592
};
522593
})();

0 commit comments

Comments
 (0)