Skip to content

Commit

Permalink
Merge branch 't/11909'
Browse files Browse the repository at this point in the history
  • Loading branch information
Reinmar committed Jun 16, 2014
2 parents c151a1b + 74ed892 commit 7ffe649
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 44 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ Important Notes:

* We made CKEditor tests environment public. CKEditor tests can be found in the [`tests/`](https://github.com/ckeditor/ckeditor-dev/tree/master/tests) directory. Read more how to set up the environment and execute tests in the [CKEditor Tests Environment](http://docs.ckeditor.com/#!/guide/dev_tests) guide.

New Features:

* [#11909](http://dev.ckeditor.com/ticket/11909): Introduced a parameter to prevent [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData) from recording undo snapshots.

Fixed Issues:

* [#11757](http://dev.ckeditor.com/ticket/11757): Fixed: Imperfections in the [Moono](http://ckeditor.com/addon/moono) skin. Thanks to [danyaPostfactum](https://github.com/danyaPostfactum)!
Expand Down
44 changes: 33 additions & 11 deletions core/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -926,20 +926,42 @@
*
* CKEDITOR.instances.editor1.setData( '<p>This is the editor data.</p>' );
*
* CKEDITOR.instances.editor1.setData( '<p>Some other editor data.</p>', function() {
* this.checkDirty(); // true
* });
*
* @param {String} data HTML code to replace the curent content in the editor.
* @param {Function} callback Function to be called after the `setData` is completed.
* @param {Boolean} internal Whether to suppress any event firing when copying data internally inside the editor.
* CKEDITOR.instances.editor1.setData( '<p>Some other editor data.</p>', {
* callback: function() {
* this.checkDirty(); // true
* }
* } );
*
* Note: In CKEditor 4.4.2 the signature of this method has changed. All arguments
* except `data` has been wrapped into the `options` object. However, backward compatibility
* has been preserved and it is still possible to use the `data, callback, internal` arguments.
*
*
* @param {String} data HTML code to replace the current content in the editor.
* @param {Object} [options]
* @param {Boolean} [options.internal=false] Whether to suppress any event firing when copying data internally inside the editor.
* @param {Function} [options.callback] Function to be called after the `setData` is completed (on {@link #dataReady}).
* @param {Boolean} [options.noSnapshot=false] If set to `true` will prevent recording undo snapshot.
* Introduced in CKEditor 4.4.2.
*/
setData: function( data, callback, internal ) {
!internal && this.fire( 'saveSnapshot' );
setData: function( data, options, internal ) {
var fireSnapshot = true,
// Backward compatibility.
callback = options,
eventData;

if ( options && typeof options == 'object' ) {
internal = options.internal;
callback = options.callback;
fireSnapshot = !options.noSnapshot;
}

if ( !internal && fireSnapshot )
this.fire( 'saveSnapshot' );

if ( callback || !internal ) {
this.once( 'dataReady', function( evt ) {
if ( !internal )
if ( !internal && fireSnapshot )
this.fire( 'saveSnapshot' );

if ( callback )
Expand All @@ -948,7 +970,7 @@
}

// Fire "setData" so data manipulation may happen.
var eventData = { dataValue: data };
eventData = { dataValue: data };
!internal && this.fire( 'setData', eventData );

this._.data = eventData.dataValue;
Expand Down
124 changes: 91 additions & 33 deletions tests/core/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,62 +90,120 @@ bender.test(
/**
* Test editor core data retrieval and manipulation functionality.
*/
test_getData : function() {
var events = [];
'test getData/setData': function() {
var events = [],
editor = new CKEDITOR.editor( {}, CKEDITOR.document.getById( 'editor4' ), CKEDITOR.ELEMENT_MODE_REPLACE );
function checkEventData( value ) {
return function( evt ) {
events.push( evt.name );

// Check data value.
if ( value )
assert.areSame( value, evt.data.dataValue, 'check data on event: ' + evt.name );

// Alter the data value.
if ( evt.name == 'setData' )
evt.data.dataValue = 'bar';

};
}
// This function allows to call either older API or new object based setData().
// It takes setData() params in new format (as editor#setData()).
function callSetData( data, params, legacyInterface ) {
if ( legacyInterface )
editor.setData( data, params.callback, params.internal );
else
editor.setData( data, params );
}

var editor =
new CKEDITOR.editor( {},
CKEDITOR.document.getById( 'editor4' ),
CKEDITOR.ELEMENT_MODE_REPLACE );

// Events are fired on setData call.
var checker = checkEventData();
var listeners = [],
allEvents = [ 'setData', 'afterSetData', 'beforeGetData', 'getData', 'saveSnapshot' ],
listener = checkEventData();

var listeners = [];
var allEvents = [ 'setData', 'afterSetData', 'beforeGetData', 'getData' ];
for ( var i = 0; i < allEvents.length; i++ )
listeners.push( editor.on( allEvents[ i ], checker ) );
listeners.push( editor.on( allEvents[ i ], listener ) );

// Set/get data internally.
editor.setData( 'foo', null, true );
assert.areSame( 'foo', editor.getData( true ), 'setData internally' );
for ( i = 0; i <= 1; i++ ) {
var useOldAPI = Boolean( i ),
// Helper var with human-readable info what interface version is called.
interfaceName = useOldAPI ? 'old API params inline' :'new API params as object';

// No events should be fired.
arrayAssert.itemsAreEqual( [], events );
events = [];

for ( i = 0; i < listeners.length; i++ )
listeners[ i ].removeListener();
// Test setData/getData internal.
callSetData( 'foo', { internal: true }, useOldAPI );
assert.areSame( 'foo', editor.getData( true ), 'setData internally - ' + interfaceName );
// No events should be fired.
assert.areSame( '', events.join( ',' ), 'Events fired - ' + interfaceName );

// Events are fired on setData call.
editor.on( 'setData', checkEventData( 'foo' ) );
editor.on( 'afterSetData', checkEventData( 'bar' ) );
editor.setData( 'foo' );
events = [];
// Test non-internal setData() - snapshot is expected.
callSetData( 'foo', {}, useOldAPI );

arrayAssert.itemsAreEqual( [ 'setData', 'afterSetData' ], events );
assert.areSame( 'bar', editor.getData(), 'setData listener change data value' );
assert.areSame( 'saveSnapshot,setData,afterSetData', events.join( ',' ),
'Invalid events for setData() - ' + interfaceName );

// Test non-internal getData().
events = [];

assert.areSame( 'bar', editor.getData(), 'setData listener change data value - ' + interfaceName );
assert.areSame( 'beforeGetData,getData', events.join( ',' ) );
}

// New API provides params.noSnapshot, which should prevent saveSnapshot event.
events = [];
// Events are fired on getData call.
editor.on( 'beforeGetData', checkEventData() );
editor.on( 'getData', checkEventData( 'bar' ) );
editor.getData();
callSetData( 'foo', { noSnapshot: true } );

assert.areSame( 'setData,afterSetData', events.join( ',' ), 'Invalid events with params.noSnapshot = true' );
},

'test setData callback': function() {
var callbackCalledTimes = 0,
callback = function() {
callbackCalledTimes += 1;
},
waitTimeout = 80;

this.editor.setData( '<p>setData</p>', { callback: callback } );

wait( function() {
assert.areEqual( 1, callbackCalledTimes, 'Invalid callback calls count' );
// And test for older API.
this.editor.setData( '<p>setData</p>', callback );

wait( function() {
assert.areEqual( 2, callbackCalledTimes, 'Invalid callback calls count 2nd case' );
}, waitTimeout );
}, waitTimeout );
},

'test setData()': function() {
var firedEvents = [],
listeners = [],
editor = this.editor,
subscribedEvents = [ 'setData', 'afterSetData', 'beforeGetData', 'getData' ],
callbackCalledTimes = 0,
callback = function() {
callbackCalledTimes += 1;
},
// This listener will store types of events fired.
listener = function( evt ) {
firedEvents.push( evt.name );
};

// Registering listeners.
for ( var i = 0; i < subscribedEvents.length; i++ )
listeners.push( editor.on( subscribedEvents[ i ], listener ) );

// Legacy interface.
editor.setData( '<p>setData</p>', null, true );
arrayAssert.itemsAreEqual( [], firedEvents );

assert.areEqual( '<p>setData</p>', editor.getData( true ) );
arrayAssert.itemsAreEqual( [], firedEvents );

arrayAssert.itemsAreEqual( [ 'beforeGetData', 'getData' ], events );
assert.isTrue( true );

// Cleanup.
for ( var i = 0; i < listeners.length; i++ )
listeners[ i ].removeListener();
},

updateElement: function( element, mode ) {
Expand Down

0 comments on commit 7ffe649

Please sign in to comment.