Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

downcastAttributeToElement should let specify from what element the model attribute will be converted #1373

Merged
merged 1 commit into from
Mar 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/conversion/conversion.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,30 @@ export default class Conversion {
* }
* } );
*
* // Use `config.model.name` to define conversion only from given node type, `$text` in this case.
* // The same attribute on different elements may be then handled by a different converter.
* conversion.attributeToElement( {
* model: {
* key: 'textDecoration',
* values: [ 'underline', 'lineThrough' ],
* name: '$text'
* },
* view: {
* underline: {
* name: 'span',
* style: {
* 'text-decoration': 'underline'
* }
* },
* lineThrough: {
* name: 'span',
* style: {
* 'text-decoration': 'line-through'
* }
* }
* }
* } );
*
* // Use `upcastAlso` to define other view elements that should be also converted to `bold` attribute.
* conversion.attributeToElement( {
* model: 'bold',
Expand Down
17 changes: 16 additions & 1 deletion src/conversion/downcast-converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,16 @@ export function downcastElementToElement( config ) {
* }
* } );
*
* downcastAttributeToElement( {
* model: {
* key: 'color',
* name: '$text'
* },
* view: ( modelAttributeValue, viewWriter ) => {
* return viewWriter.createAttributeElement( 'span', { style: 'color:' + modelAttributeValue } );
* }
* } );
*
* See {@link module:engine/conversion/conversion~Conversion#for} to learn how to add converter to conversion process.
*
* @param {Object} config Conversion configuration.
Expand All @@ -120,6 +130,11 @@ export function downcastAttributeToElement( config ) {
config = cloneDeep( config );

const modelKey = config.model.key ? config.model.key : config.model;
let eventName = 'attribute:' + modelKey;

if ( config.model.name ) {
eventName += ':' + config.model.name;
}

if ( config.model.values ) {
for ( const modelValue of config.model.values ) {
Expand All @@ -132,7 +147,7 @@ export function downcastAttributeToElement( config ) {
const elementCreator = _getFromAttributeCreator( config );

return dispatcher => {
dispatcher.on( 'attribute:' + modelKey, wrap( elementCreator ), { priority: config.priority || 'normal' } );
dispatcher.on( eventName, wrap( elementCreator ), { priority: config.priority || 'normal' } );
};
}

Expand Down
43 changes: 43 additions & 0 deletions tests/conversion/conversion.js
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,49 @@ describe( 'Conversion', () => {
'<p>Foo bar</p>'
);
} );

it( 'config.model.name is given', () => {
schema.extend( '$text', {
allowAttributes: [ 'textDecoration' ]
} );

conversion.attributeToElement( {
model: {
key: 'textDecoration',
values: [ 'underline', 'lineThrough' ],
name: '$text'
},
view: {
underline: {
name: 'span',
style: {
'text-decoration': 'underline'
}
},
lineThrough: {
name: 'span',
style: {
'text-decoration': 'line-through'
}
}
}
} );

test(
'<p><span style="text-decoration:underline">Foo</span></p>',
'<paragraph><$text textDecoration="underline">Foo</$text></paragraph>'
);

test(
'<p><span style="text-decoration:line-through">Foo</span></p>',
'<paragraph><$text textDecoration="lineThrough">Foo</$text></paragraph>'
);

test(
'<p><span style="text-decoration:underline">Foo</span></p>',
'<paragraph><$text textDecoration="underline">Foo</$text></paragraph>'
);
} );
} );

describe( 'attributeToAttribute', () => {
Expand Down
31 changes: 31 additions & 0 deletions tests/conversion/downcast-converters.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,37 @@ describe( 'downcast-helpers', () => {

expectResult( '<span style="font-weight:500">foo</span>' );
} );

it( 'config.model.name is given', () => {
const helper = downcastAttributeToElement( {
model: {
key: 'color',
name: '$text'
},
view: ( modelAttributeValue, viewWriter ) => {
return viewWriter.createAttributeElement( 'span', { style: 'color:' + modelAttributeValue } );
}
} );

conversion.for( 'downcast' )
.add( helper )
.add( downcastElementToElement( {
model: 'smiley',
view: ( modelElement, viewWriter ) => {
return viewWriter.createEmptyElement( 'img', {
src: 'smile.jpg',
class: 'smiley'
} );
}
} ) );

model.change( writer => {
writer.insertText( 'foo', { color: '#FF0000' }, modelRoot, 0 );
writer.insertElement( 'smiley', { color: '#FF0000' }, modelRoot, 3 );
} );

expectResult( '<span style="color:#FF0000">foo</span><img class="smiley" src="smile.jpg"></img>' );
} );
} );

describe( 'downcastAttributeToAttribute', () => {
Expand Down