diff --git a/src/entercommand.js b/src/entercommand.js index db5478b..b267717 100644 --- a/src/entercommand.js +++ b/src/entercommand.js @@ -8,6 +8,7 @@ */ import Command from '@ckeditor/ckeditor5-core/src/command'; +import { getCopyOnEnterAttributes } from './utils'; /** * Enter command. It is used by the {@link module:enter/enter~Enter Enter feature} to handle the Enter key. @@ -56,7 +57,9 @@ function enterBlock( model, writer, selection, schema ) { } if ( isSelectionEmpty ) { + const attributesToCopy = getCopyOnEnterAttributes( writer.model.schema, selection.getAttributes() ); splitBlock( writer, range.start ); + writer.setSelectionAttribute( attributesToCopy ); } else { const leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd ); const isContainedWithinOneElement = ( startElement == endElement ); diff --git a/src/shiftentercommand.js b/src/shiftentercommand.js index 5944238..ceb6d22 100644 --- a/src/shiftentercommand.js +++ b/src/shiftentercommand.js @@ -8,6 +8,7 @@ */ import Command from '@ckeditor/ckeditor5-core/src/command'; +import { getCopyOnEnterAttributes } from './utils'; /** * ShiftEnter command. It is used by the {@link module:enter/shiftenter~ShiftEnter ShiftEnter feature} to handle @@ -81,7 +82,11 @@ function softBreakAction( model, writer, selection ) { const isContainedWithinOneElement = ( startElement == endElement ); if ( isSelectionEmpty ) { + const attributesToCopy = getCopyOnEnterAttributes( model.schema, selection.getAttributes() ); insertBreak( writer, range.end ); + + writer.removeSelectionAttribute( selection.getAttributeKeys() ); + writer.setSelectionAttribute( attributesToCopy ); } else { const leaveUnmerged = !( range.start.isAtStart && range.end.isAtEnd ); model.deleteContent( selection, { leaveUnmerged } ); diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..66a68ac --- /dev/null +++ b/src/utils.js @@ -0,0 +1,26 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license + */ + +/** + * @module enter/utils + */ + +/** + * Returns attributes that should be preserved on the enter key. + * + * Filtering is realized based on `copyOnEnter` attribute property. Read more about attribute properties + * {@link module:engine/model/schema~Schema#setAttributeProperties here}. + * + * @param {module:engine/model/schema~Schema} schema + * @param {Iterable.<*>} allAttributes attributes to filter. + * @returns {Iterable.<*>} + */ +export function* getCopyOnEnterAttributes( schema, allAttributes ) { + for ( const attribute of allAttributes ) { + if ( attribute && schema.getAttributeProperties( attribute[ 0 ] ).copyOnEnter ) { + yield attribute; + } + } +} diff --git a/tests/entercommand.js b/tests/entercommand.js index d8e7217..3d5f52c 100644 --- a/tests/entercommand.js +++ b/tests/entercommand.js @@ -87,6 +87,31 @@ describe( 'EnterCommand', () => { '
x
[]
y
', 'x
[]
y
' ); + + describe( 'copyOnEnter', () => { + beforeEach( () => { + schema.extend( '$text', { allowAttributes: [ 'foo', 'bar' ] } ); + schema.setAttributeProperties( 'foo', { copyOnEnter: true } ); + } ); + + test( + 'allowed attributes are copied', + '<$text foo="true">test[]$text>
', + '<$text foo="true">test$text>
<$text foo="true">[]$text>
' + ); + + test( + 'unknown attributes are not copied', + '<$text bar="true">test[]$text>
', + '<$text bar="true">test$text>
[]
' + ); + + test( + 'only allowed attributes are copied from mix set', + '<$text bar="true" foo="true">test[]$text>
', + '<$text bar="true" foo="true">test$text>
<$text foo="true">[]$text>
' + ); + } ); } ); describe( 'non-collapsed selection', () => { diff --git a/tests/shiftentercommand.js b/tests/shiftentercommand.js index ca12217..08b5be6 100644 --- a/tests/shiftentercommand.js +++ b/tests/shiftentercommand.js @@ -101,6 +101,31 @@ describe( 'ShiftEnterCommand', () => { 'x
[]foo
y
', 'x
y
' ); + + describe( 'copyOnEnter', () => { + beforeEach( () => { + schema.extend( '$text', { allowAttributes: [ 'foo', 'bar' ] } ); + schema.setAttributeProperties( 'foo', { copyOnEnter: true } ); + } ); + + test( + 'allowed attributes are copied', + '<$text foo="true">test[]$text>
', + '<$text foo="true">test$text>
<$text bar="true">test[]$text>
', + '<$text bar="true">test$text>
<$text bar="true" foo="true">test[]$text>
', + '<$text bar="true" foo="true">test$text>