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

Commit fc7da80

Browse files
authored
Merge pull request #1184 from ckeditor/t/1179
Fix: View stringify utility now sorts CSS classes and values in `style` attribute. Closes #1179.
2 parents 2924d52 + 7730795 commit fc7da80

File tree

5 files changed

+66
-33
lines changed

5 files changed

+66
-33
lines changed

src/dev-utils/view.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,22 @@ class ViewStringify {
827827
const keys = [ ...element.getAttributeKeys() ].sort();
828828

829829
for ( const attribute of keys ) {
830-
attributes.push( `${ attribute }="${ element.getAttribute( attribute ) }"` );
830+
let attributeValue;
831+
832+
if ( attribute === 'class' ) {
833+
attributeValue = [ ...element.getClassNames() ]
834+
.sort()
835+
.join( ' ' );
836+
} else if ( attribute === 'style' ) {
837+
attributeValue = [ ...element.getStyleNames() ]
838+
.sort()
839+
.map( style => `${ style }:${ element.getStyle( style ) }` )
840+
.join( ';' );
841+
} else {
842+
attributeValue = element.getAttribute( attribute );
843+
}
844+
845+
attributes.push( `${ attribute }="${ attributeValue }"` );
831846
}
832847

833848
return attributes.join( ' ' );

tests/conversion/model-selection-to-view-converters.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -528,9 +528,9 @@ describe( 'model-selection-to-view-converters', () => {
528528
beforeEach( () => {
529529
function themeElementCreator( themeValue ) {
530530
if ( themeValue == 'important' ) {
531-
return new ViewAttributeElement( 'strong', { style: 'text-transform:uppercase;' } );
531+
return new ViewAttributeElement( 'strong', { style: 'text-transform:uppercase' } );
532532
} else if ( themeValue == 'gold' ) {
533-
return new ViewAttributeElement( 'span', { style: 'color:yellow;' } );
533+
return new ViewAttributeElement( 'span', { style: 'color:yellow' } );
534534
}
535535
}
536536

@@ -545,31 +545,31 @@ describe( 'model-selection-to-view-converters', () => {
545545
test(
546546
[ 1, 5 ],
547547
'fo<$text theme="gold">ob</$text>ar',
548-
'f{o<span style="color:yellow;">ob</span>a}r'
548+
'f{o<span style="color:yellow">ob</span>a}r'
549549
);
550550
} );
551551

552552
it( 'in same attribute', () => {
553553
test(
554554
[ 2, 4 ],
555555
'f<$text theme="gold">ooba</$text>r',
556-
'f<span style="color:yellow;">o{ob}a</span>r'
556+
'f<span style="color:yellow">o{ob}a</span>r'
557557
);
558558
} );
559559

560560
it( 'in same attribute, selection same as attribute', () => {
561561
test(
562562
[ 2, 4 ],
563563
'fo<$text theme="important">ob</$text>ar',
564-
'fo{<strong style="text-transform:uppercase;">ob</strong>}ar'
564+
'fo{<strong style="text-transform:uppercase">ob</strong>}ar'
565565
);
566566
} );
567567

568568
it( 'starts in attribute, ends in text node', () => {
569569
test(
570570
[ 3, 5 ],
571571
'fo<$text theme="important">ob</$text>ar',
572-
'fo<strong style="text-transform:uppercase;">o{b</strong>a}r'
572+
'fo<strong style="text-transform:uppercase">o{b</strong>a}r'
573573
);
574574
} );
575575
} );
@@ -579,15 +579,15 @@ describe( 'model-selection-to-view-converters', () => {
579579
test(
580580
[ 3, 3 ],
581581
'f<$text theme="gold">ooba</$text>r',
582-
'f<span style="color:yellow;">oo{}ba</span>r'
582+
'f<span style="color:yellow">oo{}ba</span>r'
583583
);
584584
} );
585585

586586
it( 'in container with theme attribute', () => {
587587
test(
588588
[ 1, 1 ],
589589
'foobar',
590-
'f<strong style="text-transform:uppercase;">[]</strong>oobar',
590+
'f<strong style="text-transform:uppercase">[]</strong>oobar',
591591
{ theme: 'important' }
592592
);
593593
} );
@@ -596,9 +596,9 @@ describe( 'model-selection-to-view-converters', () => {
596596
test(
597597
[ 3, 3 ],
598598
'f<$text theme="gold">ooba</$text>r',
599-
'f<span style="color:yellow;">oo</span>' +
600-
'<em><span style="color:yellow;">[]</span></em>' +
601-
'<span style="color:yellow;">ba</span>r',
599+
'f<span style="color:yellow">oo</span>' +
600+
'<em><span style="color:yellow">[]</span></em>' +
601+
'<span style="color:yellow">ba</span>r',
602602
{ italic: true }
603603
);
604604
} );
@@ -611,9 +611,9 @@ describe( 'model-selection-to-view-converters', () => {
611611
test(
612612
[ 3, 3 ],
613613
'f<$text theme="gold">ooba</$text>r',
614-
'f<span style="color:yellow;">oo</span>' +
615-
'<strong style="text-transform:uppercase;">[]</strong>' +
616-
'<span style="color:yellow;">ba</span>r',
614+
'f<span style="color:yellow">oo</span>' +
615+
'<strong style="text-transform:uppercase">[]</strong>' +
616+
'<span style="color:yellow">ba</span>r',
617617
{ theme: 'important' }
618618
);
619619
} );

tests/dev-utils/view.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,24 @@ describe( 'view test utils', () => {
355355
expect( stringify( p, null, { showType: true } ) )
356356
.to.equal( '<container:p><ui:span></ui:span></container:p>' );
357357
} );
358+
359+
it( 'should sort classes in specified element', () => {
360+
const text = new Text( 'foobar' );
361+
const b = new Element( 'b', {
362+
class: 'zz xx aa'
363+
}, text );
364+
365+
expect( stringify( b ) ).to.equal( '<b class="aa xx zz">foobar</b>' );
366+
} );
367+
368+
it( 'should sort styles in specified element', () => {
369+
const text = new Text( 'foobar' );
370+
const i = new Element( 'i', {
371+
style: 'text-decoration: underline; font-weight: bold'
372+
}, text );
373+
374+
expect( stringify( i ) ).to.equal( '<i style="font-weight:bold;text-decoration:underline">foobar</i>' );
375+
} );
358376
} );
359377

360378
describe( 'parse', () => {

tests/view/writer/unwrap.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,17 @@ describe( 'writer', () => {
259259

260260
it( 'should unwrap single element by removing matching classes', () => {
261261
test(
262-
'<container:p>[<attribute:b view-priority="1" class="foo bar baz">test</attribute:b>]</container:p>',
262+
'<container:p>[<attribute:b view-priority="1" class="bar baz foo">test</attribute:b>]</container:p>',
263263
'<attribute:b view-priority="1" class="baz foo"></attribute:b>',
264264
'<container:p>[<attribute:b view-priority="1" class="bar">test</attribute:b>]</container:p>'
265265
);
266266
} );
267267

268268
it( 'should not unwrap single element when classes are different', () => {
269269
test(
270-
'<container:p>[<attribute:b view-priority="1" class="foo bar baz">test</attribute:b>]</container:p>',
270+
'<container:p>[<attribute:b view-priority="1" class="bar baz foo">test</attribute:b>]</container:p>',
271271
'<attribute:b view-priority="1" class="baz foo qux"></attribute:b>',
272-
'<container:p>[<attribute:b view-priority="1" class="foo bar baz">test</attribute:b>]</container:p>'
272+
'<container:p>[<attribute:b view-priority="1" class="bar baz foo">test</attribute:b>]</container:p>'
273273
);
274274
} );
275275

@@ -279,18 +279,18 @@ describe( 'writer', () => {
279279
'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px;">test</attribute:b>]' +
280280
'</container:p>',
281281
'<attribute:b view-priority="1" style="position: absolute;"></attribute:b>',
282-
'<container:p>[<attribute:b view-priority="1" style="color:red;top:10px;">test</attribute:b>]</container:p>'
282+
'<container:p>[<attribute:b view-priority="1" style="color:red;top:10px">test</attribute:b>]</container:p>'
283283
);
284284
} );
285285

286286
it( 'should not unwrap single element when styles are different', () => {
287287
test(
288288
'<container:p>' +
289-
'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px;">test</attribute:b>]' +
289+
'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px">test</attribute:b>]' +
290290
'</container:p>',
291291
'<attribute:b view-priority="1" style="position: relative;"></attribute:b>',
292292
'<container:p>' +
293-
'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px;">test</attribute:b>]' +
293+
'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px">test</attribute:b>]' +
294294
'</container:p>'
295295
);
296296
} );

tests/view/writer/wrap.js

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -227,26 +227,26 @@ describe( 'writer', () => {
227227
test(
228228
'<container:p>[<attribute:b view-priority="1" class="foo bar baz"></attribute:b>]</container:p>',
229229
'<attribute:b view-priority="1" class="foo bar qux jax"></attribute:b>',
230-
'<container:p>[<attribute:b view-priority="1" class="foo bar baz qux jax"></attribute:b>]</container:p>'
230+
'<container:p>[<attribute:b view-priority="1" class="bar baz foo jax qux"></attribute:b>]</container:p>'
231231
);
232232
} );
233233

234234
it( 'should wrap single element by merging styles', () => {
235235
test(
236-
'<container:p>[<attribute:b view-priority="1" style="color:red; position: absolute;"></attribute:b>]</container:p>',
237-
'<attribute:b view-priority="1" style="color:red; top: 20px;"></attribute:b>',
238-
'<container:p>[<attribute:b view-priority="1" style="color:red;position:absolute;top:20px;"></attribute:b>]</container:p>'
236+
'<container:p>[<attribute:b view-priority="1" style="color:red; position: absolute"></attribute:b>]</container:p>',
237+
'<attribute:b view-priority="1" style="color:red; top: 20px"></attribute:b>',
238+
'<container:p>[<attribute:b view-priority="1" style="color:red;position:absolute;top:20px"></attribute:b>]</container:p>'
239239
);
240240
} );
241241

242242
it( 'should not merge styles when they differ', () => {
243243
test(
244-
'<container:p>[<attribute:b view-priority="1" style="color:red;"></attribute:b>]</container:p>',
245-
'<attribute:b view-priority="1" style="color:black;"></attribute:b>',
244+
'<container:p>[<attribute:b view-priority="1" style="color:red"></attribute:b>]</container:p>',
245+
'<attribute:b view-priority="1" style="color:black"></attribute:b>',
246246
'<container:p>' +
247247
'[' +
248-
'<attribute:b view-priority="1" style="color:black;">' +
249-
'<attribute:b view-priority="1" style="color:red;"></attribute:b>' +
248+
'<attribute:b view-priority="1" style="color:black">' +
249+
'<attribute:b view-priority="1" style="color:red"></attribute:b>' +
250250
'</attribute:b>' +
251251
']' +
252252
'</container:p>'
@@ -255,12 +255,12 @@ describe( 'writer', () => {
255255

256256
it( 'should not merge single elements when they have different priority', () => {
257257
test(
258-
'<container:p>[<attribute:b view-priority="2" style="color:red;"></attribute:b>]</container:p>',
259-
'<attribute:b view-priority="1" style="color:red;"></attribute:b>',
258+
'<container:p>[<attribute:b view-priority="2" style="color:red"></attribute:b>]</container:p>',
259+
'<attribute:b view-priority="1" style="color:red"></attribute:b>',
260260
'<container:p>' +
261261
'[' +
262-
'<attribute:b view-priority="1" style="color:red;">' +
263-
'<attribute:b view-priority="2" style="color:red;"></attribute:b>' +
262+
'<attribute:b view-priority="1" style="color:red">' +
263+
'<attribute:b view-priority="2" style="color:red"></attribute:b>' +
264264
'</attribute:b>' +
265265
']</container:p>'
266266
);

0 commit comments

Comments
 (0)