Skip to content

Commit 7b210e8

Browse files
author
Piotr Jasiun
committed
Merge branch 't/11027' into major
2 parents d792be6 + 57f8477 commit 7b210e8

File tree

10 files changed

+82
-25
lines changed

10 files changed

+82
-25
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CKEditor 4 Changelog
55

66
New Features:
77

8+
* [#11027](http://dev.ckeditor.com/ticket/11027): Fixed block commands break on widget issue; added contentDomInvalidated event.
89
* [#10886](http://dev.ckeditor.com/ticket/10886): Widgets: added tooltip to the drag handler.
910
* [#10895](http://dev.ckeditor.com/ticket/10895): Image2: added support for server file browsers.
1011
* [#11057](http://dev.ckeditor.com/ticket/11057): Fixed: Regression in #10212 test.

core/editor.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,4 +1754,15 @@ CKEDITOR.ELEMENT_MODE_INLINE = 3;
17541754
*
17551755
* @event contentDomUnload
17561756
* @param {CKEDITOR.editor} editor This editor instance.
1757+
*/
1758+
1759+
/**
1760+
* The event fired when contents DOM changes and some of the references as well as
1761+
* native DOM event listeners could be lost.
1762+
* This event is useful when it is important to keep track of references
1763+
* to elements in the editable contents from code.
1764+
*
1765+
* @since 4.3
1766+
* @event contentDomInvalidated
1767+
* @param {CKEDITOR.editor} editor This editor instance.
17571768
*/

core/selection.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,9 @@
19581958
fake: function( element ) {
19591959
var editor = this.root.editor;
19601960

1961+
// Cleanup after previous selection - e.g. remove hidden sel container.
1962+
this.reset();
1963+
19611964
hideSelection( editor );
19621965

19631966
// Set this value after executing hiseSelection, because it may

plugins/blockquote/plugin.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
exec: function( editor ) {
1717
var state = editor.getCommand( 'blockquote' ).state,
1818
selection = editor.getSelection(),
19-
range = selection && selection.getRanges( true )[ 0 ];
19+
range = selection && selection.getRanges()[ 0 ];
2020

2121
if ( !range )
2222
return;

plugins/indentblock/plugin.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138

139139
exec: function( editor ) {
140140
var selection = editor.getSelection(),
141-
range = selection && selection.getRanges( 1 )[ 0 ],
141+
range = selection && selection.getRanges()[ 0 ],
142142
nearestListBlock;
143143

144144
// If there's some list in the path, then it will be
@@ -156,8 +156,10 @@
156156
iterator.enforceRealBlocks = true;
157157
iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
158158

159-
while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) )
160-
indentElement.call( this, block, classes );
159+
while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) {
160+
if ( !block.isReadOnly() )
161+
indentElement.call( this, block, classes );
162+
}
161163
}
162164

163165
return true;

plugins/indentlist/plugin.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,11 +221,14 @@
221221
}
222222
}
223223

224+
if ( newList )
225+
editor.fire( 'contentDomInvalidated' );
226+
224227
return true;
225228
}
226229

227230
var selection = editor.getSelection(),
228-
ranges = selection && selection.getRanges( 1 ),
231+
ranges = selection && selection.getRanges(),
229232
iterator = ranges.createIterator(),
230233
range;
231234

plugins/justify/plugin.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
return;
135135

136136
var bookmarks = selection.createBookmarks(),
137-
ranges = selection.getRanges( true );
137+
ranges = selection.getRanges();
138138

139139
var cssClassName = this.cssClassName,
140140
iterator, block;
@@ -147,6 +147,9 @@
147147
iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
148148

149149
while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) {
150+
if ( block.isReadOnly() )
151+
continue;
152+
150153
block.removeAttribute( 'align' );
151154
block.removeStyle( 'text-align' );
152155

plugins/list/plugin.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,8 @@
291291
listsCreated.push( child );
292292
}
293293
newList.listNode.replace( groupObj.root );
294+
295+
editor.fire( 'contentDomInvalidated' );
294296
}
295297

296298
var headerTagRegex = /^h[1-6]$/;
@@ -443,6 +445,8 @@
443445
compensateBrs();
444446

445447
docFragment.replace( groupObj.root );
448+
449+
editor.fire( 'contentDomInvalidated' );
446450
}
447451

