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

Commit f8dec1e

Browse files
authored
Merge pull request #1373 from ckeditor/t/1370
Fixed: conversion.downcast-converters.downcastAttributeToElement should let specify from what element the model attribute will be converted. Closes #1370.
2 parents 294373c + cfe14cf commit f8dec1e

File tree

4 files changed

+114
-1
lines changed

4 files changed

+114
-1
lines changed

src/conversion/conversion.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,30 @@ export default class Conversion {
224224
* }
225225
* } );
226226
*
227+
* // Use `config.model.name` to define conversion only from given node type, `$text` in this case.
228+
* // The same attribute on different elements may be then handled by a different converter.
229+
* conversion.attributeToElement( {
230+
* model: {
231+
* key: 'textDecoration',
232+
* values: [ 'underline', 'lineThrough' ],
233+
* name: '$text'
234+
* },
235+
* view: {
236+
* underline: {
237+
* name: 'span',
238+
* style: {
239+
* 'text-decoration': 'underline'
240+
* }
241+
* },
242+
* lineThrough: {
243+
* name: 'span',
244+
* style: {
245+
* 'text-decoration': 'line-through'
246+
* }
247+
* }
248+
* }
249+
* } );
250+
*
227251
* // Use `upcastAlso` to define other view elements that should be also converted to `bold` attribute.
228252
* conversion.attributeToElement( {
229253
* model: 'bold',

src/conversion/downcast-converters.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@ export function downcastElementToElement( config ) {
105105
* }
106106
* } );
107107
*
108+
* downcastAttributeToElement( {
109+
* model: {
110+
* key: 'color',
111+
* name: '$text'
112+
* },
113+
* view: ( modelAttributeValue, viewWriter ) => {
114+
* return viewWriter.createAttributeElement( 'span', { style: 'color:' + modelAttributeValue } );
115+
* }
116+
* } );
117+
*
108118
* See {@link module:engine/conversion/conversion~Conversion#for} to learn how to add converter to conversion process.
109119
*
110120
* @param {Object} config Conversion configuration.
@@ -120,6 +130,11 @@ export function downcastAttributeToElement( config ) {
120130
config = cloneDeep( config );
121131

122132
const modelKey = config.model.key ? config.model.key : config.model;
133+
let eventName = 'attribute:' + modelKey;
134+
135+
if ( config.model.name ) {
136+
eventName += ':' + config.model.name;
137+
}
123138

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

134149
return dispatcher => {
135-
dispatcher.on( 'attribute:' + modelKey, wrap( elementCreator ), { priority: config.priority || 'normal' } );
150+
dispatcher.on( eventName, wrap( elementCreator ), { priority: config.priority || 'normal' } );
136151
};
137152
}
138153

tests/conversion/conversion.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,49 @@ describe( 'Conversion', () => {
407407
'<p>Foo bar</p>'
408408
);
409409
} );
410+
411+
it( 'config.model.name is given', () => {
412+
schema.extend( '$text', {
413+
allowAttributes: [ 'textDecoration' ]
414+
} );
415+
416+
conversion.attributeToElement( {
417+
model: {
418+
key: 'textDecoration',
419+
values: [ 'underline', 'lineThrough' ],
420+
name: '$text'
421+
},
422+
view: {
423+
underline: {
424+
name: 'span',
425+
style: {
426+
'text-decoration': 'underline'
427+
}
428+
},
429+
lineThrough: {
430+
name: 'span',
431+
style: {
432+
'text-decoration': 'line-through'
433+
}
434+
}
435+
}
436+
} );
437+
438+
test(
439+
'<p><span style="text-decoration:underline">Foo</span></p>',
440+
'<paragraph><$text textDecoration="underline">Foo</$text></paragraph>'
441+
);
442+
443+
test(
444+
'<p><span style="text-decoration:line-through">Foo</span></p>',
445+
'<paragraph><$text textDecoration="lineThrough">Foo</$text></paragraph>'
446+
);
447+
448+
test(
449+
'<p><span style="text-decoration:underline">Foo</span></p>',
450+
'<paragraph><$text textDecoration="underline">Foo</$text></paragraph>'
451+
);
452+
} );
410453
} );
411454

412455
describe( 'attributeToAttribute', () => {

tests/conversion/downcast-converters.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,37 @@ describe( 'downcast-helpers', () => {
209209

210210
expectResult( '<span style="font-weight:500">foo</span>' );
211211
} );
212+
213+
it( 'config.model.name is given', () => {
214+
const helper = downcastAttributeToElement( {
215+
model: {
216+
key: 'color',
217+
name: '$text'
218+
},
219+
view: ( modelAttributeValue, viewWriter ) => {
220+
return viewWriter.createAttributeElement( 'span', { style: 'color:' + modelAttributeValue } );
221+
}
222+
} );
223+
224+
conversion.for( 'downcast' )
225+
.add( helper )
226+
.add( downcastElementToElement( {
227+
model: 'smiley',
228+
view: ( modelElement, viewWriter ) => {
229+
return viewWriter.createEmptyElement( 'img', {
230+
src: 'smile.jpg',
231+
class: 'smiley'
232+
} );
233+
}
234+
} ) );
235+
236+
model.change( writer => {
237+
writer.insertText( 'foo', { color: '#FF0000' }, modelRoot, 0 );
238+
writer.insertElement( 'smiley', { color: '#FF0000' }, modelRoot, 3 );
239+
} );
240+
241+
expectResult( '<span style="color:#FF0000">foo</span><img class="smiley" src="smile.jpg"></img>' );
242+
} );
212243
} );
213244

214245
describe( 'downcastAttributeToAttribute', () => {

0 commit comments

Comments
 (0)