Browse Source

Merge branch 'master' into t/1060

Szymon Kupś 8 years ago
parent
commit
b52c8b59e5
35 changed files with 227 additions and 202 deletions
  1. 1 1
      packages/ckeditor5-engine/package.json
  2. 0 1
      packages/ckeditor5-engine/src/conversion/viewconsumable.js
  3. 1 1
      packages/ckeditor5-engine/src/dev-utils/model.js
  4. 0 1
      packages/ckeditor5-engine/src/dev-utils/view.js
  5. 1 1
      packages/ckeditor5-engine/src/model/batch.js
  6. 2 2
      packages/ckeditor5-engine/src/model/delta/attributedelta.js
  7. 1 1
      packages/ckeditor5-engine/src/model/document.js
  8. 2 2
      packages/ckeditor5-engine/src/model/documentselection.js
  9. 1 1
      packages/ckeditor5-engine/src/model/history.js
  10. 2 2
      packages/ckeditor5-engine/src/model/markercollection.js
  11. 3 3
      packages/ckeditor5-engine/src/model/range.js
  12. 2 2
      packages/ckeditor5-engine/src/model/selection.js
  13. 2 2
      packages/ckeditor5-engine/src/view/domconverter.js
  14. 3 3
      packages/ckeditor5-engine/src/view/element.js
  15. 0 1
      packages/ckeditor5-engine/src/view/matcher.js
  16. 8 8
      packages/ckeditor5-engine/src/view/range.js
  17. 1 1
      packages/ckeditor5-engine/src/view/selection.js
  18. 0 1
      packages/ckeditor5-engine/src/view/writer.js
  19. 1 3
      packages/ckeditor5-engine/tests/dev-utils/view.js
  20. 50 49
      packages/ckeditor5-engine/tests/manual/markers.js
  21. 13 12
      packages/ckeditor5-engine/tests/manual/nestededitable.js
  22. 16 15
      packages/ckeditor5-engine/tests/manual/placeholder.js
  23. 11 10
      packages/ckeditor5-engine/tests/manual/tickets/401/1.js
  24. 20 19
      packages/ckeditor5-engine/tests/manual/tickets/462/1.js
  25. 15 14
      packages/ckeditor5-engine/tests/manual/tickets/603/1.js
  26. 11 10
      packages/ckeditor5-engine/tests/manual/tickets/629/1.js
  27. 15 13
      packages/ckeditor5-engine/tests/manual/tickets/880/1.js
  28. 11 10
      packages/ckeditor5-engine/tests/manual/tickets/887/1.js
  29. 1 1
      packages/ckeditor5-engine/tests/model/selection.js
  30. 1 2
      packages/ckeditor5-engine/tests/view/domconverter/binding.js
  31. 4 4
      packages/ckeditor5-engine/tests/view/domconverter/uielement.js
  32. 4 2
      packages/ckeditor5-engine/tests/view/observer/selectionobserver.js
  33. 22 2
      packages/ckeditor5-engine/tests/view/range.js
  34. 1 1
      packages/ckeditor5-engine/tests/view/renderer.js
  35. 1 1
      packages/ckeditor5-engine/tests/view/selection.js

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

@@ -19,7 +19,7 @@
     "@ckeditor/ckeditor5-paragraph": "^0.8.0",
     "@ckeditor/ckeditor5-typing": "^0.9.1",
     "@ckeditor/ckeditor5-undo": "^0.8.1",
-    "eslint-config-ckeditor5": "^1.0.0",
+    "eslint-config-ckeditor5": "^1.0.5",
     "gulp": "^3.9.1",
     "guppy-pre-commit": "^0.4.0"
   },

+ 0 - 1
packages/ckeditor5-engine/src/conversion/viewconsumable.js

@@ -316,7 +316,6 @@ export default class ViewConsumable {
  * @private
  */
 class ViewElementConsumables {
-
 	/**
 	 * Creates ViewElementConsumables instance.
 	 */

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

@@ -428,7 +428,7 @@ function stringifyAttributeValue( data ) {
 }
 
 // Loop trough attributes map and converts each value by passed converter.
-function* convertAttributes( attributes, converter ) {
+function *convertAttributes( attributes, converter ) {
 	for ( const [ key, value ] of attributes ) {
 		yield [ key, converter( value ) ];
 	}

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

@@ -355,7 +355,6 @@ export function parse( data, options = {} ) {
  * @private
  */
 class RangeParser {
-
 	/**
 	 * Create RangeParser instance.
 	 *

+ 1 - 1
packages/ckeditor5-engine/src/model/batch.js

@@ -96,7 +96,7 @@ export default class Batch {
 	 *
 	 * @returns {Iterable.<module:engine/model/operation/operation~Operation>}
 	 */
-	* getOperations() {
+	*getOperations() {
 		for ( const delta of this.deltas ) {
 			yield* delta.operations;
 		}

+ 2 - 2
packages/ckeditor5-engine/src/model/delta/attributedelta.js

@@ -212,9 +212,9 @@ function changeRange( batch, doc, attributeKey, attributeValue, range ) {
 	// Currently position in the scanning range. Because we need value after the position, it is not a current
 	// position of the iterator but the previous one (we need to iterate one more time to get the value after).
 	let position,
-	// Value before the currently position.
+		// Value before the currently position.
 		attributeValueBefore,
-	// Value after the currently position.
+		// Value after the currently position.
 		attributeValueAfter;
 
 	for ( const value of range ) {

+ 1 - 1
packages/ckeditor5-engine/src/model/document.js

@@ -490,7 +490,7 @@ function validateTextNodePosition( rangeBoundary ) {
 // @param {module:engine/module/treewalker~TreeWalker} [forward] Walker iterating in forward direction.
 // @returns {Iterable.<Object>} Object returned at each iteration contains `value` and `walker` (informing which walker returned
 // given value) fields.
-function* combineWalkers( backward, forward ) {
+function *combineWalkers( backward, forward ) {
 	let done = false;
 
 	while ( !done ) {

+ 2 - 2
packages/ckeditor5-engine/src/model/documentselection.js

@@ -133,7 +133,7 @@ export default class DocumentSelection extends Selection {
 	/**
 	 * @inheritDoc
 	 */
-	* getRanges() {
+	*getRanges() {
 		if ( this._ranges.length ) {
 			yield* super.getRanges();
 		} else {
@@ -500,7 +500,7 @@ export default class DocumentSelection extends Selection {
 	 * @private
 	 * @returns {Iterable.<*>}
 	 */
-	* _getStoredAttributes() {
+	*_getStoredAttributes() {
 		const selectionParent = this.getFirstPosition().parent;
 
 		if ( this.isCollapsed && selectionParent.isEmpty ) {

+ 1 - 1
packages/ckeditor5-engine/src/model/history.js

@@ -78,7 +78,7 @@ export default class History {
 	 * Defaults to `Number.POSITIVE_INFINITY` which means that deltas up to the last one will be returned.
 	 * @returns {Iterator.<module:engine/model/delta/delta~Delta>} Deltas added to the history from given base versions range.
 	 */
-	* getDeltas( from = 0, to = Number.POSITIVE_INFINITY ) {
+	*getDeltas( from = 0, to = Number.POSITIVE_INFINITY ) {
 		// No deltas added, nothing to yield.
 		if ( this._deltas.length === 0 ) {
 			return;

+ 2 - 2
packages/ckeditor5-engine/src/model/markercollection.js

@@ -133,7 +133,7 @@ export default class MarkerCollection {
 	 * @param {module:engine/model/position~Position} position
 	 * @returns {Iterator.<module:engine/model/markercollection~Marker>}
 	 */
-	* getMarkersAtPosition( position ) {
+	*getMarkersAtPosition( position ) {
 		for ( const marker of this ) {
 			if ( marker.getRange().containsPosition( position ) ) {
 				yield marker;
@@ -167,7 +167,7 @@ export default class MarkerCollection {
 	 * @param prefix
 	 * @returns {Iterator.<module:engine/model/markercollection~Marker>}
 	 */
-	* getMarkersGroup( prefix ) {
+	*getMarkersGroup( prefix ) {
 		for ( const marker of this._markers.values() ) {
 			if ( marker.name.startsWith( prefix + ':' ) ) {
 				yield marker;

+ 3 - 3
packages/ckeditor5-engine/src/model/range.js

@@ -53,7 +53,7 @@ export default class Range {
 	 *
 	 * @returns {Iterable.<module:engine/model/treewalker~TreeWalkerValue>}
 	 */
-	* [ Symbol.iterator ]() {
+	*[ Symbol.iterator ]() {
 		yield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );
 	}
 
@@ -331,7 +331,7 @@ export default class Range {
 	 * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.
 	 * @returns {Iterable.<module:engine/model/item~Item>}
 	 */
-	* getItems( options = {} ) {
+	*getItems( options = {} ) {
 		options.boundaries = this;
 		options.ignoreElementEnd = true;
 
@@ -355,7 +355,7 @@ export default class Range {
 	 * @param {Object} options Object with configuration options. See {@link module:engine/model/treewalker~TreeWalker}.
 	 * @returns {Iterable.<module:engine/model/position~Position>}
 	 */
-	* getPositions( options = {} ) {
+	*getPositions( options = {} ) {
 		options.boundaries = this;
 
 		const treeWalker = new TreeWalker( options );

+ 2 - 2
packages/ckeditor5-engine/src/model/selection.js

@@ -177,7 +177,7 @@ export default class Selection {
 	 *
 	 * @returns {Iterator.<module:engine/model/range~Range>}
 	 */
-	* getRanges() {
+	*getRanges() {
 		for ( const range of this._ranges ) {
 			yield Range.createFromRange( range );
 		}
@@ -599,7 +599,7 @@ export default class Selection {
 	 *
 	 * @returns {Iterator.<module:engine/model/element~Element>}
 	 */
-	* getSelectedBlocks() {
+	*getSelectedBlocks() {
 		const visited = new WeakSet();
 
 		for ( const range of this.getRanges() ) {

+ 2 - 2
packages/ckeditor5-engine/src/view/domconverter.js

@@ -242,7 +242,7 @@ export default class DomConverter {
 	 * @param {Object} options See {@link module:engine/view/domconverter~DomConverter#viewToDom} options parameter.
 	 * @returns {Iterable.<Node>} DOM nodes.
 	 */
-	* viewChildrenToDom( viewElement, domDocument, options = {} ) {
+	*viewChildrenToDom( viewElement, domDocument, options = {} ) {
 		const fillerPositionOffset = viewElement.getFillerOffset && viewElement.getFillerOffset();
 		let offset = 0;
 
@@ -435,7 +435,7 @@ export default class DomConverter {
 	 * @param {Object} options See {@link module:engine/view/domconverter~DomConverter#domToView} options parameter.
 	 * @returns {Iterable.<module:engine/view/node~Node>} View nodes.
 	 */
-	* domChildrenToView( domElement, options = {} ) {
+	*domChildrenToView( domElement, options = {} ) {
 		for ( let i = 0; i < domElement.childNodes.length; i++ ) {
 			const domChild = domElement.childNodes[ i ];
 			const viewChild = this.domToView( domChild, options );

+ 3 - 3
packages/ckeditor5-engine/src/view/element.js

@@ -234,7 +234,7 @@ export default class Element extends Node {
 	 *
 	 * @returns {Iterator.<String>} Keys for attributes.
 	 */
-	* getAttributeKeys() {
+	*getAttributeKeys() {
 		if ( this._classes.size > 0 ) {
 			yield 'class';
 		}
@@ -258,7 +258,7 @@ export default class Element extends Node {
 	 *
 	 * @returns {Iterable.<*>}
 	 */
-	* getAttributes() {
+	*getAttributes() {
 		yield* this._attrs.entries();
 
 		if ( this._classes.size > 0 ) {
@@ -669,7 +669,7 @@ export default class Element extends Node {
 	 *
 	 * @returns {Iterable.<*>}
 	 */
-	* getCustomProperties() {
+	*getCustomProperties() {
 		yield* this._customProperties.entries();
 	}
 

+ 0 - 1
packages/ckeditor5-engine/src/view/matcher.js

@@ -212,7 +212,6 @@ export default class Matcher {
 
 		return ( typeof pattern != 'function' && name && !( name instanceof RegExp ) ) ? name : null;
 	}
-
 }
 
 // Returns match information if {@link module:engine/view/element~Element element} is matching provided pattern.

+ 8 - 8
packages/ckeditor5-engine/src/view/range.js

@@ -49,7 +49,7 @@ export default class Range {
 	 *
 	 * @returns {Iterable.<module:engine/view/treewalker~TreeWalkerValue>}
 	 */
-	* [ Symbol.iterator ]() {
+	*[ Symbol.iterator ]() {
 		yield* new TreeWalker( { boundaries: this, ignoreElementEnd: true } );
 	}
 
@@ -98,8 +98,8 @@ export default class Range {
 	 * @returns {module:engine/view/range~Range} Enlarged range.
 	 */
 	getEnlarged() {
-		let start = this.start.getLastMatchingPosition( enlargeShrinkSkip, { direction: 'backward' } );
-		let end = this.end.getLastMatchingPosition( enlargeShrinkSkip );
+		let start = this.start.getLastMatchingPosition( enlargeTrimSkip, { direction: 'backward' } );
+		let end = this.end.getLastMatchingPosition( enlargeTrimSkip );
 
 		// Fix positions, in case if they are in Text node.
 		if ( start.parent.is( 'text' ) && start.isAtStart ) {
@@ -130,8 +130,8 @@ export default class Range {
 	 * @returns {module:engine/view/range~Range} Shrink range.
 	 */
 	getTrimmed() {
-		let start = this.start.getLastMatchingPosition( enlargeShrinkSkip );
-		let end = this.end.getLastMatchingPosition( enlargeShrinkSkip, { direction: 'backward' } );
+		let start = this.start.getLastMatchingPosition( enlargeTrimSkip, { boundaries: new Range( this.start, this.end ) } );
+		let end = this.end.getLastMatchingPosition( enlargeTrimSkip, { boundaries: new Range( start, this.end ), direction: 'backward' } );
 		const nodeAfterStart = start.nodeAfter;
 		const nodeBeforeEnd = end.nodeBefore;
 
@@ -328,7 +328,7 @@ export default class Range {
 	 * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.
 	 * @returns {Iterable.<module:engine/view/item~Item>}
 	 */
-	* getItems( options = {} ) {
+	*getItems( options = {} ) {
 		options.boundaries = this;
 		options.ignoreElementEnd = true;
 
@@ -352,7 +352,7 @@ export default class Range {
 	 * @param {Object} options Object with configuration options. See {@link module:engine/view/treewalker~TreeWalker}.
 	 * @returns {Iterable.<module:engine/view/position~Position>}
 	 */
-	* getPositions( options = {} ) {
+	*getPositions( options = {} ) {
 		options.boundaries = this;
 
 		const treeWalker = new TreeWalker( options );
@@ -438,7 +438,7 @@ export default class Range {
 }
 
 // Function used by getEnlagred and getShrinked methods.
-function enlargeShrinkSkip( value ) {
+function enlargeTrimSkip( value ) {
 	if ( value.item.is( 'attributeElement' ) || value.item.is( 'uiElement' ) ) {
 		return true;
 	}

+ 1 - 1
packages/ckeditor5-engine/src/view/selection.js

@@ -223,7 +223,7 @@ export default class Selection {
 	 *
 	 * @returns {Iterator.<module:engine/view/range~Range>}
 	 */
-	* getRanges() {
+	*getRanges() {
 		for ( const range of this._ranges ) {
 			yield Range.createFromRange( range );
 		}

+ 0 - 1
packages/ckeditor5-engine/src/view/writer.js

@@ -933,7 +933,6 @@ function wrapChildren( parent, startOffset, endOffset, attribute ) {
 		const isUI = child.is( 'uiElement' );
 
 		// Wrap text, empty elements, ui elements or attributes with higher or equal priority.
-		// if ( isText || isEmpty || isUI || ( isAttribute && attribute.priority <= child.priority ) ) {
 		if ( isText || isEmpty || isUI || ( isAttribute && shouldABeOutsideB( attribute, child ) ) ) {
 			// Clone attribute.
 			const newAttribute = attribute.clone();

+ 1 - 3
packages/ckeditor5-engine/tests/dev-utils/view.js

@@ -611,9 +611,7 @@ describe( 'view test utils', () => {
 		} );
 
 		it( 'should throw when wrong type is provided', () => {
-			sinon.stub( XmlDataProcessor.prototype, 'toView', () => {
-				return new ContainerElement( 'invalidType:b' );
-			} );
+			sinon.stub( XmlDataProcessor.prototype, 'toView' ).returns( new ContainerElement( 'invalidType:b' ) );
 
 			expect( () => {
 				parse( 'sth' );

+ 50 - 49
packages/ckeditor5-engine/tests/manual/markers.js

@@ -24,64 +24,65 @@ const markerNames = [];
 let model = null;
 let _uid = 1;
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Paragraph, Bold, Italic, List, Heading, Undo ],
-	toolbar: [ 'headings', 'bold', 'italic', 'bulletedList', 'numberedList', 'undo', 'redo' ]
-} )
-.then( editor => {
-	window.editor = editor;
-	model = window.editor.editing.model;
-
-	buildModelConverter().for( editor.editing.modelToView )
-		.fromMarker( 'highlight' )
-		.toElement( data => {
-			const color = data.name.split( ':' )[ 1 ];
-
-			return new ViewAttributeElement( 'span', { class: 'h-' + color } );
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Paragraph, Bold, Italic, List, Heading, Undo ],
+		toolbar: [ 'headings', 'bold', 'italic', 'bulletedList', 'numberedList', 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
+		model = window.editor.editing.model;
+
+		buildModelConverter().for( editor.editing.modelToView )
+			.fromMarker( 'highlight' )
+			.toElement( data => {
+				const color = data.name.split( ':' )[ 1 ];
+
+				return new ViewAttributeElement( 'span', { class: 'h-' + color } );
+			} );
+
+		window.document.getElementById( 'add-yellow' ).addEventListener( 'mousedown', e => {
+			e.preventDefault();
+			addHighlight( 'yellow' );
 		} );
 
-	window.document.getElementById( 'add-yellow' ).addEventListener( 'mousedown', e => {
-		e.preventDefault();
-		addHighlight( 'yellow' );
-	} );
-
-	window.document.getElementById( 'add-red' ).addEventListener( 'mousedown', e => {
-		e.preventDefault();
-		addHighlight( 'red' );
-	} );
+		window.document.getElementById( 'add-red' ).addEventListener( 'mousedown', e => {
+			e.preventDefault();
+			addHighlight( 'red' );
+		} );
 
-	window.document.getElementById( 'remove-marker' ).addEventListener( 'mousedown', e => {
-		e.preventDefault();
-		removeHighlight();
-	} );
+		window.document.getElementById( 'remove-marker' ).addEventListener( 'mousedown', e => {
+			e.preventDefault();
+			removeHighlight();
+		} );
 
-	window.document.getElementById( 'move-to-start' ).addEventListener( 'mousedown', e => {
-		e.preventDefault();
-		moveSelectionToStart();
-	} );
+		window.document.getElementById( 'move-to-start' ).addEventListener( 'mousedown', e => {
+			e.preventDefault();
+			moveSelectionToStart();
+		} );
 
-	window.document.getElementById( 'move-left' ).addEventListener( 'mousedown', e => {
-		e.preventDefault();
-		moveSelectionByOffset( -1 );
-	} );
+		window.document.getElementById( 'move-left' ).addEventListener( 'mousedown', e => {
+			e.preventDefault();
+			moveSelectionByOffset( -1 );
+		} );
 
-	window.document.getElementById( 'move-right' ).addEventListener( 'mousedown', e => {
-		e.preventDefault();
-		moveSelectionByOffset( 1 );
-	} );
+		window.document.getElementById( 'move-right' ).addEventListener( 'mousedown', e => {
+			e.preventDefault();
+			moveSelectionByOffset( 1 );
+		} );
 
-	model.enqueueChanges( () => {
-		const root = model.getRoot();
-		const range = new Range( new Position( root, [ 0, 10 ] ), new Position( root, [ 0, 16 ] ) );
-		const name = 'highlight:yellow:' + uid();
+		model.enqueueChanges( () => {
+			const root = model.getRoot();
+			const range = new Range( new Position( root, [ 0, 10 ] ), new Position( root, [ 0, 16 ] ) );
+			const name = 'highlight:yellow:' + uid();
 
-		markerNames.push( name );
-		model.markers.set( name, range );
+			markerNames.push( name );
+			model.markers.set( name, range );
+		} );
+	} )
+	.catch( err => {
+		console.error( err.stack );
 	} );
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
 
 function uid() {
 	return _uid++;

+ 13 - 12
packages/ckeditor5-engine/tests/manual/nestededitable.js

@@ -69,21 +69,22 @@ class NestedEditable extends Plugin {
 	}
 }
 
-ClassicEditor.create( global.document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Paragraph, NestedEditable, Undo ],
-	toolbar: [ 'undo', 'redo' ]
-} )
-.then( editor => {
-	editor.document.on( 'changesDone', () => {
+ClassicEditor
+	.create( global.document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Paragraph, NestedEditable, Undo ],
+		toolbar: [ 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		editor.document.on( 'changesDone', () => {
+			printModelContents( editor );
+		} );
+
 		printModelContents( editor );
+	} )
+	.catch( err => {
+		console.error( err.stack );
 	} );
 
-	printModelContents( editor );
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
-
 const modelDiv = global.document.querySelector( '#model' );
 function printModelContents( editor ) {
 	modelDiv.innerText = getData( editor.document );

+ 16 - 15
packages/ckeditor5-engine/tests/manual/placeholder.js

@@ -14,19 +14,20 @@ import Heading from '@ckeditor/ckeditor5-heading/src/heading';
 import global from '@ckeditor/ckeditor5-utils/src/dom/global';
 import { attachPlaceholder } from '../../src/view/placeholder';
 
-ClassicEditor.create( global.document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Paragraph, Undo, Heading ],
-	toolbar: [ 'headings', 'undo', 'redo' ]
-} )
-.then( editor => {
-	const viewDoc = editor.editing.view;
-	const header = viewDoc.getRoot().getChild( 0 );
-	const paragraph = viewDoc.getRoot().getChild( 1 );
+ClassicEditor
+	.create( global.document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Paragraph, Undo, Heading ],
+		toolbar: [ 'headings', 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		const viewDoc = editor.editing.view;
+		const header = viewDoc.getRoot().getChild( 0 );
+		const paragraph = viewDoc.getRoot().getChild( 1 );
 
-	attachPlaceholder( header, 'Type some header text...' );
-	attachPlaceholder( paragraph, 'Type some paragraph text...' );
-	viewDoc.render();
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+		attachPlaceholder( header, 'Type some header text...' );
+		attachPlaceholder( paragraph, 'Type some paragraph text...' );
+		viewDoc.render();
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 11 - 10
packages/ckeditor5-engine/tests/manual/tickets/401/1.js

@@ -11,13 +11,14 @@ import Typing from '@ckeditor/ckeditor5-typing/src/typing';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
 
-ClassicEditor.create( document.getElementById( 'editor' ), {
-	plugins: [ Enter, Typing, Paragraph, Bold ],
-	toolbar: [ 'bold' ]
-} )
-.then( editor => {
-	window.editor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+ClassicEditor
+	.create( document.getElementById( 'editor' ), {
+		plugins: [ Enter, Typing, Paragraph, Bold ],
+		toolbar: [ 'bold' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 20 - 19
packages/ckeditor5-engine/tests/manual/tickets/462/1.js

@@ -12,25 +12,26 @@ import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
 import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Paragraph, Bold, Italic ],
-	toolbar: [ 'bold', 'italic' ]
-} )
-.then( editor => {
-	window.editor = editor;
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Paragraph, Bold, Italic ],
+		toolbar: [ 'bold', 'italic' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
 
-	setInterval( () => {
-		console.clear();
+		setInterval( () => {
+			console.clear();
 
-		const domSelection = document.getSelection();
-		const selectionExists = domSelection && domSelection.anchorNode;
+			const domSelection = document.getSelection();
+			const selectionExists = domSelection && domSelection.anchorNode;
 
-		console.log( editor.editing.view.getDomRoot().innerHTML.replace( /\u200b/g, '@' ) );
-		console.log( 'selection.hasAttribute( italic ):', editor.document.selection.hasAttribute( 'italic' ) );
-		console.log( 'selection.hasAttribute( bold ):', editor.document.selection.hasAttribute( 'bold' ) );
-		console.log( 'selection anchor\'s parentNode:', selectionExists ? domSelection.anchorNode.parentNode : 'no DOM selection' );
-	}, 2000 );
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+			console.log( editor.editing.view.getDomRoot().innerHTML.replace( /\u200b/g, '@' ) );
+			console.log( 'selection.hasAttribute( italic ):', editor.document.selection.hasAttribute( 'italic' ) );
+			console.log( 'selection.hasAttribute( bold ):', editor.document.selection.hasAttribute( 'bold' ) );
+			console.log( 'selection anchor\'s parentNode:', selectionExists ? domSelection.anchorNode.parentNode : 'no DOM selection' );
+		}, 2000 );
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 15 - 14
packages/ckeditor5-engine/tests/manual/tickets/603/1.js

@@ -13,20 +13,21 @@ import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
 import Italic from '@ckeditor/ckeditor5-basic-styles/src/italic';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Paragraph, Heading, Bold, Italic ],
-	toolbar: [ 'headings', 'bold', 'italic' ]
-} )
-.then( editor => {
-	window.editor = editor;
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Paragraph, Heading, Bold, Italic ],
+		toolbar: [ 'headings', 'bold', 'italic' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
 
-	const sel = editor.document.selection;
+		const sel = editor.document.selection;
 
-	sel.on( 'change', ( evt, data ) => {
-		const date = new Date();
-		console.log( `${ date.getSeconds() }s${ String( date.getMilliseconds() ).slice( 0, 2 ) }ms`, evt.name, data );
+		sel.on( 'change', ( evt, data ) => {
+			const date = new Date();
+			console.log( `${ date.getSeconds() }s${ String( date.getMilliseconds() ).slice( 0, 2 ) }ms`, evt.name, data );
+		} );
+	} )
+	.catch( err => {
+		console.error( err.stack );
 	} );
-} )
-.catch( err => {
-	console.error( err.stack );
-} );

+ 11 - 10
packages/ckeditor5-engine/tests/manual/tickets/629/1.js

@@ -11,13 +11,14 @@ import Typing from '@ckeditor/ckeditor5-typing/src/typing';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ Enter, Typing, Paragraph, Bold ],
-	toolbar: [ 'bold' ]
-} )
-.then( editor => {
-	window.editor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ Enter, Typing, Paragraph, Bold ],
+		toolbar: [ 'bold' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 15 - 13
packages/ckeditor5-engine/tests/manual/tickets/880/1.js

@@ -10,18 +10,20 @@ import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ EssentialsPreset, Paragraph, Bold ],
-	toolbar: [ 'undo', 'redo' ]
-} )
-.then( editor => {
-	window.editor = editor;
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ EssentialsPreset, Paragraph, Bold ],
+		toolbar: [ 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
 
-	editor.editing.view.on( 'selectionChange', () => {
-		editor.document.enqueueChanges( () => {} );
-		console.log( 'selectionChange', ( new Date() ).getTime() );
+		editor.editing.view.on( 'selectionChange', () => {
+			editor.document.enqueueChanges( () => {
+			} );
+			console.log( 'selectionChange', ( new Date() ).getTime() );
+		} );
+	} )
+	.catch( err => {
+		console.error( err.stack );
 	} );
-} )
-.catch( err => {
-	console.error( err.stack );
-} );

+ 11 - 10
packages/ckeditor5-engine/tests/manual/tickets/887/1.js

@@ -10,13 +10,14 @@ import EssentialsPreset from '@ckeditor/ckeditor5-presets/src/essentials';
 import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
 import Bold from '@ckeditor/ckeditor5-basic-styles/src/bold';
 
-ClassicEditor.create( document.querySelector( '#editor' ), {
-	plugins: [ EssentialsPreset, Paragraph, Bold ],
-	toolbar: [ 'undo', 'redo' ]
-} )
-.then( editor => {
-	window.editor = editor;
-} )
-.catch( err => {
-	console.error( err.stack );
-} );
+ClassicEditor
+	.create( document.querySelector( '#editor' ), {
+		plugins: [ EssentialsPreset, Paragraph, Bold ],
+		toolbar: [ 'undo', 'redo' ]
+	} )
+	.then( editor => {
+		window.editor = editor;
+	} )
+	.catch( err => {
+		console.error( err.stack );
+	} );

+ 1 - 1
packages/ckeditor5-engine/tests/model/selection.js

@@ -468,7 +468,7 @@ describe( 'Selection', () => {
 			const startPos = Position.createAt( root, 1 );
 			const endPos = Position.createAt( root, 2 );
 			const newEndPos = Position.createAt( root, 4 );
-			const spy = testUtils.sinon.stub( Position, 'createAt', () => newEndPos );
+			const spy = testUtils.sinon.stub( Position, 'createAt' ).returns( newEndPos );
 
 			selection.addRange( new Range( startPos, endPos ) );
 

+ 1 - 2
packages/ckeditor5-engine/tests/view/domconverter/binding.js

@@ -277,7 +277,7 @@ describe( 'DomConverter', () => {
 
 		it( 'should bind DOM element to selection', () => {
 			const bindSelection = converter.fakeSelectionToView( domEl );
-			expect( bindSelection ).to.be.defined;
+			expect( bindSelection ).to.not.be.undefined;
 			expect( bindSelection.isEqual( selection ) ).to.be.true;
 		} );
 
@@ -287,7 +287,6 @@ describe( 'DomConverter', () => {
 			selection.addRange( ViewRange.createIn( new ViewElement() ), true );
 			const bindSelection = converter.fakeSelectionToView( domEl );
 
-			expect( bindSelection ).to.be.defined;
 			expect( bindSelection ).to.not.equal( selection );
 			expect( bindSelection.isEqual( selection ) ).to.be.false;
 			expect( bindSelection.isEqual( selectionCopy ) ).to.be.true;

+ 4 - 4
packages/ckeditor5-engine/tests/view/domconverter/uielement.js

@@ -41,14 +41,14 @@ describe( 'DOMConverter UIElement integration', () => {
 			expect( domElement.innerHTML ).to.equal( '<p><span>foo</span> bar</p>' );
 		} );
 
-		it( 'should bind only UIElement not child elements', () => {
+		it( 'should create DOM structure that all is mapped to single UIElement', () => {
 			const myElement = new MyUIElement( 'div' );
 			const domElement = converter.viewToDom( myElement, document, { bind: true } );
-			const domSpan = domElement.childNodes[ 0 ];
+			const domParagraph = domElement.childNodes[ 0 ];
 
 			expect( converter.mapDomToView( domElement ) ).to.equal( myElement );
-			expect( converter.mapDomToView( domSpan ) ).to.be.falsy;
-			expect( converter.mapDomToView( domSpan.childNodes[ 0 ] ) ).to.be.falsy;
+			expect( converter.mapDomToView( domParagraph ) ).to.equal( myElement );
+			expect( converter.mapDomToView( domParagraph.childNodes[ 0 ] ) ).to.equal( myElement );
 		} );
 	} );
 

+ 4 - 2
packages/ckeditor5-engine/tests/view/observer/selectionobserver.js

@@ -162,7 +162,7 @@ describe( 'SelectionObserver', () => {
 		viewDocument.selection.addRange( ViewRange.createFromParentsAndOffsets( viewFoo, 0, viewFoo, 0 ) );
 
 		return new Promise( ( resolve, reject ) => {
-			testUtils.sinon.stub( log, 'warn', msg => {
+			testUtils.sinon.stub( log, 'warn' ).callsFake( msg => {
 				expect( msg ).to.match( /^selectionchange-infinite-loop/ );
 
 				resolve();
@@ -197,7 +197,9 @@ describe( 'SelectionObserver', () => {
 	} );
 
 	it( 'should not be treated as an infinite loop if changes are not often', () => {
-		const clock = testUtils.sinon.useFakeTimers( 'setInterval', 'clearInterval' );
+		const clock = testUtils.sinon.useFakeTimers( {
+			toFake: [ 'setInterval', 'clearInterval' ]
+		} );
 		const stub = testUtils.sinon.stub( log, 'warn' );
 
 		// We need to recreate SelectionObserver, so it will use mocked setInterval.

+ 22 - 2
packages/ckeditor5-engine/tests/view/range.js

@@ -162,16 +162,36 @@ describe( 'Range', () => {
 				.to.equal( '<p><b>f</b>{oo}<b><span></span>bar</b></p>' );
 		} );
 
-		it( 'case6', () => {
+		it( 'case 6', () => {
 			expect( trim( '<p>foo[</p><p>bar</p><p>]bom</p>' ) )
 				.to.equal( '<p>foo[</p><p>bar</p><p>]bom</p>' );
 		} );
 
-		it( 'case7', () => {
+		it( 'case 7', () => {
 			expect( trim( '<p>foo[<b><img></img></b>]bom</p>' ) )
 				.to.equal( '<p>foo<b>[<img></img>]</b>bom</p>' );
 		} );
 
+		// Other results may theoretically be correct too. It is not decided whether the trimmed range should
+		// be collapsed in attribute element, at its start or its end. This is one of possible correct results
+		// and we won't know for sure unless we have more cases. See #1058.
+		it( 'case 8', () => {
+			expect( trim( '<p>[<b></b>]</p>' ) )
+				.to.equal( '<p><b></b>[]</p>' );
+		} );
+
+		// As above.
+		it( 'case 9', () => {
+			expect( trim( '<p><b></b>[<b></b>]<b></b></p>' ) )
+				.to.equal( '<p><b></b><b></b>[]<b></b></p>' );
+		} );
+
+		// As above.
+		it( 'case 10', () => {
+			expect( trim( '<p>[<b></b><b></b>]</p>' ) )
+				.to.equal( '<p><b></b><b></b>[]</p>' );
+		} );
+
 		function trim( data ) {
 			data = data
 				.replace( /<p>/g, '<container:p>' )

+ 1 - 1
packages/ckeditor5-engine/tests/view/renderer.js

@@ -1438,7 +1438,7 @@ describe( 'Renderer', () => {
 				const container = domRoot.childNodes[ 1 ];
 
 				const bindSelection = renderer.domConverter.fakeSelectionToView( container );
-				expect( bindSelection ).to.be.defined;
+				expect( bindSelection ).to.not.be.undefined;
 				expect( bindSelection.isEqual( selection ) ).to.be.true;
 			} );
 

+ 1 - 1
packages/ckeditor5-engine/tests/view/selection.js

@@ -241,7 +241,7 @@ describe( 'Selection', () => {
 			const endPos = Position.createAt( el, 2 );
 			const newEndPos = Position.createAt( el, 4 );
 
-			const spy = sinon.stub( Position, 'createAt', () => newEndPos );
+			const spy = sinon.stub( Position, 'createAt' ).returns( newEndPos );
 
 			selection.addRange( new Range( startPos, endPos ) );
 			selection.setFocus( el, 'end' );