448452
function listCommand( name, type ) {
@@ -476,7 +480,7 @@
476480
var doc = editor.document,
477481
config = editor.config,
478482
selection = editor.getSelection(),
479-
ranges = selection && selection.getRanges( true );
483+
ranges = selection && selection.getRanges();
480484

481485
// Midas lists rule #1 says we can create a list even in an empty document.
482486
// But DOM iterator wouldn't run if the document is really empty.

plugins/undo/plugin.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -181,20 +181,25 @@
181181
* @class CKEDITOR.plugins.undo.Image
182182
* @constructor Creates an Image class instance.
183183
* @param {CKEDITOR.editor} editor The editor instance on which the image is created.
184+
* @param {Boolean} [contentsOnly] If set to `true` image will contain only contents, without selection.
184185
*/
185-
var Image = CKEDITOR.plugins.undo.Image = function( editor ) {
186+
var Image = CKEDITOR.plugins.undo.Image = function( editor, contentsOnly ) {
186187
this.editor = editor;
187188

188189
editor.fire( 'beforeUndoImage' );
189190

190-
var contents = editor.getSnapshot(),
191-
selection = contents && editor.getSelection();
191+
var contents = editor.getSnapshot();
192192

193193
// In IE, we need to remove the expando attributes.
194-
CKEDITOR.env.ie && contents && ( contents = contents.replace( /\s+data-cke-expando=".*?"/g, '' ) );
194+
if ( CKEDITOR.env.ie && contents )
195+
contents = contents.replace( /\s+data-cke-expando=".*?"/g, '' );
195196

196197
this.contents = contents;
197-
this.bookmarks = selection && selection.createBookmarks2( true );
198+
199+
if ( !contentsOnly ) {
200+
var selection = contents && editor.getSelection();
201+
this.bookmarks = selection && selection.createBookmarks2( true );
202+
}
198203

199204
editor.fire( 'afterUndoImage' );
200205
};
@@ -614,7 +619,12 @@
614619
*/
615620
lock: function() {
616621
if ( !this.locked ) {
617-
var imageBefore = new Image( this.editor );
622+
// Make a contents image. Don't include bookmarks, because:
623+
// * we don't compare them,
624+
// * there's a chance that DOM has been changed since
625+
// locked (e.g. fake) selection was made, so createBookmark2 could fail.
626+
// http://dev.ckeditor.com/ticket/11027#comment:3
627+
var imageBefore = new Image( this.editor, true );
618628

619629
// If current editor content matches the tip of snapshot stack,
620630
// the stack tip must be updated by unlock, to include any changes made
@@ -640,12 +650,12 @@
640650
// Decrease level of lock and check if equals 0, what means that undoM is completely unlocked.
641651
if ( !--this.locked.level ) {
642652
var updateImage = this.locked.update,
643-
newImage = new Image( this.editor );
653+
newImage = new Image( this.editor, true );
644654

645655
this.locked = null;
646656

647657
if ( updateImage && !updateImage.equalsContent( newImage ) )
648-
this.update( newImage );
658+
this.update();
649659
}
650660
}
651661
}

plugins/widget/plugin.js

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -256,24 +256,40 @@
256256
/**
257257
* Checks if all widget instances are still present in the DOM.
258258
* Destroys those instances that are not present.
259+
* Reinitializes widgets on widget wrappers for which widget instances
260+
* cannot be found.
259261
*
260262
* This method is triggered by the {@link #event-checkWidgets} event.
261263
*/
262264
checkWidgets: function() {
263265
if ( this.editor.mode != 'wysiwyg' )
264266
return;
265267

266-
var toBeDestroyed = [],
267-
editable = this.editor.editable(),
268+
var editable = this.editor.editable(),
268269
instances = this.instances,
269-
id;
270+
i, count, wrapper;
270271

271272
if ( !editable )
272273
return;
273274

274-
for ( id in instances ) {
275-
if ( !editable.contains( instances[ id ].wrapper ) )
276-
this.destroy( instances[ id ], true );
275+
// Remove widgets which have no corresponding elements in DOM.
276+
for ( i in instances ) {
277+
if ( !editable.contains( instances[ i ].wrapper ) )
278+
this.destroy( instances[ i ], true );
279+
}
280+
281+
var wrappers = editable.find( '.cke_widget_wrapper' );
282+
283+
// Create widgets on existing wrappers if they do not exists.
284+
for ( i = 0, count = wrappers.count(); i < count; i++ ) {
285+
wrapper = wrappers.getItem( i );
286+
287+
if ( !this.getByElement( wrapper, true ) ) {
288+
// Add cke_widget_new class because otherwise
289+
// widget will not be created on such wrapper.
290+
wrapper.addClass( 'cke_widget_new' );
291+
this.initOn( wrapper.getFirst( isWidgetElement2 ) );
292+
}
277293
}
278294
},
279295

@@ -416,7 +432,7 @@
416432
* Initializes a widget on a given element if the widget has not been initialized on it yet.
417433
*
418434
* @param {CKEDITOR.dom.element} element The future widget element.
419-
* @param {String/CKEDITOR.plugins.widget.definition} widgetDef Name of a widget or a widget definition.
435+
* @param {String/CKEDITOR.plugins.widget.definition} [widgetDef] Name of a widget or a widget definition.
420436
* The widget definition should be previously registered by using the
421437
* {@link CKEDITOR.plugins.widget.repository#add} method.
422438
* @param [startupData] Widget startup data (has precedence over default one).
@@ -2154,9 +2170,7 @@
21542170
// * keyup.
21552171
function setupWidgetsObserver( widgetsRepo ) {
21562172
var editor = widgetsRepo.editor,
2157-
buffer = CKEDITOR.tools.eventsBuffer( widgetsRepo.MIN_WIDGETS_CHECK_INTERVAL, function() {
2158-
widgetsRepo.fire( 'checkWidgets' );
2159-
} ),
2173+
buffer = CKEDITOR.tools.eventsBuffer( widgetsRepo.MIN_WIDGETS_CHECK_INTERVAL, checkWidgets ),
21602174
ignoredKeys = { 16:1,17:1,18:1,37:1,38:1,39:1,40:1,225:1 }; // SHIFT,CTRL,ALT,LEFT,UP,RIGHT,DOWN,RIGHT ALT(FF)
21612175

21622176
editor.on( 'contentDom', function() {
@@ -2172,6 +2186,12 @@
21722186
editor.on( 'contentDomUnload', buffer.reset );
21732187

21742188
widgetsRepo.on( 'checkWidgets', widgetsRepo.checkWidgets, widgetsRepo );
2189+
2190+
editor.on( 'contentDomInvalidated', checkWidgets );
2191+
2192+
function checkWidgets() {
2193+
widgetsRepo.fire( 'checkWidgets' );
2194+
}
21752195
}
21762196

21772197
// Helper for coordinating which widgets should be

0 commit comments

Comments
 (0)