Skip to content

Commit

Permalink
Merge branch 't/12448' into major
Browse files Browse the repository at this point in the history
  • Loading branch information
Reinmar committed Dec 2, 2014
2 parents 33c8854 + 553a5eb commit 18d651a
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 54 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ New Features:
* [#11583](http://dev.ckeditor.com/ticket/11583): Added support for HTML5 `required` attribute in various form elements. Thanks to [Steven Busse](https://github.com/sbusse)!
* [#12143](http://dev.ckeditor.com/ticket/12143): Added [`config.floatSpacePreferRight`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-floatSpacePreferRight) configuration option that switches the alignment of the floating toolbar. Thanks to [InvisibleBacon](http://github.com/InvisibleBacon)!
* [#12416](http://dev.ckeditor.com/ticket/12416): Added [`widget.definition.upcastPriority`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-upcastPriority) property which gives more control over widgets upcasting order to the widget author.
* [#12448](http://dev.ckeditor.com/ticket/12448): Set of new methods, params and events giving the developer more control over HTML insertion. See the [`editable.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertHtml) param `range`, the [`editable.insertHtmlIntoRange()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertHtmlIntoRange) method and the [`editor.afterInsertHtml`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-afterInsertHtml) event.

Fixed Issues:

Expand Down
112 changes: 83 additions & 29 deletions core/editable.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,25 +231,18 @@
},

/**
* @see CKEDITOR.editor#insertHtml
*/
insertHtml: function( data, mode ) {
beforeInsert( this );
// Default mode is 'html'.
insert( this, mode || 'html', data );
},

/**
* @see CKEDITOR.editor#insertText
* Low-level method for inserting text into the editable.
* See the {@link CKEDITOR.editor#method-insertText} method which is the editor-level API
* for this purpose.
*
* @param {String} text
*/
insertText: function( text ) {
beforeInsert( this );
insert( this, 'text', this.transformPlainTextToHtml( text ) );
this.insertHtml( this.transformPlainTextToHtml( text ), 'text' );
},

/**
* Set enterMode based on current selection and {@link CKEDITOR.editor#activeEnterMode}
* and call {@link CKEDITOR.tools#transformPlainTextToHtml}.
* Transforms plain text to HTML based on current selection and {@link CKEDITOR.editor#activeEnterMode}.
*
* @since 4.5
* @param {String} text Text to transform.
Expand All @@ -263,9 +256,79 @@
return CKEDITOR.tools.transformPlainTextToHtml( text, enterMode );
},

/**
* Low-level method for inserting HTML into the editable.
* See the {@link CKEDITOR.editor#method-insertHtml} method which is the editor-level API
* for this purpose.
*
* @param {String} data The HTML to be inserted.
* @param {String} [mode='html'] See {@link CKEDITOR.editor#method-insertHtml}'s param.
* @param {CKEDITOR.dom.range} [range] If specified the HTML will be inserted into the range
* instead of into the selection.
*/
insertHtml: function( data, mode, range ) {
if ( !range )
this.insertHtmlIntoSelection( data, mode );
else
this.insertHtmlIntoRange( data, range, mode );
},

/**
* Inserts HTML into the selection. See also the {@link #insertHtml} method.
*
* Fires the {@link CKEDITOR.editor#event-afterInsertHtml} event.
*
* @since 4.5
* @param {String} data The HTML to be inserted.
* @param {String} [mode='html'] See {@link CKEDITOR.editor#method-insertHtml}'s param.
*/
insertHtmlIntoSelection: function( data, mode ) {
// HTML insertion only considers the first range.
// Note: getRanges will be overwritten for tests since we want to test
// custom ranges and bypass native selections.
var range = this.editor.getSelection().getRanges()[ 0 ];

beforeInsert( this );

// Default mode is 'html'.
insert( this, mode || 'html', data, range );

// Make the final range selection.
range.select();

afterInsert( this );

this.editor.fire( 'afterInsertHtml', {} );
},

/**
* Inserts HTML into the position in the editor determined by the range.
*
* Fires the {@link CKEDITOR.editor#event-afterInsertHtml} event.
*
* **Note:** This method does not {@link CKEDITOR.editor#saveSnashot save undo snapshots}.
*
* @since 4.5
* @param {String} data HTML code to be inserted into the editor.
* @param {CKEDITOR.dom.range} range The range as a place of insertion.
* @param {String} [mode='html'] Mode in which HTML will be inserted.
* See {@link CKEDITOR.editor#method-insertHtml}.
*/
insertHtmlIntoRange: function( data, range, mode ) {
// Default mode is 'html'
insert( this, mode || 'html', data, range );

this.editor.fire( 'afterInsertHtml', { intoRange: range } );
},

/**
* @see CKEDITOR.editor#insertElement
* Low-level method for inserting an element into the editable.
* See the {@link CKEDITOR.editor#method-insertElement} method which is the editor-level API
* for this purpose.
*
* @param {CKEDITOR.dom.element} element The element to insert.
* @param {CKEDITOR.dom.range} [range] If specified the element will be inserted into the range
* instead of into the selection.
*/
insertElement: function( element, range ) {
if ( !range )
Expand All @@ -275,7 +338,9 @@
},

/**
* Inserts an element into the position in the editor determined by range.
* Inserts an element into the position in the editor determined by the range.
*
* **Note:** This method does not {@link CKEDITOR.editor#saveSnashot save undo snapshots}.
*
* @param {CKEDITOR.dom.element} element The element to be inserted.
* @param {CKEDITOR.dom.range} range The range as a place of insertion.
Expand Down Expand Up @@ -332,7 +397,7 @@
},

/**
* Inserts an element into the currently selected position in the editor.
* Inserts an element into the selection.
*
* @param {CKEDITOR.dom.element} element The element to be inserted.
*/
Expand Down Expand Up @@ -1260,14 +1325,8 @@

// Inserts the given (valid) HTML into the range position (with range content deleted),
// guarantee it's result to be a valid DOM tree.
function insert( editable, type, data ) {
function insert( editable, type, data, range ) {
var editor = editable.editor,
selection = editor.getSelection(),
// HTML insertion only considers the first range.
// Note: getRanges will be overwritten for tests since we want to test
// custom ranges and bypass native selections.
// TODO what should we do with others? Remove?
range = selection.getRanges()[ 0 ],
dontFilter = false;

if ( type == 'unfiltered_html' ) {
Expand Down Expand Up @@ -1320,11 +1379,6 @@
// Set final range position and clean up.

cleanupAfterInsertion( that );

// Make the final range selection.
range.select();

afterInsert( editable );
}

// Prepare range to its data deletion.
Expand Down
32 changes: 29 additions & 3 deletions core/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,10 @@
*
* CKEDITOR.instances.editor1.insertHtml( '<p>This is a new paragraph.</p>' );
*
* Fires the {@link #event-insertHtml} and {@link #event-afterInsertHtml} events. The HTML is inserted
* in {@link #event-insertHtml} event's listener with a default priority (10) so you can add listeners with
* lower or higher priorities in order to execute some code before or after the HTML is inserted.
*
* @param {String} html HTML code to be inserted into the editor.
* @param {String} [mode='html'] The mode in which the HTML code will be inserted. One of the following:
*
Expand All @@ -1041,6 +1045,10 @@
*
* CKEDITOR.instances.editor1.insertText( ' line1 \n\n line2' );
*
* Fires the {@link #event-insertText} and {@link #event-afterInsertHtml} events. The text is inserted
* in {@link #event-insertText} event's listener with a default priority (10) so you can add listeners with
* lower or higher priorities in order to execute some code before or after the text is inserted.
*
* @since 3.5
* @param {String} text Text to be inserted into the editor.
*/
Expand All @@ -1055,6 +1063,10 @@
* var element = CKEDITOR.dom.element.createFromHtml( '<img src="hello.png" border="0" title="Hello" />' );
* CKEDITOR.instances.editor1.insertElement( element );
*
* Fires the {@link #event-insertElement} event. The element is inserted in listener with a default priority (10)
* so you can add listeners with lower or higher priorities in order to execute some code before or after
* the element is inserted.
*
* @param {CKEDITOR.dom.element} element The element to be inserted
* into the editor.
*/
Expand Down Expand Up @@ -1701,7 +1713,8 @@ CKEDITOR.ELEMENT_MODE_INLINE = 3;
*/

/**
* Internal event to perform the {@link #method-insertHtml} call.
* Fired by the {@link #method-insertHtml} method. See the method documentation for more information
* on how this event can be used.
*
* @event insertHtml
* @param {CKEDITOR.editor} editor This editor instance.
Expand All @@ -1711,21 +1724,34 @@ CKEDITOR.ELEMENT_MODE_INLINE = 3;
*/

/**
* Internal event to perform the {@link #method-insertText} call.
* Fired by the {@link #method-insertText} method. See the method documentation for more information
* on how this event can be used.
*
* @event insertText
* @param {CKEDITOR.editor} editor This editor instance.
* @param {String} data The text to insert.
*/

/**
* Internal event to perform the {@link #method-insertElement} call.
* Fired by the {@link #method-insertElement} method. See the method documentation for more information
* on how this event can be used.
*
* @event insertElement
* @param {CKEDITOR.editor} editor This editor instance.
* @param {CKEDITOR.dom.element} data The element to insert.
*/

/**
* Event fired after data insertion using insertHtml or insertHtmlIntoRange methods.
*
* @since 4.5
* @event afterInsertHtml
* @param data
* @param {CKEDITOR.dom.range} [data.intoRange] If set the HTML was inserted into the range
* instead of into the selection. See the {@link CKEDITOR.editable#insertHtml} method which accepts range
* as a parameter.
*/

/**
* Event fired after the {@link #property-readOnly} property changes.
*
Expand Down
21 changes: 11 additions & 10 deletions plugins/widget/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2626,18 +2626,19 @@
} );

// Listen with high priority to check widgets after data was inserted.
editor.on( 'insertText', checkNewWidgets, null, null, 999 );
editor.on( 'insertHtml', checkNewWidgets, null, null, 999 );

function checkNewWidgets() {
editor.fire( 'lockSnapshot' );
editor.on( 'afterInsertHtml', function( evt ) {
if ( evt.data.intoRange ) {
widgetsRepo.checkWidgets( { initOnlyNew: true } );
} else {
editor.fire( 'lockSnapshot' );

// Init only new for performance reason.
// Focus inited if only widget was processed.
widgetsRepo.checkWidgets( { initOnlyNew: true, focusInited: processedWidgetOnly } );
// Init only new for performance reason.
// Focus inited if only widget was processed.
widgetsRepo.checkWidgets( { initOnlyNew: true, focusInited: processedWidgetOnly } );

editor.fire( 'unlockSnapshot' );
}
editor.fire( 'unlockSnapshot' );
}
} );
}

// Helper for coordinating which widgets should be
Expand Down
16 changes: 14 additions & 2 deletions tests/core/editable/_helpers/insertion.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ var insertionDT = ( function() {
assertInsertion: function( editablesNames, source, insertion, expected, enterMode, message ) {
var editableName, result, editor, modes, mode,
root, checkAllModes, rangeList, revertChanges, revertChanges2,
expectedForMode;
expectedForMode, afterInsertCount, afterInsertData;

editablesNames = editablesNames.split( ',' );
// Check all supported modes if expected value is a string or regexp.
Expand Down Expand Up @@ -97,7 +97,7 @@ var insertionDT = ( function() {
while ( 1 ) {
var startContainer = range.startContainer,
startOffset = range.startOffset;
// Limit the fix only to non-block elements.(#3950)
// Limit the fix only to non-block elements. (#3950)
if (
startOffset ==
(
Expand Down Expand Up @@ -146,13 +146,20 @@ var insertionDT = ( function() {
editor = this.editorsPool[ editableName ];
root = editor.editable();

editor.on( 'afterInsertHtml', function( evt ) {
afterInsertCount++;
afterInsertData = evt.data;
} );

// Set enter mode to the given value or reset to the default one.
editor.enterMode = enterMode || editor._.defaultEnterMode;

for ( mode in modes ) {
// Selection::getRanges() will read from this variable.
rangeList = new CKEDITOR.dom.rangeList( tools.setHtmlWithRange( root, source, root ) );

afterInsertCount = 0;

if ( mode == 'insertElement' )
editor.insertElement( CKEDITOR.dom.element.createFromHtml( insertion, editor.document ) );
else if ( mode == 'insertText' )
Expand All @@ -172,6 +179,11 @@ var insertionDT = ( function() {
assert[ expectedForMode.exec ? 'isMatching' : 'areSame' ]( expectedForMode, result,
( message || 'editor\'s content should equal expected value' ) +
' (editable: "' + editableName + '" & mode: "' + mode + '")' );

if ( mode != 'insertElement' ) {
assert.areSame( 1, afterInsertCount, 'There should be 1 afterInsertHtml event after every insertion.' );
assert.isUndefined( afterInsertData.intoRange, 'intoRange parameter should be undefined.' );
}
}
}

Expand Down
Loading

0 comments on commit 18d651a

Please sign in to comment.