-
-
Save Reinmar/1acce88add99964be1c6 to your computer and use it in GitHub Desktop.
Plugin for CKEditor which changes enter key behaviour so it keeps the block's style.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( function() { | |
'use strict'; | |
CKEDITOR.plugins.add( 'enterkeepstyles', { | |
init: function( editor ) { | |
var comboStyles = []; | |
/** | |
* Block styles defined in {@link CKEDITOR.config#stylesSet editor's style set}. | |
* | |
* @property {CKEDITOR.style[]} | |
*/ | |
this.comboStyles = comboStyles; | |
/** | |
* Formats defined in {@link CKEDITOR.config#format_tags}. | |
* | |
* @property {CKEDITOR.style[]} | |
*/ | |
this.formatStyles = this.getFormatStyles( editor.config ); | |
// We can only get combo styles asynchronously. | |
editor.on( 'stylesSet', function( evt ) { | |
var stylesDefinitions = evt.data.styles, | |
style; | |
for ( var i = 0; i < stylesDefinitions.length; i++ ) { | |
style = new CKEDITOR.style( stylesDefinitions[ i ] ); | |
if ( style.type == CKEDITOR.STYLE_BLOCK ) { | |
comboStyles.push( style ); | |
} | |
} | |
} ); | |
this.attachEnterListeners( editor ); | |
}, | |
/** | |
* Attaches listeners to the `enter` command to change its behaviour. | |
* | |
* One of the listeners will be called right before `enter` command is executed and will memorise | |
* active styles. Second one will be called after `enter` command is executed and will | |
* apply the memorised styles. | |
* | |
* @param {CKEDITOR.editor} editor | |
*/ | |
attachEnterListeners: function( editor ) { | |
var activeStyles = [], | |
that = this; | |
// Memorise which styles have been active before | |
// enter command is executed. | |
editor.on( 'beforeCommandExec', function( evt ) { | |
if ( evt.data.name != 'enter' ) { | |
return; | |
} | |
activeStyles = that.getActiveStyles( editor ); | |
} ); | |
// Apply the memorised styles after enter command was executed. | |
// Make sure that we don't create a new undo snapshot for these changes. | |
editor.on( 'afterCommandExec', function( evt ) { | |
if ( evt.data.name != 'enter' ) { | |
return; | |
} | |
if ( activeStyles.length ) { | |
// Lock undo manager while we are applying styles/ | |
// so any changes to the DOM will be merged into the previous snapshot | |
// meaning that enter key plus these changes will be just a one undo step. | |
editor.fire( 'lockSnapshot', { | |
forceUpdate: true | |
} ); | |
while ( activeStyles.length ) { | |
editor.applyStyle( activeStyles.pop() ); | |
} | |
editor.fire( 'unlockSnapshot' ); | |
} | |
} ); | |
}, | |
/** | |
* Returns an array of active styles. | |
* | |
* Styles that are going to be checked: | |
* | |
* * {@link #comboStyles} — it is possible that more than one of these styles | |
* is active at the same moment, so more than one may be returned. | |
* * {@link #formatStyles} — if none of the {@link #comboStyles} is active | |
* one of formats may be returned. | |
* | |
* **Note:** If any of the combo's styles is active formats will not be checked, because | |
* the first style already defines the element name. | |
* | |
* @param {CKEDITOR.editor} editor | |
* @returns {CKEDITOR.style[]} The array of active styles. | |
*/ | |
getActiveStyles: function( editor ) { | |
var elementPath = editor.elementPath(), | |
i, | |
activeStyles = []; | |
for ( i = 0; i < this.comboStyles.length; ++i ) { | |
if ( this.comboStyles[ i ].checkActive( elementPath, editor ) ) { | |
activeStyles.push( this.comboStyles[ i ] ); | |
} | |
} | |
// In all correct cases it doesn't make sense to check formats if one of combo styles | |
// is active, because it already defines the element name. | |
if ( activeStyles.length ) { | |
return activeStyles; | |
} | |
for ( i = 0; i < this.formatStyles.length; ++i ) { | |
if ( this.formatStyles[ i ].checkActive( elementPath, editor ) ) { | |
return [ this.formatStyles[ i ] ]; | |
} | |
} | |
return []; | |
}, | |
/** | |
* Parses {@link CKEDITOR.config#format_tags} and related `format_*` options and returns | |
* an array of format styles. | |
* | |
* @param {CKEDITOR.config} | |
* @returns {CKEDITOR.style[]} | |
*/ | |
getFormatStyles: function( config ) { | |
var tags = config.format_tags, | |
tag, | |
styles = []; | |
if ( !tags ) { | |
return []; | |
} | |
tags = tags.split( ';' ); | |
while ( ( tag = tags.pop() ) ) { | |
styles.push( new CKEDITOR.style( config[ 'format_' + tag ] ) ); | |
} | |
return styles; | |
} | |
} ); | |
} )(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment