Forráskód Böngészése

Merge branch 'master' into t/897

Maciej Gołaszewski 8 éve
szülő
commit
8d5ed136d9

+ 14 - 0
packages/ckeditor5-engine/CHANGELOG.md

@@ -1,6 +1,20 @@
 Changelog
 =========
 
+## [1.0.0-alpha.2](https://github.com/ckeditor/ckeditor5-engine/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (2017-11-14)
+
+### Bug fixes
+
+* `model.Range` will now be extended if it was collapsed and it was transformed by insertion. Closes [#1159](https://github.com/ckeditor/ckeditor5-engine/issues/1159). ([5f020b0](https://github.com/ckeditor/ckeditor5-engine/commit/5f020b0))
+* Prevent adding inline filler to non-editable content. Closes [#1170](https://github.com/ckeditor/ckeditor5-engine/issues/1170). ([07a01b1](https://github.com/ckeditor/ckeditor5-engine/commit/07a01b1))
+* The `deleteContent()` algorithm will use merging to "remove" empty element which will ensure a better conflict resolution on collaborative editing. Closes [#1161](https://github.com/ckeditor/ckeditor5-engine/issues/1161). ([0dd29d4](https://github.com/ckeditor/ckeditor5-engine/commit/0dd29d4))
+
+### Other changes
+
+* Removed the `renderer-skipped-selection-rendering` warning since it doesn't bring any value. Closes [#1158](https://github.com/ckeditor/ckeditor5-engine/issues/1158). ([4a5a5d1](https://github.com/ckeditor/ckeditor5-engine/commit/4a5a5d1))
+* The `removeHighlight()` function now accepts descriptor id instead of a `HighlightDescriptor` object. Closes [#1164](https://github.com/ckeditor/ckeditor5-engine/issues/1164). ([7bde6f7](https://github.com/ckeditor/ckeditor5-engine/commit/7bde6f7))
+
+
 ## [1.0.0-alpha.1](https://github.com/ckeditor/ckeditor5-engine/compare/v0.11.0...v1.0.0-alpha.1) (2017-10-03)
 
 ### Bug fixes

+ 13 - 13
packages/ckeditor5-engine/package.json

@@ -1,26 +1,26 @@
 {
   "name": "@ckeditor/ckeditor5-engine",
-  "version": "1.0.0-alpha.1",
+  "version": "1.0.0-alpha.2",
   "description": "CKEditor 5 editing engine.",
   "keywords": [
     "ckeditor5",
     "ckeditor5-lib"
   ],
   "dependencies": {
-    "@ckeditor/ckeditor5-utils": "^1.0.0-alpha.1"
+    "@ckeditor/ckeditor5-utils": "^1.0.0-alpha.2"
   },
   "devDependencies": {
-    "@ckeditor/ckeditor5-basic-styles": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-core": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-editor-classic": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-enter": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-essentials": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-heading": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-list": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-paragraph": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-typing": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-undo": "^1.0.0-alpha.1",
-    "@ckeditor/ckeditor5-widget": "^1.0.0-alpha.1",
+    "@ckeditor/ckeditor5-basic-styles": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-core": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-editor-classic": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-enter": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-essentials": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-heading": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-list": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-paragraph": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-typing": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-undo": "^1.0.0-alpha.2",
+    "@ckeditor/ckeditor5-widget": "^1.0.0-alpha.2",
     "eslint": "^4.8.0",
     "eslint-config-ckeditor5": "^1.0.6",
     "husky": "^0.14.3",

+ 16 - 1
packages/ckeditor5-engine/src/dev-utils/view.js

@@ -827,7 +827,22 @@ class ViewStringify {
 		const keys = [ ...element.getAttributeKeys() ].sort();
 
 		for ( const attribute of keys ) {
-			attributes.push( `${ attribute }="${ element.getAttribute( attribute ) }"` );
+			let attributeValue;
+
+			if ( attribute === 'class' ) {
+				attributeValue = [ ...element.getClassNames() ]
+					.sort()
+					.join( ' ' );
+			} else if ( attribute === 'style' ) {
+				attributeValue = [ ...element.getStyleNames() ]
+					.sort()
+					.map( style => `${ style }:${ element.getStyle( style ) }` )
+					.join( ';' );
+			} else {
+				attributeValue = element.getAttribute( attribute );
+			}
+
+			attributes.push( `${ attribute }="${ attributeValue }"` );
 		}
 
 		return attributes.join( ' ' );

+ 10 - 12
packages/ckeditor5-engine/src/model/delta/basic-deltas.js

@@ -12,15 +12,13 @@
 // which would already have all default deltas registered.
 
 // Import default suite of deltas so a feature have to include only Batch class file.
-/* eslint-disable no-unused-vars */
-import d01 from './attributedelta';
-import d02 from './insertdelta';
-import d03 from './mergedelta';
-import d04 from './movedelta';
-import d05 from './removedelta';
-import d06 from './renamedelta';
-import d07 from './splitdelta';
-import d08 from './unwrapdelta';
-import d09 from './weakinsertdelta';
-import d10 from './wrapdelta';
-/* eslint-enable no-unused-vars */
+import './attributedelta';
+import './insertdelta';
+import './mergedelta';
+import './movedelta';
+import './removedelta';
+import './renamedelta';
+import './splitdelta';
+import './unwrapdelta';
+import './weakinsertdelta';
+import './wrapdelta';

+ 3 - 5
packages/ckeditor5-engine/src/model/document.js

@@ -7,11 +7,9 @@
  * @module engine/model/document
  */
 
-// Load all basic deltas and transformations, they register themselves, but they need to be imported somewhere.
-/* eslint-disable no-unused-vars */
-import deltas from './delta/basic-deltas';
-import transformations from './delta/basic-transformations';
-/* eslint-enable no-unused-vars */
+// Load all basic deltas and transformations, they register themselves.
+import './delta/basic-deltas';
+import './delta/basic-transformations';
 
 import Range from './range';
 import Position from './position';

+ 1 - 1
packages/ckeditor5-engine/src/model/item.jsdoc

@@ -8,7 +8,7 @@
  */
 
 /**
- * Item is a {@link module:engine/model/node~Node Node} or {module:engine/model/textproxy~TextProxy TextProxy}.
+ * Item is a {@link module:engine/model/node~Node Node} or {@link module:engine/model/textproxy~TextProxy TextProxy}.
  *
  * @typedef {module:engine/model/node~Node|module:engine/model/textproxy~TextProxy} module:engine/model/item~Item
  */

+ 1 - 1
packages/ckeditor5-engine/src/model/operation/attributeoperation.js

@@ -116,7 +116,7 @@ export default class AttributeOperation extends Operation {
 				/**
 				 * Changed node has different attribute value than operation's old attribute value.
 				 *
-				 * @error operation-attribute-wrong-old-value
+				 * @error attribute-operation-wrong-old-value
 				 * @param {module:engine/model/item~Item} item
 				 * @param {String} key
 				 * @param {*} value

+ 21 - 11
packages/ckeditor5-engine/src/view/renderer.js

@@ -15,7 +15,6 @@ import mix from '@ckeditor/ckeditor5-utils/src/mix';
 import diff from '@ckeditor/ckeditor5-utils/src/diff';
 import insertAt from '@ckeditor/ckeditor5-utils/src/dom/insertat';
 import remove from '@ckeditor/ckeditor5-utils/src/dom/remove';
-import log from '@ckeditor/ckeditor5-utils/src/log';
 import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
@@ -381,6 +380,12 @@ export default class Renderer {
 			return false;
 		}
 
+		// Prevent adding inline filler inside elements with contenteditable=false.
+		// https://github.com/ckeditor/ckeditor5-engine/issues/1170
+		if ( !_isEditable( selectionParent ) ) {
+			return false;
+		}
+
 		// We have block filler, we do not need inline one.
 		if ( selectionOffset === selectionParent.getFillerOffset() ) {
 			return false;
@@ -640,16 +645,6 @@ export default class Renderer {
 
 		// If selection is not collapsed, it does not need to be updated if it is similar.
 		if ( !this.selection.isCollapsed && this.selection.isSimilar( oldViewSelection ) ) {
-			const data = {
-				oldSelection: oldViewSelection,
-				currentSelection: this.selection
-			};
-
-			log.warn(
-				'renderer-skipped-selection-rendering: The selection was not rendered due to its similarity to the current one.',
-				data
-			);
-
 			// Selection did not changed and is correct, do not update.
 			return false;
 		}
@@ -708,3 +703,18 @@ export default class Renderer {
 }
 
 mix( Renderer, ObservableMixin );
+
+// Checks if provided element is editable.
+//
+// @private
+// @param {module:engine/view/element~Element} element
+// @returns {Boolean}
+function _isEditable( element ) {
+	if ( element.getAttribute( 'contenteditable' ) == 'false' ) {
+		return false;
+	}
+
+	const parent = element.findAncestor( element => element.hasAttribute( 'contenteditable' ) );
+
+	return !parent || parent.getAttribute( 'contenteditable' ) == 'true';
+}

+ 14 - 14
packages/ckeditor5-engine/tests/conversion/model-selection-to-view-converters.js

@@ -528,9 +528,9 @@ describe( 'model-selection-to-view-converters', () => {
 		beforeEach( () => {
 			function themeElementCreator( themeValue ) {
 				if ( themeValue == 'important' ) {
-					return new ViewAttributeElement( 'strong', { style: 'text-transform:uppercase;' } );
+					return new ViewAttributeElement( 'strong', { style: 'text-transform:uppercase' } );
 				} else if ( themeValue == 'gold' ) {
-					return new ViewAttributeElement( 'span', { style: 'color:yellow;' } );
+					return new ViewAttributeElement( 'span', { style: 'color:yellow' } );
 				}
 			}
 
@@ -545,7 +545,7 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 1, 5 ],
 					'fo<$text theme="gold">ob</$text>ar',
-					'f{o<span style="color:yellow;">ob</span>a}r'
+					'f{o<span style="color:yellow">ob</span>a}r'
 				);
 			} );
 
@@ -553,7 +553,7 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 2, 4 ],
 					'f<$text theme="gold">ooba</$text>r',
-					'f<span style="color:yellow;">o{ob}a</span>r'
+					'f<span style="color:yellow">o{ob}a</span>r'
 				);
 			} );
 
@@ -561,7 +561,7 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 2, 4 ],
 					'fo<$text theme="important">ob</$text>ar',
-					'fo{<strong style="text-transform:uppercase;">ob</strong>}ar'
+					'fo{<strong style="text-transform:uppercase">ob</strong>}ar'
 				);
 			} );
 
@@ -569,7 +569,7 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 3, 5 ],
 					'fo<$text theme="important">ob</$text>ar',
-					'fo<strong style="text-transform:uppercase;">o{b</strong>a}r'
+					'fo<strong style="text-transform:uppercase">o{b</strong>a}r'
 				);
 			} );
 		} );
@@ -579,7 +579,7 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 3, 3 ],
 					'f<$text theme="gold">ooba</$text>r',
-					'f<span style="color:yellow;">oo{}ba</span>r'
+					'f<span style="color:yellow">oo{}ba</span>r'
 				);
 			} );
 
@@ -587,7 +587,7 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 1, 1 ],
 					'foobar',
-					'f<strong style="text-transform:uppercase;">[]</strong>oobar',
+					'f<strong style="text-transform:uppercase">[]</strong>oobar',
 					{ theme: 'important' }
 				);
 			} );
@@ -596,9 +596,9 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 3, 3 ],
 					'f<$text theme="gold">ooba</$text>r',
-					'f<span style="color:yellow;">oo</span>' +
-					'<em><span style="color:yellow;">[]</span></em>' +
-					'<span style="color:yellow;">ba</span>r',
+					'f<span style="color:yellow">oo</span>' +
+					'<em><span style="color:yellow">[]</span></em>' +
+					'<span style="color:yellow">ba</span>r',
 					{ italic: true }
 				);
 			} );
@@ -611,9 +611,9 @@ describe( 'model-selection-to-view-converters', () => {
 				test(
 					[ 3, 3 ],
 					'f<$text theme="gold">ooba</$text>r',
-					'f<span style="color:yellow;">oo</span>' +
-					'<strong style="text-transform:uppercase;">[]</strong>' +
-					'<span style="color:yellow;">ba</span>r',
+					'f<span style="color:yellow">oo</span>' +
+					'<strong style="text-transform:uppercase">[]</strong>' +
+					'<span style="color:yellow">ba</span>r',
 					{ theme: 'important' }
 				);
 			} );

+ 18 - 0
packages/ckeditor5-engine/tests/dev-utils/view.js

@@ -355,6 +355,24 @@ describe( 'view test utils', () => {
 			expect( stringify( p, null, { showType: true } ) )
 				.to.equal( '<container:p><ui:span></ui:span></container:p>' );
 		} );
+
+		it( 'should sort classes in specified element', () => {
+			const text = new Text( 'foobar' );
+			const b = new Element( 'b', {
+				class: 'zz xx aa'
+			}, text );
+
+			expect( stringify( b ) ).to.equal( '<b class="aa xx zz">foobar</b>' );
+		} );
+
+		it( 'should sort styles in specified element', () => {
+			const text = new Text( 'foobar' );
+			const i = new Element( 'i', {
+				style: 'text-decoration: underline; font-weight: bold'
+			}, text );
+
+			expect( stringify( i ) ).to.equal( '<i style="font-weight:bold;text-decoration:underline">foobar</i>' );
+		} );
 	} );
 
 	describe( 'parse', () => {

+ 45 - 18
packages/ckeditor5-engine/tests/view/renderer.js

@@ -20,7 +20,6 @@ import { parse, setData as setViewData, getData as getViewData } from '../../src
 import { INLINE_FILLER, INLINE_FILLER_LENGTH, isBlockFiller, BR_FILLER } from '../../src/view/filler';
 import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 import createElement from '@ckeditor/ckeditor5-utils/src/dom/createelement';
-import log from '@ckeditor/ckeditor5-utils/src/log';
 import { unwrap, insert, remove } from '../../src/view/writer';
 import normalizeHtml from '@ckeditor/ckeditor5-utils/tests/_utils/normalizehtml';
 
@@ -410,6 +409,50 @@ describe( 'Renderer', () => {
 			expect( viewRoot ).to.be.ok;
 		} );
 
+		it( 'should not add filler when inside contenteditable=false parent', () => {
+			const { view: viewP, selection: newSelection } = parse(
+				'<container:p>foo<attribute:b contenteditable="false">[]</attribute:b>bar</container:p>' );
+
+			viewRoot.appendChildren( viewP );
+			selection.setTo( newSelection );
+
+			renderer.markToSync( 'children', viewRoot );
+			renderer.render();
+
+			expect( domRoot.childNodes.length ).to.equal( 1 );
+			expect( domRoot.childNodes[ 0 ].tagName.toLowerCase() ).to.equal( 'p' );
+
+			const domP = domRoot.childNodes[ 0 ];
+
+			expect( domP.childNodes.length ).to.equal( 3 );
+			expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
+			expect( domP.childNodes[ 2 ].data ).to.equal( 'bar' );
+			expect( domP.childNodes[ 1 ].tagName.toLowerCase() ).to.equal( 'b' );
+			expect( domP.childNodes[ 1 ].childNodes.length ).to.equal( 0 );
+		} );
+
+		it( 'should not add filler when inside contenteditable=false ancestor', () => {
+			const { view: viewP, selection: newSelection } = parse(
+				'<container:p contenteditable="false">foo<attribute:b>[]</attribute:b>bar</container:p>' );
+
+			viewRoot.appendChildren( viewP );
+			selection.setTo( newSelection );
+
+			renderer.markToSync( 'children', viewRoot );
+			renderer.render();
+
+			expect( domRoot.childNodes.length ).to.equal( 1 );
+			expect( domRoot.childNodes[ 0 ].tagName.toLowerCase() ).to.equal( 'p' );
+
+			const domP = domRoot.childNodes[ 0 ];
+
+			expect( domP.childNodes.length ).to.equal( 3 );
+			expect( domP.childNodes[ 0 ].data ).to.equal( 'foo' );
+			expect( domP.childNodes[ 2 ].data ).to.equal( 'bar' );
+			expect( domP.childNodes[ 1 ].tagName.toLowerCase() ).to.equal( 'b' );
+			expect( domP.childNodes[ 1 ].childNodes.length ).to.equal( 0 );
+		} );
+
 		it( 'should add and remove inline filler in case <p>foo<b>[]</b>bar</p>', () => {
 			const domSelection = document.getSelection();
 
@@ -1459,11 +1502,7 @@ describe( 'Renderer', () => {
 		describe( 'similar selection', () => {
 			// Use spies to check selection updates. Some selection positions are not achievable in some
 			// browsers (e.g. <p>Foo<b>{}Bar</b></p> in Chrome) so asserting dom selection after rendering would fail.
-			let selectionCollapseSpy, selectionExtendSpy, logWarnStub;
-
-			before( () => {
-				logWarnStub = sinon.stub( log, 'warn' );
-			} );
+			let selectionCollapseSpy, selectionExtendSpy;
 
 			afterEach( () => {
 				if ( selectionCollapseSpy ) {
@@ -1475,11 +1514,6 @@ describe( 'Renderer', () => {
 					selectionExtendSpy.restore();
 					selectionExtendSpy = null;
 				}
-				logWarnStub.reset();
-			} );
-
-			after( () => {
-				logWarnStub.restore();
 			} );
 
 			it( 'should always render collapsed selection even if it is similar', () => {
@@ -1520,7 +1554,6 @@ describe( 'Renderer', () => {
 				expect( selectionCollapseSpy.calledWith( domB.childNodes[ 0 ], 0 ) ).to.true;
 				expect( selectionExtendSpy.calledOnce ).to.true;
 				expect( selectionExtendSpy.calledWith( domB.childNodes[ 0 ], 0 ) ).to.true;
-				expect( logWarnStub.notCalled ).to.true;
 			} );
 
 			it( 'should always render collapsed selection even if it is similar (with empty element)', () => {
@@ -1560,7 +1593,6 @@ describe( 'Renderer', () => {
 				expect( selectionCollapseSpy.calledWith( domP.childNodes[ 0 ], 3 ) ).to.true;
 				expect( selectionExtendSpy.calledOnce ).to.true;
 				expect( selectionExtendSpy.calledWith( domP.childNodes[ 0 ], 3 ) ).to.true;
-				expect( logWarnStub.notCalled ).to.true;
 			} );
 
 			it( 'should always render non-collapsed selection if it not is similar', () => {
@@ -1601,7 +1633,6 @@ describe( 'Renderer', () => {
 				expect( selectionCollapseSpy.calledWith( domP.childNodes[ 0 ], 2 ) ).to.true;
 				expect( selectionExtendSpy.calledOnce ).to.true;
 				expect( selectionExtendSpy.calledWith( domB.childNodes[ 0 ], 1 ) ).to.true;
-				expect( logWarnStub.notCalled ).to.true;
 			} );
 
 			it( 'should always render selection (even if it is same in view) if current dom selection is in incorrect place', () => {
@@ -1669,7 +1700,6 @@ describe( 'Renderer', () => {
 
 				expect( selectionCollapseSpy.notCalled ).to.true;
 				expect( selectionExtendSpy.notCalled ).to.true;
-				expect( logWarnStub.called ).to.true;
 			} );
 
 			it( 'should not render non-collapsed selection it is similar (element end)', () => {
@@ -1708,7 +1738,6 @@ describe( 'Renderer', () => {
 
 				expect( selectionCollapseSpy.notCalled ).to.true;
 				expect( selectionExtendSpy.notCalled ).to.true;
-				expect( logWarnStub.called ).to.true;
 			} );
 
 			it( 'should not render non-collapsed selection it is similar (element start - nested)', () => {
@@ -1747,7 +1776,6 @@ describe( 'Renderer', () => {
 
 				expect( selectionCollapseSpy.notCalled ).to.true;
 				expect( selectionExtendSpy.notCalled ).to.true;
-				expect( logWarnStub.called ).to.true;
 			} );
 
 			it( 'should not render non-collapsed selection it is similar (element end - nested)', () => {
@@ -1785,7 +1813,6 @@ describe( 'Renderer', () => {
 
 				expect( selectionCollapseSpy.notCalled ).to.true;
 				expect( selectionExtendSpy.notCalled ).to.true;
-				expect( logWarnStub.called ).to.true;
 			} );
 		} );
 	} );

+ 6 - 6
packages/ckeditor5-engine/tests/view/writer/unwrap.js

@@ -259,7 +259,7 @@ describe( 'writer', () => {
 
 		it( 'should unwrap single element by removing matching classes', () => {
 			test(
-				'<container:p>[<attribute:b view-priority="1" class="foo bar baz">test</attribute:b>]</container:p>',
+				'<container:p>[<attribute:b view-priority="1" class="bar baz foo">test</attribute:b>]</container:p>',
 				'<attribute:b view-priority="1" class="baz foo"></attribute:b>',
 				'<container:p>[<attribute:b view-priority="1" class="bar">test</attribute:b>]</container:p>'
 			);
@@ -267,9 +267,9 @@ describe( 'writer', () => {
 
 		it( 'should not unwrap single element when classes are different', () => {
 			test(
-				'<container:p>[<attribute:b view-priority="1" class="foo bar baz">test</attribute:b>]</container:p>',
+				'<container:p>[<attribute:b view-priority="1" class="bar baz foo">test</attribute:b>]</container:p>',
 				'<attribute:b view-priority="1" class="baz foo qux"></attribute:b>',
-				'<container:p>[<attribute:b view-priority="1" class="foo bar baz">test</attribute:b>]</container:p>'
+				'<container:p>[<attribute:b view-priority="1" class="bar baz foo">test</attribute:b>]</container:p>'
 			);
 		} );
 
@@ -279,18 +279,18 @@ describe( 'writer', () => {
 					'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px;">test</attribute:b>]' +
 				'</container:p>',
 				'<attribute:b view-priority="1" style="position: absolute;"></attribute:b>',
-				'<container:p>[<attribute:b view-priority="1" style="color:red;top:10px;">test</attribute:b>]</container:p>'
+				'<container:p>[<attribute:b view-priority="1" style="color:red;top:10px">test</attribute:b>]</container:p>'
 			);
 		} );
 
 		it( 'should not unwrap single element when styles are different', () => {
 			test(
 				'<container:p>' +
-					'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px;">test</attribute:b>]' +
+					'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px">test</attribute:b>]' +
 				'</container:p>',
 				'<attribute:b view-priority="1" style="position: relative;"></attribute:b>',
 				'<container:p>' +
-					'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px;">test</attribute:b>]' +
+					'[<attribute:b view-priority="1" style="color:red;position:absolute;top:10px">test</attribute:b>]' +
 				'</container:p>'
 			);
 		} );

+ 12 - 12
packages/ckeditor5-engine/tests/view/writer/wrap.js

@@ -227,26 +227,26 @@ describe( 'writer', () => {
 			test(
 				'<container:p>[<attribute:b view-priority="1" class="foo bar baz"></attribute:b>]</container:p>',
 				'<attribute:b view-priority="1" class="foo bar qux jax"></attribute:b>',
-				'<container:p>[<attribute:b view-priority="1" class="foo bar baz qux jax"></attribute:b>]</container:p>'
+				'<container:p>[<attribute:b view-priority="1" class="bar baz foo jax qux"></attribute:b>]</container:p>'
 			);
 		} );
 
 		it( 'should wrap single element by merging styles', () => {
 			test(
-				'<container:p>[<attribute:b view-priority="1" style="color:red; position: absolute;"></attribute:b>]</container:p>',
-				'<attribute:b view-priority="1" style="color:red; top: 20px;"></attribute:b>',
-				'<container:p>[<attribute:b view-priority="1" style="color:red;position:absolute;top:20px;"></attribute:b>]</container:p>'
+				'<container:p>[<attribute:b view-priority="1" style="color:red; position: absolute"></attribute:b>]</container:p>',
+				'<attribute:b view-priority="1" style="color:red; top: 20px"></attribute:b>',
+				'<container:p>[<attribute:b view-priority="1" style="color:red;position:absolute;top:20px"></attribute:b>]</container:p>'
 			);
 		} );
 
 		it( 'should not merge styles when they differ', () => {
 			test(
-				'<container:p>[<attribute:b view-priority="1" style="color:red;"></attribute:b>]</container:p>',
-				'<attribute:b view-priority="1" style="color:black;"></attribute:b>',
+				'<container:p>[<attribute:b view-priority="1" style="color:red"></attribute:b>]</container:p>',
+				'<attribute:b view-priority="1" style="color:black"></attribute:b>',
 				'<container:p>' +
 				'[' +
-					'<attribute:b view-priority="1" style="color:black;">' +
-						'<attribute:b view-priority="1" style="color:red;"></attribute:b>' +
+					'<attribute:b view-priority="1" style="color:black">' +
+						'<attribute:b view-priority="1" style="color:red"></attribute:b>' +
 					'</attribute:b>' +
 				']' +
 				'</container:p>'
@@ -255,12 +255,12 @@ describe( 'writer', () => {
 
 		it( 'should not merge single elements when they have different priority', () => {
 			test(
-				'<container:p>[<attribute:b view-priority="2" style="color:red;"></attribute:b>]</container:p>',
-				'<attribute:b view-priority="1" style="color:red;"></attribute:b>',
+				'<container:p>[<attribute:b view-priority="2" style="color:red"></attribute:b>]</container:p>',
+				'<attribute:b view-priority="1" style="color:red"></attribute:b>',
 				'<container:p>' +
 				'[' +
-					'<attribute:b view-priority="1" style="color:red;">' +
-						'<attribute:b view-priority="2" style="color:red;"></attribute:b>' +
+					'<attribute:b view-priority="1" style="color:red">' +
+						'<attribute:b view-priority="2" style="color:red"></attribute:b>' +
 					'</attribute:b>' +
 				']</container:p>'
 			);