Преглед изворни кода

Merge branch 'master' into i/7633-resizer-glitch

Piotrek Koszuliński пре 5 година
родитељ
комит
0bac0ea199
100 измењених фајлова са 368 додато и 402 уклоњено
  1. 1 1
      packages/ckeditor5-autoformat/src/blockautoformatediting.js
  2. 1 1
      packages/ckeditor5-autoformat/src/inlineautoformatediting.js
  3. 7 4
      packages/ckeditor5-block-quote/src/blockquoteediting.js
  4. 2 2
      packages/ckeditor5-clipboard/src/utils/viewtoplaintext.js
  5. 3 3
      packages/ckeditor5-code-block/src/codeblockcommand.js
  6. 8 8
      packages/ckeditor5-code-block/src/codeblockediting.js
  7. 1 1
      packages/ckeditor5-code-block/src/converters.js
  8. 2 2
      packages/ckeditor5-code-block/src/outdentcodeblockcommand.js
  9. 2 2
      packages/ckeditor5-code-block/src/utils.js
  10. 1 1
      packages/ckeditor5-engine/docs/_snippets/framework/extending-content-custom-figure-attributes.js
  11. 1 1
      packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-preserving-custom-content.md
  12. 3 3
      packages/ckeditor5-engine/src/conversion/conversion.js
  13. 1 1
      packages/ckeditor5-engine/src/conversion/downcasthelpers.js
  14. 4 4
      packages/ckeditor5-engine/src/conversion/mapper.js
  15. 1 1
      packages/ckeditor5-engine/src/conversion/upcastdispatcher.js
  16. 5 5
      packages/ckeditor5-engine/src/conversion/viewconsumable.js
  17. 1 1
      packages/ckeditor5-engine/src/dev-utils/model.js
  18. 2 2
      packages/ckeditor5-engine/src/dev-utils/view.js
  19. 1 1
      packages/ckeditor5-engine/src/model/differ.js
  20. 1 1
      packages/ckeditor5-engine/src/model/documentfragment.js
  21. 4 6
      packages/ckeditor5-engine/src/model/element.js
  22. 1 1
      packages/ckeditor5-engine/src/model/model.js
  23. 2 2
      packages/ckeditor5-engine/src/model/node.js
  24. 2 2
      packages/ckeditor5-engine/src/model/operation/utils.js
  25. 2 2
      packages/ckeditor5-engine/src/model/position.js
  26. 1 5
      packages/ckeditor5-engine/src/model/rootelement.js
  27. 2 2
      packages/ckeditor5-engine/src/model/schema.js
  28. 10 6
      packages/ckeditor5-engine/src/model/text.js
  29. 10 5
      packages/ckeditor5-engine/src/model/textproxy.js
  30. 1 1
      packages/ckeditor5-engine/src/model/utils/getselectedcontent.js
  31. 1 1
      packages/ckeditor5-engine/src/model/utils/modifyselection.js
  32. 3 5
      packages/ckeditor5-engine/src/view/attributeelement.js
  33. 3 5
      packages/ckeditor5-engine/src/view/containerelement.js
  34. 1 1
      packages/ckeditor5-engine/src/view/documentfragment.js
  35. 5 5
      packages/ckeditor5-engine/src/view/domconverter.js
  36. 10 10
      packages/ckeditor5-engine/src/view/downcastwriter.js
  37. 3 5
      packages/ckeditor5-engine/src/view/editableelement.js
  38. 5 7
      packages/ckeditor5-engine/src/view/element.js
  39. 3 5
      packages/ckeditor5-engine/src/view/emptyelement.js
  40. 2 3
      packages/ckeditor5-engine/src/view/node.js
  41. 1 1
      packages/ckeditor5-engine/src/view/observer/mutationobserver.js
  42. 6 6
      packages/ckeditor5-engine/src/view/position.js
  43. 7 7
      packages/ckeditor5-engine/src/view/range.js
  44. 2 2
      packages/ckeditor5-engine/src/view/renderer.js
  45. 3 5
      packages/ckeditor5-engine/src/view/rooteditableelement.js
  46. 10 5
      packages/ckeditor5-engine/src/view/text.js
  47. 10 5
      packages/ckeditor5-engine/src/view/textproxy.js
  48. 3 5
      packages/ckeditor5-engine/src/view/uielement.js
  49. 3 3
      packages/ckeditor5-engine/tests/conversion/conversion.js
  50. 1 1
      packages/ckeditor5-engine/tests/conversion/downcasthelpers.js
  51. 2 2
      packages/ckeditor5-engine/tests/model/documentfragment.js
  52. 2 2
      packages/ckeditor5-engine/tests/model/documentselection.js
  53. 7 6
      packages/ckeditor5-engine/tests/model/element.js
  54. 1 1
      packages/ckeditor5-engine/tests/model/liveposition.js
  55. 1 1
      packages/ckeditor5-engine/tests/model/liverange.js
  56. 1 1
      packages/ckeditor5-engine/tests/model/markercollection.js
  57. 2 2
      packages/ckeditor5-engine/tests/model/node.js
  58. 1 1
      packages/ckeditor5-engine/tests/model/position.js
  59. 1 1
      packages/ckeditor5-engine/tests/model/range.js
  60. 6 4
      packages/ckeditor5-engine/tests/model/rootelement.js
  61. 4 4
      packages/ckeditor5-engine/tests/model/selection.js
  62. 3 1
      packages/ckeditor5-engine/tests/model/text.js
  63. 4 2
      packages/ckeditor5-engine/tests/model/textproxy.js
  64. 5 5
      packages/ckeditor5-engine/tests/view/attributeelement.js
  65. 5 5
      packages/ckeditor5-engine/tests/view/containerelement.js
  66. 2 2
      packages/ckeditor5-engine/tests/view/documentfragment.js
  67. 3 3
      packages/ckeditor5-engine/tests/view/documentselection.js
  68. 2 2
      packages/ckeditor5-engine/tests/view/downcastwriter/writer.js
  69. 4 5
      packages/ckeditor5-engine/tests/view/editableelement.js
  70. 6 6
      packages/ckeditor5-engine/tests/view/element.js
  71. 6 6
      packages/ckeditor5-engine/tests/view/emptyelement.js
  72. 3 3
      packages/ckeditor5-engine/tests/view/node.js
  73. 5 5
      packages/ckeditor5-engine/tests/view/observer/mutationobserver.js
  74. 3 3
      packages/ckeditor5-engine/tests/view/position.js
  75. 3 3
      packages/ckeditor5-engine/tests/view/range.js
  76. 8 6
      packages/ckeditor5-engine/tests/view/rooteditableelement.js
  77. 2 2
      packages/ckeditor5-engine/tests/view/selection.js
  78. 5 3
      packages/ckeditor5-engine/tests/view/text.js
  79. 6 4
      packages/ckeditor5-engine/tests/view/textproxy.js
  80. 5 5
      packages/ckeditor5-engine/tests/view/uielement.js
  81. 1 1
      packages/ckeditor5-font/src/ui/colortableview.js
  82. 1 1
      packages/ckeditor5-heading/src/headingcommand.js
  83. 2 2
      packages/ckeditor5-heading/src/headingediting.js
  84. 6 6
      packages/ckeditor5-heading/src/title.js
  85. 1 1
      packages/ckeditor5-horizontal-line/src/horizontallinecommand.js
  86. 4 4
      packages/ckeditor5-image/src/image/utils.js
  87. 4 4
      packages/ckeditor5-image/src/imagecaption/imagecaptionediting.js
  88. 1 1
      packages/ckeditor5-image/src/imagecaption/utils.js
  89. 1 1
      packages/ckeditor5-image/src/imageupload/imageuploadediting.js
  90. 1 1
      packages/ckeditor5-link/src/autolink.js
  91. 2 2
      packages/ckeditor5-link/src/linkcommand.js
  92. 6 66
      packages/ckeditor5-link/src/linkediting.js
  93. 2 2
      packages/ckeditor5-link/src/linkimageediting.js
  94. 1 1
      packages/ckeditor5-link/src/linkimageui.js
  95. 8 2
      packages/ckeditor5-link/src/unlinkcommand.js
  96. 1 1
      packages/ckeditor5-link/src/utils.js
  97. 26 20
      packages/ckeditor5-link/tests/linkediting.js
  98. 21 20
      packages/ckeditor5-list/src/converters.js
  99. 2 2
      packages/ckeditor5-list/src/indentcommand.js
  100. 4 4
      packages/ckeditor5-list/src/listcommand.js

+ 1 - 1
packages/ckeditor5-autoformat/src/blockautoformatediting.js

@@ -83,7 +83,7 @@ export default function blockAutoformatEditing( editor, plugin, pattern, callbac
 		const blockToFormat = entry.position.parent;
 
 		// Block formatting should trigger only if the entire content of a paragraph is a single text node... (see ckeditor5#5671).
-		if ( !blockToFormat.is( 'paragraph' ) || blockToFormat.childCount !== 1 ) {
+		if ( !blockToFormat.is( 'element', 'paragraph' ) || blockToFormat.childCount !== 1 ) {
 			return;
 		}
 

+ 1 - 1
packages/ckeditor5-autoformat/src/inlineautoformatediting.js

@@ -201,7 +201,7 @@ function getTextAfterCode( range, model ) {
 
 	const text = Array.from( range.getItems() ).reduce( ( rangeText, node ) => {
 		// Trim text to a last occurrence of an inline element and update range start.
-		if ( !( node.is( 'text' ) || node.is( 'textProxy' ) ) || node.getAttribute( 'code' ) ) {
+		if ( !( node.is( '$text' ) || node.is( '$textProxy' ) ) || node.getAttribute( 'code' ) ) {
 			start = model.createPositionAfter( node );
 
 			return '';

+ 7 - 4
packages/ckeditor5-block-quote/src/blockquoteediting.js

@@ -62,12 +62,12 @@ export default class BlockQuoteEditing extends Plugin {
 						continue;
 					}
 
-					if ( element.is( 'blockQuote' ) && element.isEmpty ) {
+					if ( element.is( 'element', 'blockQuote' ) && element.isEmpty ) {
 						// Added an empty blockQuote - remove it.
 						writer.remove( element );
 
 						return true;
-					} else if ( element.is( 'blockQuote' ) && !schema.checkChild( entry.position, element ) ) {
+					} else if ( element.is( 'element', 'blockQuote' ) && !schema.checkChild( entry.position, element ) ) {
 						// Added a blockQuote in incorrect place - most likely inside another blockQuote. Unwrap it
 						// so the content inside is not lost.
 						writer.unwrap( element );
@@ -78,7 +78,10 @@ export default class BlockQuoteEditing extends Plugin {
 						const range = writer.createRangeIn( element );
 
 						for ( const child of range.getItems() ) {
-							if ( child.is( 'blockQuote' ) && !schema.checkChild( writer.createPositionBefore( child ), child ) ) {
+							if (
+								child.is( 'element', 'blockQuote' ) &&
+								!schema.checkChild( writer.createPositionBefore( child ), child )
+							) {
 								writer.unwrap( child );
 
 								return true;
@@ -88,7 +91,7 @@ export default class BlockQuoteEditing extends Plugin {
 				} else if ( entry.type == 'remove' ) {
 					const parent = entry.position.parent;
 
-					if ( parent.is( 'blockQuote' ) && parent.isEmpty ) {
+					if ( parent.is( 'element', 'blockQuote' ) && parent.isEmpty ) {
 						// Something got removed and now blockQuote is empty. Remove the blockQuote as well.
 						writer.remove( parent );
 

+ 2 - 2
packages/ckeditor5-clipboard/src/utils/viewtoplaintext.js

@@ -21,10 +21,10 @@ const smallPaddingElements = [ 'figcaption', 'li' ];
 export default function viewToPlainText( viewItem ) {
 	let text = '';
 
-	if ( viewItem.is( 'text' ) || viewItem.is( 'textProxy' ) ) {
+	if ( viewItem.is( '$text' ) || viewItem.is( '$textProxy' ) ) {
 		// If item is `Text` or `TextProxy` simple take its text data.
 		text = viewItem.data;
-	} else if ( viewItem.is( 'img' ) && viewItem.hasAttribute( 'alt' ) ) {
+	} else if ( viewItem.is( 'element', 'img' ) && viewItem.hasAttribute( 'alt' ) ) {
 		// Special case for images - use alt attribute if it is provided.
 		text = viewItem.getAttribute( 'alt' );
 	} else {

+ 3 - 3
packages/ckeditor5-code-block/src/codeblockcommand.js

@@ -72,7 +72,7 @@ export default class CodeBlockCommand extends Command {
 	_getValue() {
 		const selection = this.editor.model.document.selection;
 		const firstBlock = first( selection.getSelectedBlocks() );
-		const isCodeBlock = !!( firstBlock && firstBlock.is( 'codeBlock' ) );
+		const isCodeBlock = !!( firstBlock && firstBlock.is( 'element', 'codeBlock' ) );
 
 		return isCodeBlock ? firstBlock.getAttribute( 'language' ) : false;
 	}
@@ -132,13 +132,13 @@ export default class CodeBlockCommand extends Command {
 	 * @param {Array.<module:engine/model/element~Element>} blocks
 	 */
 	_removeCodeBlock( writer, blocks ) {
-		const codeBlocks = blocks.filter( block => block.is( 'codeBlock' ) );
+		const codeBlocks = blocks.filter( block => block.is( 'element', 'codeBlock' ) );
 
 		for ( const block of codeBlocks ) {
 			const range = writer.createRangeOn( block );
 
 			for ( const item of Array.from( range.getItems() ).reverse() ) {
-				if ( item.is( 'softBreak' ) && item.parent.is( 'codeBlock' ) ) {
+				if ( item.is( 'element', 'softBreak' ) && item.parent.is( 'element', 'codeBlock' ) ) {
 					const { position } = writer.split( writer.createPositionBefore( item ) );
 
 					writer.rename( position.nodeAfter, 'paragraph' );

+ 8 - 8
packages/ckeditor5-code-block/src/codeblockediting.js

@@ -136,7 +136,7 @@ export default class CodeBlockEditing extends Plugin {
 		this.listenTo( editor.editing.view.document, 'clipboardInput', ( evt, data ) => {
 			const modelSelection = model.document.selection;
 
-			if ( !modelSelection.anchor.parent.is( 'codeBlock' ) ) {
+			if ( !modelSelection.anchor.parent.is( 'element', 'codeBlock' ) ) {
 				return;
 			}
 
@@ -156,7 +156,7 @@ export default class CodeBlockEditing extends Plugin {
 		this.listenTo( model, 'getSelectedContent', ( evt, [ selection ] ) => {
 			const anchor = selection.anchor;
 
-			if ( selection.isCollapsed || !anchor.parent.is( 'codeBlock' ) || !anchor.hasSameParentAs( selection.focus ) ) {
+			if ( selection.isCollapsed || !anchor.parent.is( 'element', 'codeBlock' ) || !anchor.hasSameParentAs( selection.focus ) ) {
 				return;
 			}
 
@@ -210,7 +210,7 @@ export default class CodeBlockEditing extends Plugin {
 		this.listenTo( editor.editing.view.document, 'enter', ( evt, data ) => {
 			const positionParent = editor.model.document.selection.getLastPosition().parent;
 
-			if ( !positionParent.is( 'codeBlock' ) ) {
+			if ( !positionParent.is( 'element', 'codeBlock' ) ) {
 				return;
 			}
 
@@ -248,7 +248,7 @@ function breakLineOnEnter( editor ) {
 	let leadingWhiteSpaces;
 
 	// Figure out the indentation (white space chars) at the beginning of the line.
-	if ( node && node.is( 'text' ) ) {
+	if ( node && node.is( '$text' ) ) {
 		leadingWhiteSpaces = getLeadingWhiteSpaces( node );
 	}
 
@@ -287,7 +287,7 @@ function leaveBlockStartOnEnter( editor, isSoftEnter ) {
 		return false;
 	}
 
-	if ( !nodeAfter || !nodeAfter.is( 'softBreak' ) ) {
+	if ( !nodeAfter || !nodeAfter.is( 'element', 'softBreak' ) ) {
 		return false;
 	}
 
@@ -350,7 +350,7 @@ function leaveBlockEndOnEnter( editor, isSoftEnter ) {
 	//
 	//		<codeBlock>foo[<softBreak></softBreak>]</codeBlock>
 	//
-	if ( nodeBefore.is( 'softBreak' ) ) {
+	if ( nodeBefore.is( 'element', 'softBreak' ) ) {
 		emptyLineRangeToRemoveOnEnter = model.createRangeOn( nodeBefore );
 	}
 
@@ -367,10 +367,10 @@ function leaveBlockEndOnEnter( editor, isSoftEnter ) {
 	//		<codeBlock>foo[<softBreak></softBreak>    ]</codeBlock>
 	//
 	else if (
-		nodeBefore.is( 'text' ) &&
+		nodeBefore.is( '$text' ) &&
 		!nodeBefore.data.match( /\S/ ) &&
 		nodeBefore.previousSibling &&
-		nodeBefore.previousSibling.is( 'softBreak' )
+		nodeBefore.previousSibling.is( 'element', 'softBreak' )
 	) {
 		emptyLineRangeToRemoveOnEnter = model.createRange(
 			model.createPositionBefore( nodeBefore.previousSibling ), model.createPositionAfter( nodeBefore )

+ 1 - 1
packages/ckeditor5-code-block/src/converters.js

@@ -147,7 +147,7 @@ export function dataViewToModelCodeBlockInsertion( editingView, languageDefs ) {
 		const viewItem = data.viewItem;
 		const viewChild = viewItem.getChild( 0 );
 
-		if ( !viewChild || !viewChild.is( 'code' ) ) {
+		if ( !viewChild || !viewChild.is( 'element', 'code' ) ) {
 			return;
 		}
 

+ 2 - 2
packages/ckeditor5-code-block/src/outdentcodeblockcommand.js

@@ -173,13 +173,13 @@ function getCodeLineTextNodeAtPosition( position ) {
 
 	// <codeBlock>foo^</codeBlock>
 	// <codeBlock>foo^<softBreak></softBreak>bar</codeBlock>
-	if ( !nodeAtPosition || nodeAtPosition.is( 'softBreak' ) ) {
+	if ( !nodeAtPosition || nodeAtPosition.is( 'element', 'softBreak' ) ) {
 		nodeAtPosition = position.nodeBefore;
 	}
 
 	// <codeBlock>^</codeBlock>
 	// <codeBlock>foo^<softBreak></softBreak>bar</codeBlock>
-	if ( !nodeAtPosition || nodeAtPosition.is( 'softBreak' ) ) {
+	if ( !nodeAtPosition || nodeAtPosition.is( 'element', 'softBreak' ) ) {
 		return null;
 	}
 

+ 2 - 2
packages/ckeditor5-code-block/src/utils.js

@@ -189,7 +189,7 @@ export function getIndentOutdentPositions( model ) {
 		} );
 
 		for ( const { item } of walker ) {
-			if ( item.is( 'textProxy' ) && item.parent.is( 'codeBlock' ) ) {
+			if ( item.is( '$textProxy' ) && item.parent.is( 'element', 'codeBlock' ) ) {
 				const leadingWhiteSpaces = getLeadingWhiteSpaces( item.textNode );
 				const { parent, startOffset } = item.textNode;
 
@@ -213,5 +213,5 @@ export function getIndentOutdentPositions( model ) {
 export function isModelSelectionInCodeBlock( selection ) {
 	const firstBlock = first( selection.getSelectedBlocks() );
 
-	return firstBlock && firstBlock.is( 'codeBlock' );
+	return firstBlock && firstBlock.is( 'element', 'codeBlock' );
 }

+ 1 - 1
packages/ckeditor5-engine/docs/_snippets/framework/extending-content-custom-figure-attributes.js

@@ -131,7 +131,7 @@ function downcastCustomClasses( modelElementName ) {
 function findViewChild( viewElement, viewElementName, conversionApi ) {
 	const viewChildren = Array.from( conversionApi.writer.createRangeIn( viewElement ).getItems() );
 
-	return viewChildren.find( item => item.is( viewElementName ) );
+	return viewChildren.find( item => item.is( 'element', viewElementName ) );
 }
 
 /**

+ 1 - 1
packages/ckeditor5-engine/docs/framework/guides/deep-dive/conversion-preserving-custom-content.md

@@ -429,7 +429,7 @@ function downcastCustomClassesToChild( viewElementName, modelElementName ) {
 function findViewChild( viewElement, viewElementName, conversionApi ) {
 	const viewChildren = Array.from( conversionApi.writer.createRangeIn( viewElement ).getItems() );
 
-	return viewChildren.find( item => item.is( viewElementName ) );
+	return viewChildren.find( item => item.is( 'element', viewElementName ) );
 }
 
 /**

+ 3 - 3
packages/ckeditor5-engine/src/conversion/conversion.js

@@ -337,7 +337,7 @@ export default class Conversion {
 	 *				viewElement => {
 	 *					const fontWeight = viewElement.getStyle( 'font-weight' );
 	 *
-	 *					if ( viewElement.is( 'span' ) && fontWeight && /\d+/.test() && Number( fontWeight ) > 500 ) {
+	 *					if ( viewElement.is( 'element', 'span' ) && fontWeight && /\d+/.test() && Number( fontWeight ) > 500 ) {
 	 *						// Returned value can be an object with the matched properties.
 	 *						// These properties will be "consumed" during the conversion.
 	 *						// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.
@@ -388,7 +388,7 @@ export default class Conversion {
 	 *
 	 *					const size = Number( match[ 1 ] );
 	 *
-	 *					if ( viewElement.is( 'span' ) && size > 10 ) {
+	 *					if ( viewElement.is( 'element', 'span' ) && size > 10 ) {
 	 *						// Returned value can be an object with the matched properties.
 	 *						// These properties will be "consumed" during the conversion.
 	 *						// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.
@@ -413,7 +413,7 @@ export default class Conversion {
 	 *
 	 *					const size = Number( match[ 1 ] );
 	 *
-	 *					if ( viewElement.is( 'span' ) && size < 10 ) {
+	 *					if ( viewElement.is( 'element', 'span' ) && size < 10 ) {
 	 *						// Returned value can be an object with the matched properties.
 	 *						// These properties will be "consumed" during the conversion.
 	 *						// See `engine.view.Matcher~MatcherPattern` and `engine.view.Matcher#match` for more details.

+ 1 - 1
packages/ckeditor5-engine/src/conversion/downcasthelpers.js

@@ -1155,7 +1155,7 @@ function highlightText( highlightDescriptor ) {
 			return;
 		}
 
-		if ( !( data.item instanceof ModelSelection || data.item instanceof DocumentSelection ) && !data.item.is( 'textProxy' ) ) {
+		if ( !( data.item instanceof ModelSelection || data.item instanceof DocumentSelection ) && !data.item.is( '$textProxy' ) ) {
 			return;
 		}
 

+ 4 - 4
packages/ckeditor5-engine/src/conversion/mapper.js

@@ -445,7 +445,7 @@ export default class Mapper {
 		// viewBlock == viewParent, so we need to calculate the offset in the parent element.
 
 		// If the position is a text it is simple ("ba|r" -> 2).
-		if ( viewParent.is( 'text' ) ) {
+		if ( viewParent.is( '$text' ) ) {
 			return viewOffset;
 		}
 
@@ -488,7 +488,7 @@ export default class Mapper {
 			return callback( viewNode );
 		} else if ( this._viewToModelMapping.has( viewNode ) ) {
 			return 1;
-		} else if ( viewNode.is( 'text' ) ) {
+		} else if ( viewNode.is( '$text' ) ) {
 			return viewNode.data.length;
 		} else if ( viewNode.is( 'uiElement' ) ) {
 			return 0;
@@ -537,7 +537,7 @@ export default class Mapper {
 		let viewOffset = 0;
 
 		// In the text node it is simple: offset in the model equals offset in the text.
-		if ( viewParent.is( 'text' ) ) {
+		if ( viewParent.is( '$text' ) ) {
 			return new ViewPosition( viewParent, expectedOffset );
 		}
 
@@ -631,7 +631,7 @@ export default class Mapper {
 	 *			const sibling = data.modelPosition.nodeBefore;
 	 *
 	 *			// Check if this is the element we are interested in.
-	 *			if ( !sibling.is( 'customElement' ) ) {
+	 *			if ( !sibling.is( 'element', 'customElement' ) ) {
 	 *				return;
 	 *			}
 	 *

+ 1 - 1
packages/ckeditor5-engine/src/conversion/upcastdispatcher.js

@@ -237,7 +237,7 @@ export default class UpcastDispatcher {
 
 		if ( viewItem.is( 'element' ) ) {
 			this.fire( 'element:' + viewItem.name, data, this.conversionApi );
-		} else if ( viewItem.is( 'text' ) ) {
+		} else if ( viewItem.is( '$text' ) ) {
 			this.fire( 'text', data, this.conversionApi );
 		} else {
 			this.fire( 'documentFragment', data, this.conversionApi );

+ 5 - 5
packages/ckeditor5-engine/src/conversion/viewconsumable.js

@@ -80,7 +80,7 @@ export default class ViewConsumable {
 		let elementConsumables;
 
 		// For text nodes and document fragments just mark them as consumable.
-		if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {
+		if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {
 			this._consumables.set( element, true );
 
 			return;
@@ -134,7 +134,7 @@ export default class ViewConsumable {
 		}
 
 		// For text nodes and document fragments return stored boolean value.
-		if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {
+		if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {
 			return elementConsumables;
 		}
 
@@ -172,7 +172,7 @@ export default class ViewConsumable {
 	 */
 	consume( element, consumables ) {
 		if ( this.test( element, consumables ) ) {
-			if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {
+			if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {
 				// For text nodes and document fragments set value to false.
 				this._consumables.set( element, false );
 			} else {
@@ -218,7 +218,7 @@ export default class ViewConsumable {
 		const elementConsumables = this._consumables.get( element );
 
 		if ( elementConsumables !== undefined ) {
-			if ( element.is( 'text' ) || element.is( 'documentFragment' ) ) {
+			if ( element.is( '$text' ) || element.is( 'documentFragment' ) ) {
 				// For text nodes and document fragments - set consumable to true.
 				this._consumables.set( element, true );
 			} else {
@@ -287,7 +287,7 @@ export default class ViewConsumable {
 			instance = new ViewConsumable( from );
 		}
 
-		if ( from.is( 'text' ) ) {
+		if ( from.is( '$text' ) ) {
 			instance.add( from );
 
 			return instance;

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

@@ -228,7 +228,7 @@ export function stringify( node, selectionOrPositionOrRange = null, markers = nu
 
 	downcastDispatcher.on( 'insert:$text', insertText() );
 	downcastDispatcher.on( 'attribute', ( evt, data, conversionApi ) => {
-		if ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection || data.item.is( 'textProxy' ) ) {
+		if ( data.item instanceof ModelSelection || data.item instanceof DocumentSelection || data.item.is( '$textProxy' ) ) {
 			const converter = wrap( ( modelAttributeValue, viewWriter ) => {
 				return viewWriter.createAttributeElement(
 					'model-text-with-attributes',

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

@@ -452,7 +452,7 @@ class RangeParser {
 			}
 		}
 
-		if ( node.is( 'text' ) ) {
+		if ( node.is( '$text' ) ) {
 			const regexp = new RegExp(
 				`[${ TEXT_RANGE_START_TOKEN }${ TEXT_RANGE_END_TOKEN }\\${ ELEMENT_RANGE_END_TOKEN }\\${ ELEMENT_RANGE_START_TOKEN }]`,
 				'g'
@@ -688,7 +688,7 @@ class ViewStringify {
 			}
 		}
 
-		if ( root.is( 'text' ) ) {
+		if ( root.is( '$text' ) ) {
 			callback( this._stringifyTextRanges( root ) );
 		}
 	}

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

@@ -1039,7 +1039,7 @@ function _getChildrenSnapshot( children ) {
 	const snapshot = [];
 
 	for ( const child of children ) {
-		if ( child.is( 'text' ) ) {
+		if ( child.is( '$text' ) ) {
 			for ( let i = 0; i < child.data.length; i++ ) {
 				snapshot.push( {
 					name: '$text',

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

@@ -335,7 +335,7 @@ export default class DocumentFragment {
 	// @if CK_DEBUG_ENGINE //	for ( const child of this.getChildren() ) {
 	// @if CK_DEBUG_ENGINE //		string += '\n';
 
-	// @if CK_DEBUG_ENGINE //		if ( child.is( 'text' ) ) {
+	// @if CK_DEBUG_ENGINE //		if ( child.is( '$text' ) ) {
 	// @if CK_DEBUG_ENGINE //			const textAttrs = stringifyMap( child._attrs );
 
 	// @if CK_DEBUG_ENGINE //			string += '\t'.repeat( 1 );

+ 4 - 6
packages/ckeditor5-engine/src/model/element.js

@@ -104,21 +104,19 @@ export default class Element extends Node {
 	 * Assuming that the object being checked is an element, you can also check its
 	 * {@link module:engine/model/element~Element#name name}:
 	 *
-	 *		element.is( 'image' ); // -> true if this is an <image> element
+	 *		element.is( 'element', 'image' ); // -> true if this is an <image> element
 	 *		element.is( 'element', 'image' ); // -> same as above
-	 *		text.is( 'image' ); -> false
+	 *		text.is( 'element', 'image' ); -> false
 	 *
 	 * {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
 	is( type, name = null ) {
 		if ( !name ) {
 			return type === 'element' || type === 'model:element' ||
-				type === this.name || type === 'model:' + this.name ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
 				type === 'node' || type === 'model:node';
 		}
@@ -381,7 +379,7 @@ export default class Element extends Node {
 	// @if CK_DEBUG_ENGINE // 	for ( const child of this.getChildren() ) {
 	// @if CK_DEBUG_ENGINE // 		string += '\n';
 
-	// @if CK_DEBUG_ENGINE // 		if ( child.is( 'text' ) ) {
+	// @if CK_DEBUG_ENGINE // 		if ( child.is( '$text' ) ) {
 	// @if CK_DEBUG_ENGINE // 			const textAttrs = convertMapToTags( child._attrs );
 
 	// @if CK_DEBUG_ENGINE // 			string += '\t'.repeat( level + 1 );

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

@@ -573,7 +573,7 @@ export default class Model {
 		}
 
 		for ( const item of range.getItems() ) {
-			if ( item.is( 'textProxy' ) ) {
+			if ( item.is( '$textProxy' ) ) {
 				if ( !ignoreWhitespaces ) {
 					return true;
 				} else if ( item.data.search( /\S/ ) !== -1 ) {

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

@@ -406,7 +406,7 @@ export default class Node {
 	 *
 	 * By using this method it is also possible to check a name of an element:
 	 *
-	 *		imageElement.is( 'image' ); // -> true
+	 *		imageElement.is( 'element', 'image' ); // -> true
 	 *		imageElement.is( 'element', 'image' ); // -> same as above
 	 *		imageElement.is( 'model:element', 'image' ); // -> same as above, but more precise
 	 *
@@ -427,7 +427,7 @@ export default class Node {
 	 * * {@link module:engine/model/textproxy~TextProxy#is `TextProxy#is()`}
 	 *
 	 * @method #is
-	 * @param {String} type
+	 * @param {String} type Type to check.
 	 * @returns {Boolean}
 	 */
 	is( type ) {

+ 2 - 2
packages/ckeditor5-engine/src/model/operation/utils.js

@@ -143,7 +143,7 @@ export function _setAttribute( range, key, value ) {
 		// Iterator will return `TextProxy` instances but we know that those text proxies will
 		// always represent full text nodes (this is guaranteed thanks to splitting we did before).
 		// So, we can operate on those text proxies' text nodes.
-		const node = item.is( 'textProxy' ) ? item.textNode : item;
+		const node = item.is( '$textProxy' ) ? item.textNode : item;
 
 		if ( value !== null ) {
 			node._setAttribute( key, value );
@@ -219,7 +219,7 @@ function _mergeNodesAtIndex( element, index ) {
 	const nodeAfter = element.getChild( index );
 
 	// Check if both of those nodes are text objects with same attributes.
-	if ( nodeBefore && nodeAfter && nodeBefore.is( 'text' ) && nodeAfter.is( 'text' ) && _haveSameAttributes( nodeBefore, nodeAfter ) ) {
+	if ( nodeBefore && nodeAfter && nodeBefore.is( '$text' ) && nodeAfter.is( '$text' ) && _haveSameAttributes( nodeBefore, nodeAfter ) ) {
 		// Append text of text node after index to the before one.
 		const mergedNode = new Text( nodeBefore.data + nodeAfter.data, nodeBefore.getAttributes() );
 

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

@@ -173,7 +173,7 @@ export default class Position {
 			}
 		}
 
-		if ( parent.is( 'text' ) ) {
+		if ( parent.is( '$text' ) ) {
 			/**
 			 * The position's path is incorrect. This means that a position does not point to
 			 * a correct place in the tree and hence, some of its methods and getters cannot work correctly.
@@ -1103,7 +1103,7 @@ export default class Position {
 export function getTextNodeAtPosition( position, positionParent ) {
 	const node = positionParent.getChild( positionParent.offsetToIndex( position.offset ) );
 
-	if ( node && node.is( 'text' ) && node.startOffset < position.offset ) {
+	if ( node && node.is( '$text' ) && node.startOffset < position.offset ) {
 		return node;
 	}
 

+ 1 - 5
packages/ckeditor5-engine/src/model/rootelement.js

@@ -68,14 +68,11 @@ export default class RootElement extends Element {
 	 * Assuming that the object being checked is an element, you can also check its
 	 * {@link module:engine/model/element~Element#name name}:
 	 *
-	 *		rootElement.is( '$root' ); // -> true if this is a $root element
 	 *		rootElement.is( 'rootElement', '$root' ); // -> same as above
-	 *		text.is( '$root' ); -> false
 	 *
 	 * {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
@@ -84,7 +81,6 @@ export default class RootElement extends Element {
 			return type === 'rootElement' || type === 'model:rootElement' ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
 				type === 'element' || type === 'model:element' ||
-				type === this.name || type === 'model:' + this.name ||
 				type === 'node' || type === 'model:node';
 		}
 

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

@@ -186,7 +186,7 @@ export default class Schema {
 
 		if ( typeof item == 'string' ) {
 			itemName = item;
-		} else if ( item.is && ( item.is( 'text' ) || item.is( 'textProxy' ) ) ) {
+		} else if ( item.is && ( item.is( '$text' ) || item.is( '$textProxy' ) ) ) {
 			itemName = '$text';
 		}
 		// Element or module:engine/model/schema~SchemaContextItem.
@@ -774,7 +774,7 @@ export default class Schema {
 	removeDisallowedAttributes( nodes, writer ) {
 		for ( const node of nodes ) {
 			// When node is a `Text` it has no children, so just filter it out.
-			if ( node.is( 'text' ) ) {
+			if ( node.is( '$text' ) ) {
 				removeDisallowedAttributeFromNode( this, node, writer );
 			}
 			// In a case of `Element` iterates through positions between nodes inside this element

+ 10 - 6
packages/ckeditor5-engine/src/model/text.js

@@ -67,22 +67,26 @@ export default class Text extends Node {
 	/**
 	 * Checks whether this object is of the given.
 	 *
-	 *		text.is( 'text' ); // -> true
+	 *		text.is( '$text' ); // -> true
 	 *		text.is( 'node' ); // -> true
-	 *		text.is( 'model:text' ); // -> true
+	 *		text.is( 'model:$text' ); // -> true
 	 *		text.is( 'model:node' ); // -> true
 	 *
-	 *		text.is( 'view:text' ); // -> false
+	 *		text.is( 'view:$text' ); // -> false
 	 *		text.is( 'documentSelection' ); // -> false
 	 *
 	 * {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * **Note:** Until version 20.0.0 this method wasn't accepting `'$text'` type. The legacy `'text'` type is still
+	 * accepted for backward compatibility.
+	 *
+	 * @param {String} type Type to check.
 	 * @returns {Boolean}
 	 */
 	is( type ) {
-		return type === 'text' || type === 'model:text' ||
+		return type === '$text' || type === 'model:$text' ||
+			// This are legacy values kept for backward compatibility.
+			type === 'text' || type === 'model:text' ||
 			// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
 			type === 'node' || type === 'model:node';
 	}

+ 10 - 5
packages/ckeditor5-engine/src/model/textproxy.js

@@ -166,19 +166,24 @@ export default class TextProxy {
 	/**
 	 * Checks whether this object is of the given.
 	 *
-	 *		textProxy.is( 'textProxy' ); // -> true
-	 *		textProxy.is( 'model:textProxy' ); // -> true
+	 *		textProxy.is( '$textProxy' ); // -> true
+	 *		textProxy.is( 'model:$textProxy' ); // -> true
 	 *
-	 *		textProxy.is( 'view:textProxy' ); // -> false
+	 *		textProxy.is( 'view:$textProxy' ); // -> false
 	 *		textProxy.is( 'range' ); // -> false
 	 *
 	 * {@link module:engine/model/node~Node#is Check the entire list of model objects} which implement the `is()` method.
 	 *
-	 * @param {String} type
+	 * **Note:** Until version 20.0.0 this method wasn't accepting `'$textProxy'` type. The legacy `'textProxt'` type is still
+	 * accepted for backward compatibility.
+	 *
+	 * @param {String} type Type to check.
 	 * @returns {Boolean}
 	 */
 	is( type ) {
-		return type === 'textProxy' || type === 'model:textProxy';
+		return type === '$textProxy' || type === 'model:$textProxy' ||
+			// This are legacy values kept for backward compatibility.
+			type === 'textProxy' || type === 'model:textProxy';
 	}
 
 	/**

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

@@ -70,7 +70,7 @@ export default function getSelectedContent( model, selection ) {
 
 		// Clone the whole contents.
 		for ( const item of flatSubtreeRange.getItems( { shallow: true } ) ) {
-			if ( item.is( 'textProxy' ) ) {
+			if ( item.is( '$textProxy' ) ) {
 				writer.appendText( item.data, item.getAttributes(), frag );
 			} else {
 				writer.append( writer.cloneElement( item, true ), frag );

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

@@ -173,7 +173,7 @@ function getCorrectWordBreakPosition( walker, isForward ) {
 			const nextNode = isForward ? walker.position.nodeAfter : walker.position.nodeBefore;
 
 			// Scan only text nodes. Ignore inline elements (like `<softBreak>`).
-			if ( nextNode && nextNode.is( 'text' ) ) {
+			if ( nextNode && nextNode.is( '$text' ) ) {
 				// Check boundary char of an adjacent text node.
 				const boundaryChar = nextNode.data.charAt( isForward ? 0 : nextNode.data.length - 1 );
 

+ 3 - 5
packages/ckeditor5-engine/src/view/attributeelement.js

@@ -145,14 +145,13 @@ export default class AttributeElement extends Element {
 	 * Assuming that the object being checked is an attribute element, you can also check its
 	 * {@link module:engine/view/attributeelement~AttributeElement#name name}:
 	 *
-	 *		attributeElement.is( 'b' ); // -> true if this is a bold element
+	 *		attributeElement.is( 'element', 'b' ); // -> true if this is a bold element
 	 *		attributeElement.is( 'attributeElement', 'b' ); // -> same as above
-	 *		text.is( 'b' ); -> false
+	 *		text.is( 'element', 'b' ); -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
@@ -160,7 +159,6 @@ export default class AttributeElement extends Element {
 		if ( !name ) {
 			return type === 'attributeElement' || type === 'view:attributeElement' ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
-				type === this.name || type === 'view:' + this.name ||
 				type === 'element' || type === 'view:element' ||
 				type === 'node' || type === 'view:node';
 		} else {

+ 3 - 5
packages/ckeditor5-engine/src/view/containerelement.js

@@ -71,14 +71,13 @@ export default class ContainerElement extends Element {
 	 * Assuming that the object being checked is a container element, you can also check its
 	 * {@link module:engine/view/containerelement~ContainerElement#name name}:
 	 *
-	 *		containerElement.is( 'div' ); // -> true if this is a div container element
+	 *		containerElement.is( 'element', 'div' ); // -> true if this is a div container element
 	 *		containerElement.is( 'contaienrElement', 'div' ); // -> same as above
-	 *		text.is( 'div' ); -> false
+	 *		text.is( 'element', 'div' ); -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
@@ -86,7 +85,6 @@ export default class ContainerElement extends Element {
 		if ( !name ) {
 			return type === 'containerElement' || type === 'view:containerElement' ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
-				type === this.name || type === 'view:' + this.name ||
 				type === 'element' || type === 'view:element' ||
 				type === 'node' || type === 'view:node';
 		} else {

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

@@ -224,7 +224,7 @@ export default class DocumentFragment {
 	// @if CK_DEBUG_ENGINE //	let string = 'ViewDocumentFragment: [';
 
 	// @if CK_DEBUG_ENGINE //	for ( const child of this.getChildren() ) {
-	// @if CK_DEBUG_ENGINE //		if ( child.is( 'text' ) ) {
+	// @if CK_DEBUG_ENGINE //		if ( child.is( '$text' ) ) {
 	// @if CK_DEBUG_ENGINE //			string += '\n' + '\t'.repeat( 1 ) + child.data;
 	// @if CK_DEBUG_ENGINE //		} else {
 	// @if CK_DEBUG_ENGINE //			string += '\n' + child.printTree( 1 );

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

@@ -201,7 +201,7 @@ export default class DomConverter {
 	 * @returns {Node|DocumentFragment} Converted node or DocumentFragment.
 	 */
 	viewToDom( viewNode, domDocument, options = {} ) {
-		if ( viewNode.is( 'text' ) ) {
+		if ( viewNode.is( '$text' ) ) {
 			const textData = this._processDataFromViewText( viewNode );
 
 			return domDocument.createTextNode( textData );
@@ -317,7 +317,7 @@ export default class DomConverter {
 	viewPositionToDom( viewPosition ) {
 		const viewParent = viewPosition.parent;
 
-		if ( viewParent.is( 'text' ) ) {
+		if ( viewParent.is( '$text' ) ) {
 			const domParent = this.findCorrespondingDomText( viewParent );
 
 			if ( !domParent ) {
@@ -348,7 +348,7 @@ export default class DomConverter {
 			} else {
 				const nodeBefore = viewPosition.nodeBefore;
 
-				domBefore = nodeBefore.is( 'text' ) ?
+				domBefore = nodeBefore.is( '$text' ) ?
 					this.findCorrespondingDomText( nodeBefore ) :
 					this.mapViewToDom( viewPosition.nodeBefore );
 
@@ -1135,11 +1135,11 @@ export default class DomConverter {
 				return null;
 			}
 			// <br> found – it works like a block boundary, so do not scan further.
-			else if ( value.item.is( 'br' ) ) {
+			else if ( value.item.is( 'element', 'br' ) ) {
 				return null;
 			}
 			// Found a text node in the same container element.
-			else if ( value.item.is( 'textProxy' ) ) {
+			else if ( value.item.is( '$textProxy' ) ) {
 				return value.item;
 			}
 		}

+ 10 - 10
packages/ckeditor5-engine/src/view/downcastwriter.js

@@ -529,7 +529,7 @@ export default class DowncastWriter {
 		const positionParent = position.parent;
 
 		// When inside text node - nothing to merge.
-		if ( positionParent.is( 'text' ) ) {
+		if ( positionParent.is( '$text' ) ) {
 			return position;
 		}
 
@@ -553,7 +553,7 @@ export default class DowncastWriter {
 		}
 
 		// When position is between two text nodes.
-		if ( nodeBefore.is( 'text' ) && nodeAfter.is( 'text' ) ) {
+		if ( nodeBefore.is( '$text' ) && nodeAfter.is( '$text' ) ) {
 			return mergeTextNodes( nodeBefore, nodeAfter );
 		}
 		// When position is between two same attribute elements.
@@ -749,7 +749,7 @@ export default class DowncastWriter {
 				// Create range on this element.
 				rangeToRemove = Range._createOn( item );
 				// When range starts inside Text or TextProxy element.
-			} else if ( !current.nextPosition.isAfter( range.start ) && item.is( 'textProxy' ) ) {
+			} else if ( !current.nextPosition.isAfter( range.start ) && item.is( '$textProxy' ) ) {
 				// We need to check if parent of this text matches to given element.
 				const parentElement = item.getAncestors().find( ancestor => {
 					return ancestor.is( 'element' ) && element.isSimilar( ancestor );
@@ -1104,7 +1104,7 @@ export default class DowncastWriter {
 
 		while ( i < endOffset ) {
 			const child = parent.getChild( i );
-			const isText = child.is( 'text' );
+			const isText = child.is( '$text' );
 			const isAttribute = child.is( 'attributeElement' );
 			const isEmpty = child.is( 'emptyElement' );
 			const isUI = child.is( 'uiElement' );
@@ -1334,7 +1334,7 @@ export default class DowncastWriter {
 		}
 
 		// When position is inside text node - break it and place new position between two text nodes.
-		if ( position.parent.is( 'text' ) ) {
+		if ( position.parent.is( '$text' ) ) {
 			position = breakTextNode( position );
 		}
 
@@ -1573,7 +1573,7 @@ export default class DowncastWriter {
 		}
 
 		// There are no attributes to break and text nodes breaking is not forced.
-		if ( !forceSplitText && positionParent.is( 'text' ) && isContainerOrFragment( positionParent.parent ) ) {
+		if ( !forceSplitText && positionParent.is( '$text' ) && isContainerOrFragment( positionParent.parent ) ) {
 			return position.clone();
 		}
 
@@ -1583,7 +1583,7 @@ export default class DowncastWriter {
 		}
 
 		// Break text and start again in new position.
-		if ( positionParent.is( 'text' ) ) {
+		if ( positionParent.is( '$text' ) ) {
 			return this._breakAttributes( breakTextNode( position ), forceSplitText );
 		}
 
@@ -1778,13 +1778,13 @@ function shouldABeOutsideB( a, b ) {
 function movePositionToTextNode( position ) {
 	const nodeBefore = position.nodeBefore;
 
-	if ( nodeBefore && nodeBefore.is( 'text' ) ) {
+	if ( nodeBefore && nodeBefore.is( '$text' ) ) {
 		return new Position( nodeBefore, nodeBefore.data.length );
 	}
 
 	const nodeAfter = position.nodeAfter;
 
-	if ( nodeAfter && nodeAfter.is( 'text' ) ) {
+	if ( nodeAfter && nodeAfter.is( '$text' ) ) {
 		return new Position( nodeAfter, 0 );
 	}
 
@@ -1866,7 +1866,7 @@ function validateNodesToInsert( nodes, errorContext ) {
 			throw new CKEditorError( 'view-writer-insert-invalid-node', errorContext );
 		}
 
-		if ( !node.is( 'text' ) ) {
+		if ( !node.is( '$text' ) ) {
 			validateNodesToInsert( node.getChildren(), errorContext );
 		}
 	}

+ 3 - 5
packages/ckeditor5-engine/src/view/editableelement.js

@@ -83,14 +83,13 @@ export default class EditableElement extends ContainerElement {
 	 * Assuming that the object being checked is an editbale element, you can also check its
 	 * {@link module:engine/view/editableelement~EditableElement#name name}:
 	 *
-	 *		editableElement.is( 'div' ); // -> true if this is a div element
+	 *		editableElement.is( 'element', 'div' ); // -> true if this is a div element
 	 *		editableElement.is( 'editableElement', 'div' ); // -> same as above
-	 *		text.is( 'div' ); -> false
+	 *		text.is( 'element', 'div' ); -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
@@ -99,7 +98,6 @@ export default class EditableElement extends ContainerElement {
 			return type === 'editableElement' || type === 'view:editableElement' ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
 				type === 'containerElement' || type === 'view:containerElement' ||
-				type === this.name || type === 'view:' + this.name ||
 				type === 'element' || type === 'view:element' ||
 				type === 'node' || type === 'view:node';
 		} else {

+ 5 - 7
packages/ckeditor5-engine/src/view/element.js

@@ -164,21 +164,19 @@ export default class Element extends Node {
 	 * Assuming that the object being checked is an element, you can also check its
 	 * {@link module:engine/view/element~Element#name name}:
 	 *
-	 *		element.is( 'img' ); // -> true if this is an <img> element
+	 *		element.is( 'element', 'img' ); // -> true if this is an <img> element
 	 *		element.is( 'element', 'img' ); // -> same as above
-	 *		text.is( 'img' ); -> false
+	 *		text.is( 'element', 'img' ); -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
 	is( type, name = null ) {
 		if ( !name ) {
-			return type === this.name || type === 'view:' + this.name ||
-				type === 'element' || type === 'view:element' ||
+			return type === 'element' || type === 'view:element' ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
 				type === 'node' || type === 'view:node';
 		} else {
@@ -834,7 +832,7 @@ export default class Element extends Node {
 	// @if CK_DEBUG_ENGINE //	string += '\t'.repeat( level ) + `<${ this.name }${ convertMapToTags( this.getAttributes() ) }>`;
 
 	// @if CK_DEBUG_ENGINE //	for ( const child of this.getChildren() ) {
-	// @if CK_DEBUG_ENGINE //		if ( child.is( 'text' ) ) {
+	// @if CK_DEBUG_ENGINE //		if ( child.is( '$text' ) ) {
 	// @if CK_DEBUG_ENGINE //			string += '\n' + '\t'.repeat( level + 1 ) + child.data;
 	// @if CK_DEBUG_ENGINE //		} else {
 	// @if CK_DEBUG_ENGINE //			string += '\n' + child.printTree( level + 1 );

+ 3 - 5
packages/ckeditor5-engine/src/view/emptyelement.js

@@ -62,14 +62,13 @@ export default class EmptyElement extends Element {
 	 * Assuming that the object being checked is an empty element, you can also check its
 	 * {@link module:engine/view/emptyelement~EmptyElement#name name}:
 	 *
-	 *		emptyElement.is( 'img' ); // -> true if this is a img element
+	 *		emptyElement.is( 'element', 'img' ); // -> true if this is a img element
 	 *		emptyElement.is( 'emptyElement', 'img' ); // -> same as above
-	 *		text.is( 'img' ); -> false
+	 *		text.is( 'element', 'img' ); -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
@@ -77,7 +76,6 @@ export default class EmptyElement extends Element {
 		if ( !name ) {
 			return type === 'emptyElement' || type === 'view:emptyElement' ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
-				type === this.name || type === 'view:' + this.name ||
 				type === 'element' || type === 'view:element' ||
 				type === 'node' || type === 'view:node';
 		} else {

+ 2 - 3
packages/ckeditor5-engine/src/view/node.js

@@ -312,8 +312,7 @@ export default class Node {
 	 *
 	 * By using this method it is also possible to check a name of an element:
 	 *
-	 *		imgElement.is( 'img' ); // -> true
-	 *		imgElement.is( 'element', 'img' ); // -> same as above
+	 *		imgElement.is( 'element', 'img' ); // -> true
 	 *		imgElement.is( 'view:element', 'img' ); // -> same as above, but more precise
 	 *
 	 * The list of view objects which implement the `is()` method:
@@ -335,7 +334,7 @@ export default class Node {
 	 * * {@link module:engine/view/uielement~UIElement#is `UIElement#is()`}
 	 *
 	 * @method #is
-	 * @param {String} type
+	 * @param {String} type Type to check.
 	 * @returns {Boolean}
 	 */
 	is( type ) {

+ 1 - 1
packages/ckeditor5-engine/src/view/observer/mutationobserver.js

@@ -264,7 +264,7 @@ export default class MutationObserver extends Observer {
 				return true;
 			}
 			// Texts.
-			else if ( child1.is( 'text' ) && child2.is( 'text' ) ) {
+			else if ( child1.is( '$text' ) && child2.is( '$text' ) ) {
 				return child1.data === child2.data;
 			}
 

+ 6 - 6
packages/ckeditor5-engine/src/view/position.js

@@ -59,7 +59,7 @@ export default class Position {
 	 * @type {module:engine/view/node~Node|null}
 	 */
 	get nodeAfter() {
-		if ( this.parent.is( 'text' ) ) {
+		if ( this.parent.is( '$text' ) ) {
 			return null;
 		}
 
@@ -74,7 +74,7 @@ export default class Position {
 	 * @type {module:engine/view/node~Node|null}
 	 */
 	get nodeBefore() {
-		if ( this.parent.is( 'text' ) ) {
+		if ( this.parent.is( '$text' ) ) {
 			return null;
 		}
 
@@ -98,7 +98,7 @@ export default class Position {
 	 * @type {Boolean}
 	 */
 	get isAtEnd() {
-		const endOffset = this.parent.is( 'text' ) ? this.parent.data.length : this.parent.childCount;
+		const endOffset = this.parent.is( '$text' ) ? this.parent.data.length : this.parent.childCount;
 
 		return this.offset === endOffset;
 	}
@@ -346,7 +346,7 @@ export default class Position {
 			const node = itemOrPosition;
 
 			if ( offset == 'end' ) {
-				offset = node.is( 'text' ) ? node.data.length : node.childCount;
+				offset = node.is( '$text' ) ? node.data.length : node.childCount;
 			} else if ( offset == 'before' ) {
 				return this._createBefore( node );
 			} else if ( offset == 'after' ) {
@@ -378,7 +378,7 @@ export default class Position {
 	 */
 	static _createAfter( item ) {
 		// TextProxy is not a instance of Node so we need do handle it in specific way.
-		if ( item.is( 'textProxy' ) ) {
+		if ( item.is( '$textProxy' ) ) {
 			return new Position( item.textNode, item.offsetInText + item.data.length );
 		}
 
@@ -404,7 +404,7 @@ export default class Position {
 	 */
 	static _createBefore( item ) {
 		// TextProxy is not a instance of Node so we need do handle it in specific way.
-		if ( item.is( 'textProxy' ) ) {
+		if ( item.is( '$textProxy' ) ) {
 			return new Position( item.textNode, item.offsetInText );
 		}
 

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

@@ -113,11 +113,11 @@ export default class Range {
 		let end = this.end.getLastMatchingPosition( enlargeTrimSkip );
 
 		// Fix positions, in case if they are in Text node.
-		if ( start.parent.is( 'text' ) && start.isAtStart ) {
+		if ( start.parent.is( '$text' ) && start.isAtStart ) {
 			start = Position._createBefore( start.parent );
 		}
 
-		if ( end.parent.is( 'text' ) && end.isAtEnd ) {
+		if ( end.parent.is( '$text' ) && end.isAtEnd ) {
 			end = Position._createAfter( end.parent );
 		}
 
@@ -153,11 +153,11 @@ export default class Range {
 		const nodeBeforeEnd = end.nodeBefore;
 
 		// Because TreeWalker prefers positions next to text node, we need to move them manually into these text nodes.
-		if ( nodeAfterStart && nodeAfterStart.is( 'text' ) ) {
+		if ( nodeAfterStart && nodeAfterStart.is( '$text' ) ) {
 			start = new Position( nodeAfterStart, 0 );
 		}
 
-		if ( nodeBeforeEnd && nodeBeforeEnd.is( 'text' ) ) {
+		if ( nodeBeforeEnd && nodeBeforeEnd.is( '$text' ) ) {
 			end = new Position( nodeBeforeEnd, nodeBeforeEnd.data.length );
 		}
 
@@ -359,11 +359,11 @@ export default class Range {
 		// These are basically the same range, only the difference is if the range position is at
 		// at the end/at the beginning of a text node or just before/just after the text node.
 		//
-		if ( this.start.parent.is( 'text' ) && this.start.isAtEnd && this.start.parent.nextSibling ) {
+		if ( this.start.parent.is( '$text' ) && this.start.isAtEnd && this.start.parent.nextSibling ) {
 			nodeAfterStart = this.start.parent.nextSibling;
 		}
 
-		if ( this.end.parent.is( 'text' ) && this.end.isAtStart && this.end.parent.previousSibling ) {
+		if ( this.end.parent.is( '$text' ) && this.end.isAtStart && this.end.parent.previousSibling ) {
 			nodeBeforeEnd = this.end.parent.previousSibling;
 		}
 
@@ -517,7 +517,7 @@ export default class Range {
 	 * @returns {module:engine/view/range~Range}
 	 */
 	static _createOn( item ) {
-		const size = item.is( 'textProxy' ) ? item.offsetSize : 1;
+		const size = item.is( '$textProxy' ) ? item.offsetSize : 1;
 
 		return this._createFromPositionAndShift( Position._createBefore( item ), size );
 	}

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

@@ -332,7 +332,7 @@ export default class Renderer {
 	_getInlineFillerPosition() {
 		const firstPos = this.selection.getFirstPosition();
 
-		if ( firstPos.parent.is( 'text' ) ) {
+		if ( firstPos.parent.is( '$text' ) ) {
 			return ViewPosition._createBefore( this.selection.getFirstPosition().parent );
 		} else {
 			return firstPos;
@@ -659,7 +659,7 @@ export default class Renderer {
 			return;
 		}
 
-		if ( viewNode.is( 'text' ) ) {
+		if ( viewNode.is( '$text' ) ) {
 			this.markedTexts.add( viewNode );
 		} else if ( viewNode.is( 'element' ) ) {
 			for ( const child of viewNode.getChildren() ) {

+ 3 - 5
packages/ckeditor5-engine/src/view/rooteditableelement.js

@@ -55,14 +55,13 @@ export default class RootEditableElement extends EditableElement {
 	 * Assuming that the object being checked is a root editable element, you can also check its
 	 * {@link module:engine/view/rooteditableelement~RootEditableElement#name name}:
 	 *
-	 *		rootEditableElement.is( 'div' ); // -> true if this is a div root editable element
+	 *		rootEditableElement.is( 'element', 'div' ); // -> true if this is a div root editable element
 	 *		rootEditableElement.is( 'rootElement', 'div' ); // -> same as above
-	 *		text.is( 'div' ); -> false
+	 *		text.is( 'element', 'div' ); -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
@@ -72,7 +71,6 @@ export default class RootEditableElement extends EditableElement {
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
 				type === 'editableElement' || type === 'view:editableElement' ||
 				type === 'containerElement' || type === 'view:containerElement' ||
-				type === this.name || type === 'view:' + this.name ||
 				type === 'element' || type === 'view:element' ||
 				type === 'node' || type === 'view:node';
 		} else {

+ 10 - 5
packages/ckeditor5-engine/src/view/text.js

@@ -45,22 +45,27 @@ export default class Text extends Node {
 	/**
 	 * Checks whether this object is of the given type.
 	 *
-	 *		text.is( 'text' ); // -> true
+	 *		text.is( '$text' ); // -> true
 	 *		text.is( 'node' ); // -> true
-	 *		text.is( 'view:text' ); // -> true
+	 *		text.is( 'view:$text' ); // -> true
 	 *		text.is( 'view:node' ); // -> true
 	 *
-	 *		text.is( 'model:text' ); // -> false
+	 *		text.is( 'model:$text' ); // -> false
 	 *		text.is( 'element' ); // -> false
 	 *		text.is( 'range' ); // -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type
+	 * **Note:** Until version 20.0.0 this method wasn't accepting `'$text'` type. The legacy `'text'` type is still
+	 * accepted for backward compatibility.
+	 *
+	 * @param {String} type Type to check.
 	 * @returns {Boolean}
 	 */
 	is( type ) {
-		return type === 'text' || type === 'view:text' ||
+		return type === '$text' || type === 'view:$text' ||
+			// This are legacy values kept for backward compatibility.
+			type === 'text' || type === 'view:text' ||
 			// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
 			type === 'node' || type === 'view:node';
 	}

+ 10 - 5
packages/ckeditor5-engine/src/view/textproxy.js

@@ -143,20 +143,25 @@ export default class TextProxy {
 	/**
 	 * Checks whether this object is of the given type.
 	 *
-	 *		textProxy.is( 'textProxy' ); // -> true
-	 *		textProxy.is( 'view:textProxy' ); // -> true
+	 *		textProxy.is( '$textProxy' ); // -> true
+	 *		textProxy.is( 'view:$textProxy' ); // -> true
 	 *
-	 *		textProxy.is( 'model:textProxy' ); // -> false
+	 *		textProxy.is( 'model:$textProxy' ); // -> false
 	 *		textProxy.is( 'element' ); // -> false
 	 *		textProxy.is( 'range' ); // -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type
+	 * **Note:** Until version 20.0.0 this method wasn't accepting `'$textProxy'` type. The legacy `'textProxy'` type is still
+	 * accepted for backward compatibility.
+	 *
+	 * @param {String} type Type to check.
 	 * @returns {Boolean}
 	 */
 	is( type ) {
-		return type === 'textProxy' || type === 'view:textProxy';
+		return type === '$textProxy' || type === 'view:$textProxy' ||
+			// This are legacy values kept for backward compatibility.
+			type === 'textProxy' || type === 'view:textProxy';
 	}
 
 	/**

+ 3 - 5
packages/ckeditor5-engine/src/view/uielement.js

@@ -75,14 +75,13 @@ export default class UIElement extends Element {
 	 * Assuming that the object being checked is an ui element, you can also check its
 	 * {@link module:engine/view/uielement~UIElement#name name}:
 	 *
-	 *		uiElement.is( 'span' ); // -> true if this is a span ui element
+	 *		uiElement.is( 'element', 'span' ); // -> true if this is a span ui element
 	 *		uiElement.is( 'uiElement', 'span' ); // -> same as above
-	 *		text.is( 'span' ); -> false
+	 *		text.is( 'element', 'span' ); -> false
 	 *
 	 * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.
 	 *
-	 * @param {String} type Type to check when `name` parameter is present.
-	 * Otherwise, it acts like the `name` parameter.
+	 * @param {String} type Type to check.
 	 * @param {String} [name] Element name.
 	 * @returns {Boolean}
 	 */
@@ -90,7 +89,6 @@ export default class UIElement extends Element {
 		if ( !name ) {
 			return type === 'uiElement' || type === 'view:uiElement' ||
 				// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.
-				type === this.name || type === 'view:' + this.name ||
 				type === 'element' || type === 'view:element' ||
 				type === 'node' || type === 'view:node';
 		} else {

+ 3 - 3
packages/ckeditor5-engine/tests/conversion/conversion.js

@@ -334,7 +334,7 @@ describe( 'Conversion', () => {
 						},
 						// Duplicates the `x-bold` from above to test if only one attribute would be converted.
 						// It should not convert to both bold & x-bold.
-						viewElement => viewElement.is( 'x-bold' ) ? { name: 'x-bold' } : null
+						viewElement => viewElement.is( 'element', 'x-bold' ) ? { name: 'x-bold' } : null
 					]
 				} );
 
@@ -426,7 +426,7 @@ describe( 'Conversion', () => {
 
 							const size = Number( match[ 1 ] );
 
-							if ( viewElement.is( 'span' ) && size > 10 ) {
+							if ( viewElement.is( 'element', 'span' ) && size > 10 ) {
 								return { name: true, style: [ 'font-size' ] };
 							}
 
@@ -447,7 +447,7 @@ describe( 'Conversion', () => {
 
 							const size = Number( match[ 1 ] );
 
-							if ( viewElement.is( 'span' ) && size < 10 ) {
+							if ( viewElement.is( 'element', 'span' ) && size < 10 ) {
 								return { name: true, style: [ 'font-size' ] };
 							}
 

+ 1 - 1
packages/ckeditor5-engine/tests/conversion/downcasthelpers.js

@@ -2758,7 +2758,7 @@ describe( 'downcast selection converters', () => {
 				for ( const range of selection.getRanges() ) {
 					const node = range.start.parent;
 
-					if ( !!node && node.is( 'td' ) ) {
+					if ( !!node && node.is( 'element', 'td' ) ) {
 						conversionApi.consumable.consume( selection, 'selection' );
 
 						const viewNode = conversionApi.mapper.toViewElement( node );

+ 2 - 2
packages/ckeditor5-engine/tests/model/documentfragment.js

@@ -75,8 +75,8 @@ describe( 'DocumentFragment', () => {
 
 		it( 'should return false for other values', () => {
 			expect( frag.is( 'node' ) ).to.be.false;
-			expect( frag.is( 'text' ) ).to.be.false;
-			expect( frag.is( 'textProxy' ) ).to.be.false;
+			expect( frag.is( '$text' ) ).to.be.false;
+			expect( frag.is( '$textProxy' ) ).to.be.false;
 			expect( frag.is( 'element' ) ).to.be.false;
 			expect( frag.is( 'rootElement' ) ).to.be.false;
 			expect( frag.is( 'view:documentFragment' ) ).to.be.false;

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

@@ -719,8 +719,8 @@ describe( 'DocumentSelection', () => {
 		it( 'should return false for other values', () => {
 			expect( selection.is( 'node' ) ).to.be.false;
 			expect( selection.is( 'model:node' ) ).to.be.false;
-			expect( selection.is( 'text' ) ).to.be.false;
-			expect( selection.is( 'textProxy' ) ).to.be.false;
+			expect( selection.is( '$text' ) ).to.be.false;
+			expect( selection.is( '$textProxy' ) ).to.be.false;
 			expect( selection.is( 'element' ) ).to.be.false;
 			expect( selection.is( 'element', 'paragraph' ) ).to.be.false;
 			expect( selection.is( 'rootElement' ) ).to.be.false;

+ 7 - 6
packages/ckeditor5-engine/tests/model/element.js

@@ -52,24 +52,25 @@ describe( 'Element', () => {
 			expect( element.is( 'model:element' ) ).to.be.true;
 			expect( element.is( 'element', 'paragraph' ) ).to.be.true;
 			expect( element.is( 'model:element', 'paragraph' ) ).to.be.true;
-			expect( element.is( 'paragraph' ) ).to.be.true;
-			expect( element.is( 'model:paragraph' ) ).to.be.true;
+			expect( element.is( 'element', 'paragraph' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
 			expect( element.is( 'element', 'image' ) ).to.be.false;
 			expect( element.is( 'model:element', 'image' ) ).to.be.false;
-			expect( element.is( 'image' ) ).to.be.false;
+			expect( element.is( 'element', 'image' ) ).to.be.false;
 			expect( element.is( 'model:image' ) ).to.be.false;
-			expect( element.is( 'text' ) ).to.be.false;
-			expect( element.is( 'model:text' ) ).to.be.false;
-			expect( element.is( 'textProxy' ) ).to.be.false;
+			expect( element.is( '$text' ) ).to.be.false;
+			expect( element.is( 'model:$text' ) ).to.be.false;
+			expect( element.is( '$textProxy' ) ).to.be.false;
 			expect( element.is( 'documentFragment' ) ).to.be.false;
 			expect( element.is( 'rootElement' ) ).to.be.false;
 			expect( element.is( 'model:rootElement' ) ).to.be.false;
 			expect( element.is( 'view:node' ) ).to.be.false;
 			expect( element.is( 'view:element' ) ).to.be.false;
 			expect( element.is( 'view:element' ) ).to.be.false;
+			expect( element.is( 'node', 'paragraph' ) ).to.be.false;
+			expect( element.is( 'model:node', 'paragraph' ) ).to.be.false;
 		} );
 	} );
 

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

@@ -59,7 +59,7 @@ describe( 'LivePosition', () =>
 		it( 'should return false for incorrect values', () => {
 			expect( live.is( 'model' ) ).to.be.false;
 			expect( live.is( 'model:node' ) ).to.be.false;
-			expect( live.is( 'text' ) ).to.be.false;
+			expect( live.is( '$text' ) ).to.be.false;
 			expect( live.is( 'element', 'paragraph' ) ).to.be.false;
 		} );
 	} );

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

@@ -201,7 +201,7 @@ describe( 'LiveRange', () => {
 		it( 'should return false for incorrect values', () => {
 			expect( live.is( 'model' ) ).to.be.false;
 			expect( live.is( 'model:node' ) ).to.be.false;
-			expect( live.is( 'text' ) ).to.be.false;
+			expect( live.is( '$text' ) ).to.be.false;
 			expect( live.is( 'element', 'paragraph' ) ).to.be.false;
 		} );
 	} );

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

@@ -433,7 +433,7 @@ describe( 'Marker', () => {
 		it( 'should return false for incorrect values', () => {
 			expect( marker.is( 'model' ) ).to.be.false;
 			expect( marker.is( 'model:node' ) ).to.be.false;
-			expect( marker.is( 'text' ) ).to.be.false;
+			expect( marker.is( '$text' ) ).to.be.false;
 			expect( marker.is( 'element', 'paragraph' ) ).to.be.false;
 		} );
 	} );

+ 2 - 2
packages/ckeditor5-engine/tests/model/node.js

@@ -153,8 +153,8 @@ describe( 'Node', () => {
 
 		it( 'should return false for incorrect values', () => {
 			expect( node.is( 'model' ) ).to.be.false;
-			expect( node.is( 'model:text' ) ).to.be.false;
-			expect( node.is( 'text' ) ).to.be.false;
+			expect( node.is( 'model:$text' ) ).to.be.false;
+			expect( node.is( '$text' ) ).to.be.false;
 			expect( node.is( 'element', 'paragraph' ) ).to.be.false;
 		} );
 	} );

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

@@ -148,7 +148,7 @@ describe( 'Position', () => {
 		it( 'should return false for incorrect values', () => {
 			expect( position.is( 'model' ) ).to.be.false;
 			expect( position.is( 'model:node' ) ).to.be.false;
-			expect( position.is( 'text' ) ).to.be.false;
+			expect( position.is( '$text' ) ).to.be.false;
 			expect( position.is( 'element', 'paragraph' ) ).to.be.false;
 		} );
 	} );

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

@@ -59,7 +59,7 @@ describe( 'Range', () => {
 		it( 'should return false for incorrect values', () => {
 			expect( range.is( 'model' ) ).to.be.false;
 			expect( range.is( 'model:node' ) ).to.be.false;
-			expect( range.is( 'text' ) ).to.be.false;
+			expect( range.is( '$text' ) ).to.be.false;
 			expect( range.is( 'element', 'paragraph' ) ).to.be.false;
 		} );
 	} );

+ 6 - 4
packages/ckeditor5-engine/tests/model/rootelement.js

@@ -37,8 +37,6 @@ describe( 'RootElement', () => {
 			expect( root.is( 'model:element', '$root' ) ).to.be.true;
 			expect( root.is( 'element' ) ).to.be.true;
 			expect( root.is( 'model:element' ) ).to.be.true;
-			expect( root.is( '$root' ) ).to.be.true;
-			expect( root.is( 'model:$root' ) ).to.be.true;
 			expect( root.is( 'rootElement', '$root' ) ).to.be.true;
 			expect( root.is( 'model:rootElement', '$root' ) ).to.be.true;
 			expect( root.is( 'rootElement' ) ).to.be.true;
@@ -53,10 +51,14 @@ describe( 'RootElement', () => {
 			expect( root.is( 'rootElement', '$graveyard' ) ).to.be.false;
 			expect( root.is( 'model:rootElement', '$graveyard' ) ).to.be.false;
 			expect( root.is( '$graveyard' ) ).to.be.false;
-			expect( root.is( 'text' ) ).to.be.false;
-			expect( root.is( 'textProxy' ) ).to.be.false;
+			expect( root.is( '$text' ) ).to.be.false;
+			expect( root.is( '$textProxy' ) ).to.be.false;
 			expect( root.is( 'documentFragment' ) ).to.be.false;
 			expect( root.is( 'view:element' ) ).to.be.false;
+			expect( root.is( '$root' ) ).to.be.false;
+			expect( root.is( 'model:$root' ) ).to.be.false;
+			expect( root.is( 'node', '$root' ) ).to.be.false;
+			expect( root.is( 'model:node', '$root' ) ).to.be.false;
 		} );
 	} );
 } );

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

@@ -142,7 +142,7 @@ describe( 'Selection', () => {
 		it( 'should return false for incorrect values', () => {
 			expect( selection.is( 'model' ) ).to.be.false;
 			expect( selection.is( 'model:node' ) ).to.be.false;
-			expect( selection.is( 'text' ) ).to.be.false;
+			expect( selection.is( '$text' ) ).to.be.false;
 			expect( selection.is( 'element', 'paragraph' ) ).to.be.false;
 		} );
 	} );
@@ -834,8 +834,8 @@ describe( 'Selection', () => {
 		it( 'should return false for other values', () => {
 			expect( selection.is( 'documentSelection' ) ).to.be.false;
 			expect( selection.is( 'node' ) ).to.be.false;
-			expect( selection.is( 'text' ) ).to.be.false;
-			expect( selection.is( 'textProxy' ) ).to.be.false;
+			expect( selection.is( '$text' ) ).to.be.false;
+			expect( selection.is( '$textProxy' ) ).to.be.false;
 			expect( selection.is( 'element' ) ).to.be.false;
 			expect( selection.is( 'rootElement' ) ).to.be.false;
 		} );
@@ -1376,7 +1376,7 @@ describe( 'Selection', () => {
 			let innerText = '';
 
 			for ( const child of el.getChildren() ) {
-				if ( child.is( 'text' ) ) {
+				if ( child.is( '$text' ) ) {
 					innerText += child.data;
 				}
 			}

+ 3 - 1
packages/ckeditor5-engine/tests/model/text.js

@@ -42,12 +42,14 @@ describe( 'Text', () => {
 		it( 'should return true for node, text', () => {
 			expect( text.is( 'node' ) ).to.be.true;
 			expect( text.is( 'model:node' ) ).to.be.true;
+			expect( text.is( '$text' ) ).to.be.true;
+			expect( text.is( 'model:$text' ) ).to.be.true;
 			expect( text.is( 'text' ) ).to.be.true;
 			expect( text.is( 'model:text' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
-			expect( text.is( 'textProxy' ) ).to.be.false;
+			expect( text.is( '$textProxy' ) ).to.be.false;
 			expect( text.is( 'element' ) ).to.be.false;
 			expect( text.is( 'model:element' ) ).to.be.false;
 			expect( text.is( 'rootElement' ) ).to.be.false;

+ 4 - 2
packages/ckeditor5-engine/tests/model/textproxy.js

@@ -98,7 +98,9 @@ describe( 'TextProxy', () => {
 	} );
 
 	describe( 'is()', () => {
-		it( 'should return true for textProxy', () => {
+		it( 'should return true for $textProxy', () => {
+			expect( textProxy.is( '$textProxy' ) ).to.be.true;
+			expect( textProxy.is( 'model:$textProxy' ) ).to.be.true;
 			expect( textProxy.is( 'textProxy' ) ).to.be.true;
 			expect( textProxy.is( 'model:textProxy' ) ).to.be.true;
 		} );
@@ -106,7 +108,7 @@ describe( 'TextProxy', () => {
 		it( 'should return false for other accept values', () => {
 			expect( textProxy.is( 'node' ) ).to.be.false;
 			expect( textProxy.is( 'model:node' ) ).to.be.false;
-			expect( textProxy.is( 'text' ) ).to.be.false;
+			expect( textProxy.is( '$text' ) ).to.be.false;
 			expect( textProxy.is( 'element' ) ).to.be.false;
 			expect( textProxy.is( 'model:element', 'image' ) ).to.be.false;
 			expect( textProxy.is( 'documentFragment' ) ).to.be.false;

+ 5 - 5
packages/ckeditor5-engine/tests/view/attributeelement.js

@@ -44,8 +44,6 @@ describe( 'AttributeElement', () => {
 			expect( el.is( 'view:element' ) ).to.be.true;
 			expect( el.is( 'element', 'span' ) ).to.be.true;
 			expect( el.is( 'view:element', 'span' ) ).to.be.true;
-			expect( el.is( 'span' ) ).to.be.true;
-			expect( el.is( 'view:span' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
@@ -53,15 +51,17 @@ describe( 'AttributeElement', () => {
 			expect( el.is( 'view:attributeElement', 'p' ) ).to.be.false;
 			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:element', 'p' ) ).to.be.false;
-			expect( el.is( 'p' ) ).to.be.false;
+			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:p' ) ).to.be.false;
-			expect( el.is( 'text' ) ).to.be.false;
-			expect( el.is( 'textProxy' ) ).to.be.false;
+			expect( el.is( '$text' ) ).to.be.false;
+			expect( el.is( '$textProxy' ) ).to.be.false;
 			expect( el.is( 'containerElement' ) ).to.be.false;
 			expect( el.is( 'uiElement' ) ).to.be.false;
 			expect( el.is( 'emptyElement' ) ).to.be.false;
 			expect( el.is( 'rootElement' ) ).to.be.false;
 			expect( el.is( 'documentFragment' ) ).to.be.false;
+			expect( el.is( 'node', 'span' ) ).to.be.false;
+			expect( el.is( 'view:node', 'span' ) ).to.be.false;
 		} );
 	} );
 

+ 5 - 5
packages/ckeditor5-engine/tests/view/containerelement.js

@@ -42,8 +42,6 @@ describe( 'ContainerElement', () => {
 			expect( el.is( 'view:element' ) ).to.be.true;
 			expect( el.is( 'element', 'p' ) ).to.be.true;
 			expect( el.is( 'view:element', 'p' ) ).to.be.true;
-			expect( el.is( 'p' ) ).to.be.true;
-			expect( el.is( 'view:p' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
@@ -51,15 +49,17 @@ describe( 'ContainerElement', () => {
 			expect( el.is( 'view:containerElement', 'span' ) ).to.be.false;
 			expect( el.is( 'element', 'span' ) ).to.be.false;
 			expect( el.is( 'view:element', 'span' ) ).to.be.false;
-			expect( el.is( 'span' ) ).to.be.false;
+			expect( el.is( 'element', 'span' ) ).to.be.false;
 			expect( el.is( 'view:span' ) ).to.be.false;
-			expect( el.is( 'text' ) ).to.be.false;
-			expect( el.is( 'textProxy' ) ).to.be.false;
+			expect( el.is( '$text' ) ).to.be.false;
+			expect( el.is( '$textProxy' ) ).to.be.false;
 			expect( el.is( 'attributeElement' ) ).to.be.false;
 			expect( el.is( 'uiElement' ) ).to.be.false;
 			expect( el.is( 'emptyElement' ) ).to.be.false;
 			expect( el.is( 'rootElement' ) ).to.be.false;
 			expect( el.is( 'documentFragment' ) ).to.be.false;
+			expect( el.is( 'node', 'p' ) ).to.be.false;
+			expect( el.is( 'view:node', 'p' ) ).to.be.false;
 		} );
 	} );
 

+ 2 - 2
packages/ckeditor5-engine/tests/view/documentfragment.js

@@ -94,8 +94,8 @@ describe( 'DocumentFragment', () => {
 		it( 'should return false for other accept values', () => {
 			expect( frag.is( 'node' ) ).to.be.false;
 			expect( frag.is( 'view:node' ) ).to.be.false;
-			expect( frag.is( 'text' ) ).to.be.false;
-			expect( frag.is( 'textProxy' ) ).to.be.false;
+			expect( frag.is( '$text' ) ).to.be.false;
+			expect( frag.is( '$textProxy' ) ).to.be.false;
 			expect( frag.is( 'element' ) ).to.be.false;
 			expect( frag.is( 'view:element' ) ).to.be.false;
 			expect( frag.is( 'containerElement' ) ).to.be.false;

+ 3 - 3
packages/ckeditor5-engine/tests/view/documentselection.js

@@ -741,9 +741,9 @@ describe( 'DocumentSelection', () => {
 		it( 'should return false for other values', () => {
 			expect( documentSelection.is( 'node' ) ).to.be.false;
 			expect( documentSelection.is( 'view:node' ) ).to.be.false;
-			expect( documentSelection.is( 'text' ) ).to.be.false;
-			expect( documentSelection.is( 'view:text' ) ).to.be.false;
-			expect( documentSelection.is( 'textProxy' ) ).to.be.false;
+			expect( documentSelection.is( '$text' ) ).to.be.false;
+			expect( documentSelection.is( 'view:$text' ) ).to.be.false;
+			expect( documentSelection.is( '$textProxy' ) ).to.be.false;
 			expect( documentSelection.is( 'element' ) ).to.be.false;
 			expect( documentSelection.is( 'rootElement' ) ).to.be.false;
 			expect( documentSelection.is( 'model:selection' ) ).to.be.false;

+ 2 - 2
packages/ckeditor5-engine/tests/view/downcastwriter/writer.js

@@ -61,7 +61,7 @@ describe( 'DowncastWriter', () => {
 		it( 'should create Text instance', () => {
 			const text = writer.createText( 'foo bar' );
 
-			expect( text.is( 'text' ) ).to.be.true;
+			expect( text.is( '$text' ) ).to.be.true;
 			expect( text.data ).to.equal( 'foo bar' );
 		} );
 	} );
@@ -348,7 +348,7 @@ describe( 'DowncastWriter', () => {
 			);
 
 			// Find all spans.
-			const allSpans = Array.from( ViewRange._createIn( root ).getItems() ).filter( element => element.is( 'span' ) );
+			const allSpans = Array.from( ViewRange._createIn( root ).getItems() ).filter( element => element.is( 'element', 'span' ) );
 
 			// For each of the spans created above...
 			for ( const oneOfAllSpans of allSpans ) {

+ 4 - 5
packages/ckeditor5-engine/tests/view/editableelement.js

@@ -31,8 +31,7 @@ describe( 'EditableElement', () => {
 			expect( el.is( 'view:element' ) ).to.be.true;
 			expect( el.is( 'element', 'div' ) ).to.be.true;
 			expect( el.is( 'view:element', 'div' ) ).to.be.true;
-			expect( el.is( 'div' ) ).to.be.true;
-			expect( el.is( 'view:div' ) ).to.be.true;
+			expect( el.is( 'element', 'div' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
@@ -42,10 +41,10 @@ describe( 'EditableElement', () => {
 			expect( el.is( 'view:containerElement', 'p' ) ).to.be.false;
 			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:element', 'p' ) ).to.be.false;
-			expect( el.is( 'p' ) ).to.be.false;
+			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:p' ) ).to.be.false;
-			expect( el.is( 'text' ) ).to.be.false;
-			expect( el.is( 'textProxy' ) ).to.be.false;
+			expect( el.is( '$text' ) ).to.be.false;
+			expect( el.is( '$textProxy' ) ).to.be.false;
 			expect( el.is( 'attributeElement' ) ).to.be.false;
 			expect( el.is( 'uiElement' ) ).to.be.false;
 			expect( el.is( 'emptyElement' ) ).to.be.false;

+ 6 - 6
packages/ckeditor5-engine/tests/view/element.js

@@ -103,18 +103,16 @@ describe( 'Element', () => {
 			expect( el.is( 'view:element' ) ).to.be.true;
 			expect( el.is( 'element', 'p' ) ).to.be.true;
 			expect( el.is( 'view:element', 'p' ) ).to.be.true;
-			expect( el.is( 'p' ) ).to.be.true;
-			expect( el.is( 'view:p' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
 			expect( el.is( 'element', 'span' ) ).to.be.false;
 			expect( el.is( 'view:element', 'span' ) ).to.be.false;
-			expect( el.is( 'span' ) ).to.be.false;
+			expect( el.is( 'element', 'span' ) ).to.be.false;
 			expect( el.is( 'view:span' ) ).to.be.false;
-			expect( el.is( 'text' ) ).to.be.false;
-			expect( el.is( 'view:text' ) ).to.be.false;
-			expect( el.is( 'textProxy' ) ).to.be.false;
+			expect( el.is( '$text' ) ).to.be.false;
+			expect( el.is( 'view:$text' ) ).to.be.false;
+			expect( el.is( '$textProxy' ) ).to.be.false;
 			expect( el.is( 'containerElement' ) ).to.be.false;
 			expect( el.is( 'attributeElement' ) ).to.be.false;
 			expect( el.is( 'uiElement' ) ).to.be.false;
@@ -123,6 +121,8 @@ describe( 'Element', () => {
 			expect( el.is( 'rootElement' ) ).to.be.false;
 			expect( el.is( 'view:ootElement' ) ).to.be.false;
 			expect( el.is( 'documentFragment' ) ).to.be.false;
+			expect( el.is( 'node', 'p' ) ).to.be.false;
+			expect( el.is( 'view:node', 'p' ) ).to.be.false;
 		} );
 	} );
 

+ 6 - 6
packages/ckeditor5-engine/tests/view/emptyelement.js

@@ -39,8 +39,6 @@ describe( 'EmptyElement', () => {
 			expect( el.is( 'view:element' ) ).to.be.true;
 			expect( el.is( 'element', 'p' ) ).to.be.true;
 			expect( el.is( 'view:element', 'p' ) ).to.be.true;
-			expect( el.is( 'p' ) ).to.be.true;
-			expect( el.is( 'view:p' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
@@ -48,16 +46,18 @@ describe( 'EmptyElement', () => {
 			expect( el.is( 'view:emptyElement', 'span' ) ).to.be.false;
 			expect( el.is( 'element', 'span' ) ).to.be.false;
 			expect( el.is( 'view:element', 'span' ) ).to.be.false;
-			expect( el.is( 'span' ) ).to.be.false;
+			expect( el.is( 'element', 'span' ) ).to.be.false;
 			expect( el.is( 'view:span' ) ).to.be.false;
-			expect( el.is( 'text' ) ).to.be.false;
-			expect( el.is( 'view:text' ) ).to.be.false;
-			expect( el.is( 'textProxy' ) ).to.be.false;
+			expect( el.is( '$text' ) ).to.be.false;
+			expect( el.is( 'view:$text' ) ).to.be.false;
+			expect( el.is( '$textProxy' ) ).to.be.false;
 			expect( el.is( 'containerElement' ) ).to.be.false;
 			expect( el.is( 'attributeElement' ) ).to.be.false;
 			expect( el.is( 'uiElement' ) ).to.be.false;
 			expect( el.is( 'rootElement' ) ).to.be.false;
 			expect( el.is( 'documentFragment' ) ).to.be.false;
+			expect( el.is( 'node', 'p' ) ).to.be.false;
+			expect( el.is( 'view:node', 'p' ) ).to.be.false;
 		} );
 	} );
 

+ 3 - 3
packages/ckeditor5-engine/tests/view/node.js

@@ -49,9 +49,9 @@ describe( 'Node', () => {
 			expect( node.is( 'rootElement' ) ).to.be.false;
 			expect( node.is( 'containerElement' ) ).to.be.false;
 			expect( node.is( 'element' ) ).to.be.false;
-			expect( node.is( 'p' ) ).to.be.false;
-			expect( node.is( 'text' ) ).to.be.false;
-			expect( node.is( 'textProxy' ) ).to.be.false;
+			expect( node.is( 'element', 'p' ) ).to.be.false;
+			expect( node.is( '$text' ) ).to.be.false;
+			expect( node.is( '$textProxy' ) ).to.be.false;
 			expect( node.is( 'attributeElement' ) ).to.be.false;
 			expect( node.is( 'uiElement' ) ).to.be.false;
 			expect( node.is( 'emptyElement' ) ).to.be.false;

+ 5 - 5
packages/ckeditor5-engine/tests/view/observer/mutationobserver.js

@@ -300,7 +300,7 @@ describe( 'MutationObserver', () => {
 		expect( lastMutations[ 0 ].type ).to.equal( 'children' );
 		expect( lastMutations[ 0 ].oldChildren.length ).to.equal( 0 );
 		expect( lastMutations[ 0 ].newChildren.length ).to.equal( 1 );
-		expect( lastMutations[ 0 ].newChildren[ 0 ].is( 'text' ) ).to.be.true;
+		expect( lastMutations[ 0 ].newChildren[ 0 ].is( '$text' ) ).to.be.true;
 		expect( lastMutations[ 0 ].newChildren[ 0 ].data ).to.equal( ' ' );
 		expect( lastMutations[ 0 ].node ).to.equal( selection.getFirstPosition().parent );
 	} );
@@ -334,9 +334,9 @@ describe( 'MutationObserver', () => {
 		expect( lastMutations[ 0 ].newChildren.length ).to.equal( 3 );
 
 		// Foo and attribute is removed and reinserted.
-		expect( lastMutations[ 0 ].oldChildren[ 0 ].is( 'text' ) ).to.be.true;
+		expect( lastMutations[ 0 ].oldChildren[ 0 ].is( '$text' ) ).to.be.true;
 		expect( lastMutations[ 0 ].oldChildren[ 0 ].data ).to.equal( 'foo' );
-		expect( lastMutations[ 0 ].newChildren[ 0 ].is( 'text' ) ).to.be.true;
+		expect( lastMutations[ 0 ].newChildren[ 0 ].is( '$text' ) ).to.be.true;
 		expect( lastMutations[ 0 ].newChildren[ 0 ].data ).to.equal( 'foo' );
 
 		expect( lastMutations[ 0 ].oldChildren[ 1 ].is( 'attributeElement' ) ).to.be.true;
@@ -344,7 +344,7 @@ describe( 'MutationObserver', () => {
 		expect( lastMutations[ 0 ].newChildren[ 1 ].is( 'attributeElement' ) ).to.be.true;
 		expect( lastMutations[ 0 ].newChildren[ 1 ].name ).to.equal( 'b' );
 
-		expect( lastMutations[ 0 ].newChildren[ 2 ].is( 'text' ) ).to.be.true;
+		expect( lastMutations[ 0 ].newChildren[ 2 ].is( '$text' ) ).to.be.true;
 		expect( lastMutations[ 0 ].newChildren[ 2 ].data ).to.equal( ' ' );
 		expect( lastMutations[ 0 ].node ).to.equal( selection.getFirstPosition().parent );
 	} );
@@ -375,7 +375,7 @@ describe( 'MutationObserver', () => {
 		expect( lastMutations[ 0 ].type ).to.equal( 'children' );
 		expect( lastMutations[ 0 ].oldChildren.length ).to.equal( 0 );
 		expect( lastMutations[ 0 ].newChildren.length ).to.equal( 1 );
-		expect( lastMutations[ 0 ].newChildren[ 0 ].is( 'text' ) ).to.be.true;
+		expect( lastMutations[ 0 ].newChildren[ 0 ].is( '$text' ) ).to.be.true;
 		expect( lastMutations[ 0 ].newChildren[ 0 ].data ).to.equal( ' ' );
 		expect( lastMutations[ 0 ].node ).to.equal( selection.getFirstPosition().parent );
 	} );

+ 3 - 3
packages/ckeditor5-engine/tests/view/position.js

@@ -53,9 +53,9 @@ describe( 'Position', () => {
 			expect( position.is( 'rootElement' ) ).to.be.false;
 			expect( position.is( 'containerElement' ) ).to.be.false;
 			expect( position.is( 'element' ) ).to.be.false;
-			expect( position.is( 'p' ) ).to.be.false;
-			expect( position.is( 'text' ) ).to.be.false;
-			expect( position.is( 'textProxy' ) ).to.be.false;
+			expect( position.is( 'element', 'p' ) ).to.be.false;
+			expect( position.is( '$text' ) ).to.be.false;
+			expect( position.is( '$textProxy' ) ).to.be.false;
 			expect( position.is( 'attributeElement' ) ).to.be.false;
 			expect( position.is( 'uiElement' ) ).to.be.false;
 			expect( position.is( 'emptyElement' ) ).to.be.false;

+ 3 - 3
packages/ckeditor5-engine/tests/view/range.js

@@ -68,9 +68,9 @@ describe( 'Range', () => {
 			expect( range.is( 'rootElement' ) ).to.be.false;
 			expect( range.is( 'containerElement' ) ).to.be.false;
 			expect( range.is( 'element' ) ).to.be.false;
-			expect( range.is( 'p' ) ).to.be.false;
-			expect( range.is( 'text' ) ).to.be.false;
-			expect( range.is( 'textProxy' ) ).to.be.false;
+			expect( range.is( 'element', 'p' ) ).to.be.false;
+			expect( range.is( '$text' ) ).to.be.false;
+			expect( range.is( '$textProxy' ) ).to.be.false;
 			expect( range.is( 'attributeElement' ) ).to.be.false;
 			expect( range.is( 'uiElement' ) ).to.be.false;
 			expect( range.is( 'emptyElement' ) ).to.be.false;

+ 8 - 6
packages/ckeditor5-engine/tests/view/rooteditableelement.js

@@ -66,8 +66,6 @@ describe( 'RootEditableElement', () => {
 			expect( el.is( 'view:element' ) ).to.be.true;
 			expect( el.is( 'element', 'div' ) ).to.be.true;
 			expect( el.is( 'view:element', 'div' ) ).to.be.true;
-			expect( el.is( 'div' ) ).to.be.true;
-			expect( el.is( 'view:div' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
@@ -77,16 +75,20 @@ describe( 'RootEditableElement', () => {
 			expect( el.is( 'view:containerElement', 'p' ) ).to.be.false;
 			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:element', 'p' ) ).to.be.false;
-			expect( el.is( 'p' ) ).to.be.false;
+			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:p' ) ).to.be.false;
-			expect( el.is( 'text' ) ).to.be.false;
-			expect( el.is( 'view:text' ) ).to.be.false;
-			expect( el.is( 'textProxy' ) ).to.be.false;
+			expect( el.is( '$text' ) ).to.be.false;
+			expect( el.is( 'view:$text' ) ).to.be.false;
+			expect( el.is( '$textProxy' ) ).to.be.false;
 			expect( el.is( 'attributeElement' ) ).to.be.false;
 			expect( el.is( 'uiElement' ) ).to.be.false;
 			expect( el.is( 'emptyElement' ) ).to.be.false;
 			expect( el.is( 'documentFragment' ) ).to.be.false;
 			expect( el.is( 'model:rootElement' ) ).to.be.false;
+			expect( el.is( 'div' ) ).to.be.false;
+			expect( el.is( 'view:div' ) ).to.be.false;
+			expect( el.is( 'node', 'div' ) ).to.be.false;
+			expect( el.is( 'view:node', 'div' ) ).to.be.false;
 		} );
 	} );
 

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

@@ -613,8 +613,8 @@ describe( 'Selection', () => {
 			expect( selection.is( 'documentSelection' ) ).to.be.false;
 			expect( selection.is( 'view:documentSelection' ) ).to.be.false;
 			expect( selection.is( 'node' ) ).to.be.false;
-			expect( selection.is( 'text' ) ).to.be.false;
-			expect( selection.is( 'textProxy' ) ).to.be.false;
+			expect( selection.is( '$text' ) ).to.be.false;
+			expect( selection.is( '$textProxy' ) ).to.be.false;
 			expect( selection.is( 'element' ) ).to.be.false;
 			expect( selection.is( 'rootElement' ) ).to.be.false;
 			expect( selection.is( 'model:selection' ) ).to.be.false;

+ 5 - 3
packages/ckeditor5-engine/tests/view/text.js

@@ -35,13 +35,15 @@ describe( 'Text', () => {
 		it( 'should return true for node, text', () => {
 			expect( text.is( 'node' ) ).to.be.true;
 			expect( text.is( 'view:node' ) ).to.be.true;
+			expect( text.is( '$text' ) ).to.be.true;
+			expect( text.is( 'view:$text' ) ).to.be.true;
 			expect( text.is( 'text' ) ).to.be.true;
 			expect( text.is( 'view:text' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
-			expect( text.is( 'textProxy' ) ).to.be.false;
-			expect( text.is( 'view:textProxy' ) ).to.be.false;
+			expect( text.is( '$textProxy' ) ).to.be.false;
+			expect( text.is( 'view:$textProxy' ) ).to.be.false;
 			expect( text.is( 'element' ) ).to.be.false;
 			expect( text.is( 'view:element' ) ).to.be.false;
 			expect( text.is( 'containerElement' ) ).to.be.false;
@@ -50,7 +52,7 @@ describe( 'Text', () => {
 			expect( text.is( 'emptyElement' ) ).to.be.false;
 			expect( text.is( 'rootElement' ) ).to.be.false;
 			expect( text.is( 'documentFragment' ) ).to.be.false;
-			expect( text.is( 'model:text' ) ).to.be.false;
+			expect( text.is( 'model:$text' ) ).to.be.false;
 			expect( text.is( 'model:node' ) ).to.be.false;
 		} );
 	} );

+ 6 - 4
packages/ckeditor5-engine/tests/view/textproxy.js

@@ -65,7 +65,9 @@ describe( 'TextProxy', () => {
 	} );
 
 	describe( 'is()', () => {
-		it( 'should return true for textProxy', () => {
+		it( 'should return true for $textProxy', () => {
+			expect( textProxy.is( '$textProxy' ) ).to.be.true;
+			expect( textProxy.is( 'view:$textProxy' ) ).to.be.true;
 			expect( textProxy.is( 'textProxy' ) ).to.be.true;
 			expect( textProxy.is( 'view:textProxy' ) ).to.be.true;
 		} );
@@ -73,8 +75,8 @@ describe( 'TextProxy', () => {
 		it( 'should return false for other accept values', () => {
 			expect( textProxy.is( 'node' ) ).to.be.false;
 			expect( textProxy.is( 'view:node' ) ).to.be.false;
-			expect( textProxy.is( 'text' ) ).to.be.false;
-			expect( textProxy.is( 'view:text' ) ).to.be.false;
+			expect( textProxy.is( '$text' ) ).to.be.false;
+			expect( textProxy.is( 'view:$text' ) ).to.be.false;
 			expect( textProxy.is( 'element' ) ).to.be.false;
 			expect( textProxy.is( 'containerElement' ) ).to.be.false;
 			expect( textProxy.is( 'attributeElement' ) ).to.be.false;
@@ -82,7 +84,7 @@ describe( 'TextProxy', () => {
 			expect( textProxy.is( 'emptyElement' ) ).to.be.false;
 			expect( textProxy.is( 'rootElement' ) ).to.be.false;
 			expect( textProxy.is( 'documentFragment' ) ).to.be.false;
-			expect( textProxy.is( 'model:textProxy' ) ).to.be.false;
+			expect( textProxy.is( 'model:$textProxy' ) ).to.be.false;
 		} );
 	} );
 

+ 5 - 5
packages/ckeditor5-engine/tests/view/uielement.js

@@ -59,8 +59,6 @@ describe( 'UIElement', () => {
 			expect( el.is( 'view:node' ) ).to.be.true;
 			expect( el.is( 'element', 'span' ) ).to.be.true;
 			expect( el.is( 'view:element', 'span' ) ).to.be.true;
-			expect( el.is( 'span' ) ).to.be.true;
-			expect( el.is( 'view:span' ) ).to.be.true;
 		} );
 
 		it( 'should return false for other accept values', () => {
@@ -68,10 +66,10 @@ describe( 'UIElement', () => {
 			expect( el.is( 'view:uiElement', 'p' ) ).to.be.false;
 			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:element', 'p' ) ).to.be.false;
-			expect( el.is( 'p' ) ).to.be.false;
+			expect( el.is( 'element', 'p' ) ).to.be.false;
 			expect( el.is( 'view:p' ) ).to.be.false;
-			expect( el.is( 'text' ) ).to.be.false;
-			expect( el.is( 'textProxy' ) ).to.be.false;
+			expect( el.is( '$text' ) ).to.be.false;
+			expect( el.is( '$textProxy' ) ).to.be.false;
 			expect( el.is( 'containerElement' ) ).to.be.false;
 			expect( el.is( 'attributeElement' ) ).to.be.false;
 			expect( el.is( 'emptyElement' ) ).to.be.false;
@@ -80,6 +78,8 @@ describe( 'UIElement', () => {
 			expect( el.is( 'model:element' ) ).to.be.false;
 			expect( el.is( 'model:span' ) ).to.be.false;
 			expect( el.is( 'model:node' ) ).to.be.false;
+			expect( el.is( 'node', 'span' ) ).to.be.false;
+			expect( el.is( 'view:node', 'span' ) ).to.be.false;
 		} );
 	} );
 

+ 1 - 1
packages/ckeditor5-font/src/ui/colortableview.js

@@ -197,7 +197,7 @@ export default class ColorTableView extends View {
 			const range = model.createRangeIn( root );
 
 			for ( const node of range.getItems() ) {
-				if ( node.is( 'textProxy' ) && node.hasAttribute( attributeName ) ) {
+				if ( node.is( '$textProxy' ) && node.hasAttribute( attributeName ) ) {
 					this._addColorToDocumentColors( node.getAttribute( attributeName ) );
 
 					if ( this.documentColors.length >= maxCount ) {

+ 1 - 1
packages/ckeditor5-heading/src/headingcommand.js

@@ -76,7 +76,7 @@ export default class HeadingCommand extends Command {
 				} );
 
 			for ( const block of blocks ) {
-				if ( !block.is( modelElement ) ) {
+				if ( !block.is( 'element', modelElement ) ) {
 					writer.rename( block, modelElement );
 				}
 			}

+ 2 - 2
packages/ckeditor5-heading/src/headingediting.js

@@ -95,9 +95,9 @@ export default class HeadingEditing extends Plugin {
 		if ( enterCommand ) {
 			this.listenTo( enterCommand, 'afterExecute', ( evt, data ) => {
 				const positionParent = editor.model.document.selection.getFirstPosition().parent;
-				const isHeading = options.some( option => positionParent.is( option.model ) );
+				const isHeading = options.some( option => positionParent.is( 'element', option.model ) );
 
-				if ( isHeading && !positionParent.is( defaultModelElement ) && positionParent.childCount === 0 ) {
+				if ( isHeading && !positionParent.is( 'element', defaultModelElement ) && positionParent.childCount === 0 ) {
 					data.writer.rename( positionParent, defaultModelElement );
 				}
 			} );

+ 6 - 6
packages/ckeditor5-heading/src/title.js

@@ -237,7 +237,7 @@ export default class Title extends Plugin {
 
 		// When title element is at the beginning of the document then try to fix additional
 		// title elements (if there are any) and stop post-fixer as soon as possible.
-		if ( firstRootChild.is( 'title' ) ) {
+		if ( firstRootChild.is( 'element', 'title' ) ) {
 			return fixAdditionalTitleElements( titleElements, writer, model );
 		}
 
@@ -386,7 +386,7 @@ export default class Title extends Plugin {
 				const selection = model.document.selection;
 				const selectedElements = Array.from( selection.getSelectedBlocks() );
 
-				if ( selectedElements.length === 1 && selectedElements[ 0 ].is( 'title-content' ) ) {
+				if ( selectedElements.length === 1 && selectedElements[ 0 ].is( 'element', 'title-content' ) ) {
 					const firstBodyElement = model.document.getRoot().getChild( 1 );
 					writer.setSelection( firstBodyElement, 0 );
 					cancel();
@@ -429,7 +429,7 @@ function dataViewModelH1Insertion( evt, data, conversionApi ) {
 	const modelCursor = data.modelCursor;
 	const viewItem = data.viewItem;
 
-	if ( !modelCursor.isAtStart || !modelCursor.parent.is( '$root' ) ) {
+	if ( !modelCursor.isAtStart || !modelCursor.parent.is( 'element', '$root' ) ) {
 		return;
 	}
 
@@ -460,7 +460,7 @@ function mapModelPositionToView( editingView ) {
 	return ( evt, data ) => {
 		const positionParent = data.modelPosition.parent;
 
-		if ( !positionParent.is( 'title' ) ) {
+		if ( !positionParent.is( 'element', 'title' ) ) {
 			return;
 		}
 
@@ -477,7 +477,7 @@ function mapModelPositionToView( editingView ) {
 // @param {module:engine/model/element~Element} element
 // @returns {Boolean}
 function isTitle( element ) {
-	return element.is( 'title' );
+	return element.is( 'element', 'title' );
 }
 
 // Changes the given element to the title element.
@@ -542,7 +542,7 @@ function fixTitleElement( title, writer, model ) {
 // @param {module:engine/model/element~Element} placeholder
 // @returns {Boolean}
 function shouldRemoveLastParagraph( placeholder, root ) {
-	if ( !placeholder || !placeholder.is( 'paragraph' ) || placeholder.childCount ) {
+	if ( !placeholder || !placeholder.is( 'element', 'paragraph' ) || placeholder.childCount ) {
 		return false;
 	}
 

+ 1 - 1
packages/ckeditor5-horizontal-line/src/horizontallinecommand.js

@@ -108,7 +108,7 @@ function getInsertHorizontalLineParent( selection, model ) {
 
 	const parent = insertAt.parent;
 
-	if ( parent.isEmpty && !parent.is( '$root' ) ) {
+	if ( parent.isEmpty && !parent.is( 'element', '$root' ) ) {
 		return parent.parent;
 	}
 

+ 4 - 4
packages/ckeditor5-image/src/image/utils.js

@@ -65,7 +65,7 @@ export function getSelectedImageWidget( selection ) {
  * @returns {Boolean}
  */
 export function isImage( modelElement ) {
-	return !!modelElement && modelElement.is( 'image' );
+	return !!modelElement && modelElement.is( 'element', 'image' );
 }
 
 /**
@@ -129,7 +129,7 @@ export function getViewImgFromWidget( figureView ) {
 		}
 	}
 
-	return figureChildren.find( viewChild => viewChild.is( 'img' ) );
+	return figureChildren.find( viewChild => viewChild.is( 'element', 'img' ) );
 }
 
 // Checks if image is allowed by schema in optimal insertion parent.
@@ -152,7 +152,7 @@ function checkSelectionOnObject( selection, schema ) {
 
 // Checks if selection is placed in other image (ie. in caption).
 function isInOtherImage( selection ) {
-	return [ ...selection.focus.getAncestors() ].every( ancestor => !ancestor.is( 'image' ) );
+	return [ ...selection.focus.getAncestors() ].every( ancestor => !ancestor.is( 'element', 'image' ) );
 }
 
 // Returns a node that will be used to insert image with `model.insertContent` to check if image can be placed there.
@@ -161,7 +161,7 @@ function getInsertImageParent( selection, model ) {
 
 	const parent = insertAt.parent;
 
-	if ( parent.isEmpty && !parent.is( '$root' ) ) {
+	if ( parent.isEmpty && !parent.is( 'element', '$root' ) ) {
 		return parent.parent;
 	}
 

+ 4 - 4
packages/ckeditor5-image/src/imagecaption/imagecaptionediting.js

@@ -101,7 +101,7 @@ export default class ImageCaptionEditing extends Plugin {
 		const modelSelection = this.editor.model.document.selection;
 		const selectedElement = modelSelection.getSelectedElement();
 
-		if ( selectedElement && selectedElement.is( 'image' ) ) {
+		if ( selectedElement && selectedElement.is( 'element', 'image' ) ) {
 			const modelCaption = getCaptionFromImage( selectedElement );
 			viewCaption = mapper.toViewElement( modelCaption );
 		}
@@ -191,14 +191,14 @@ export default class ImageCaptionEditing extends Plugin {
 			if ( entry.type == 'insert' && entry.name != '$text' ) {
 				const item = entry.position.nodeAfter;
 
-				if ( item.is( 'image' ) && !getCaptionFromImage( item ) ) {
+				if ( item.is( 'element', 'image' ) && !getCaptionFromImage( item ) ) {
 					imagesWithoutCaption.push( item );
 				}
 
 				// Check elements with children for nested images.
-				if ( !item.is( 'image' ) && item.childCount ) {
+				if ( !item.is( 'element', 'image' ) && item.childCount ) {
 					for ( const nestedItem of model.createRangeIn( item ).getItems() ) {
-						if ( nestedItem.is( 'image' ) && !getCaptionFromImage( nestedItem ) ) {
+						if ( nestedItem.is( 'element', 'image' ) && !getCaptionFromImage( nestedItem ) ) {
 							imagesWithoutCaption.push( nestedItem );
 						}
 					}

+ 1 - 1
packages/ckeditor5-image/src/imagecaption/utils.js

@@ -50,7 +50,7 @@ export function isCaption( viewElement ) {
  */
 export function getCaptionFromImage( imageModelElement ) {
 	for ( const node of imageModelElement.getChildren() ) {
-		if ( !!node && node.is( 'caption' ) ) {
+		if ( !!node && node.is( 'element', 'caption' ) ) {
 			return node;
 		}
 	}

+ 1 - 1
packages/ckeditor5-image/src/imageupload/imageuploadediting.js

@@ -340,6 +340,6 @@ export function isHtmlIncluded( dataTransfer ) {
 
 function getImagesFromChangeItem( editor, item ) {
 	return Array.from( editor.model.createRangeOn( item ) )
-		.filter( value => value.item.is( 'image' ) )
+		.filter( value => value.item.is( 'element', 'image' ) )
 		.map( value => value.item );
 }

+ 1 - 1
packages/ckeditor5-link/src/autolink.js

@@ -74,7 +74,7 @@ export default class AutoLink extends Plugin {
 
 		selection.on( 'change:range', () => {
 			// Disable plugin when selection is inside a code block.
-			this.isEnabled = !selection.anchor.parent.is( 'codeBlock' );
+			this.isEnabled = !selection.anchor.parent.is( 'element', 'codeBlock' );
 		} );
 
 		this._enableTypingHandling();

+ 2 - 2
packages/ckeditor5-link/src/linkcommand.js

@@ -8,7 +8,7 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
-import findLinkRange from './findlinkrange';
+import findAttributeRange from '@ckeditor/ckeditor5-typing/src/utils/findattributerange';
 import toMap from '@ckeditor/ckeditor5-utils/src/tomap';
 import Collection from '@ckeditor/ckeditor5-utils/src/collection';
 import first from '@ckeditor/ckeditor5-utils/src/first';
@@ -171,7 +171,7 @@ export default class LinkCommand extends Command {
 				// When selection is inside text with `linkHref` attribute.
 				if ( selection.hasAttribute( 'linkHref' ) ) {
 					// Then update `linkHref` value.
-					const linkRange = findLinkRange( position, selection.getAttribute( 'linkHref' ), model );
+					const linkRange = findAttributeRange( position, 'linkHref', selection.getAttribute( 'linkHref' ), model );
 
 					writer.setAttribute( 'linkHref', href, linkRange );
 

+ 6 - 66
packages/ckeditor5-link/src/linkediting.js

@@ -10,12 +10,13 @@
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';
 import TwoStepCaretMovement from '@ckeditor/ckeditor5-typing/src/twostepcaretmovement';
+import inlineHighlight from '@ckeditor/ckeditor5-typing/src/utils/inlinehighlight';
 import Input from '@ckeditor/ckeditor5-typing/src/input';
 import Clipboard from '@ckeditor/ckeditor5-clipboard/src/clipboard';
 import LinkCommand from './linkcommand';
 import UnlinkCommand from './unlinkcommand';
 import ManualDecorator from './utils/manualdecorator';
-import findLinkRange from './findlinkrange';
+import findAttributeRange from '@ckeditor/ckeditor5-typing/src/utils/findattributerange';
 import { createLinkElement, ensureSafeUrl, getLocalizedDecorators, normalizeDecorators } from './utils';
 
 import '../theme/link.css';
@@ -105,7 +106,7 @@ export default class LinkEditing extends Plugin {
 		twoStepCaretMovementPlugin.registerAttribute( 'linkHref' );
 
 		// Setup highlight over selected link.
-		this._setupLinkHighlight();
+		inlineHighlight( editor, 'linkHref', 'a', HIGHLIGHT_CLASS );
 
 		// Change the attributes of the selection in certain situations after the link was inserted into the document.
 		this._enableInsertContentSelectionAttributesFixer();
@@ -207,67 +208,6 @@ export default class LinkEditing extends Plugin {
 		} );
 	}
 
-	/**
-	 * Adds a visual highlight style to a link in which the selection is anchored.
-	 * Together with two-step caret movement, they indicate that the user is typing inside the link.
-	 *
-	 * Highlight is turned on by adding the `.ck-link_selected` class to the link in the view:
-	 *
-	 * * The class is removed before the conversion has started, as callbacks added with the `'highest'` priority
-	 * to {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} events.
-	 * * The class is added in the view post fixer, after other changes in the model tree were converted to the view.
-	 *
-	 * This way, adding and removing the highlight does not interfere with conversion.
-	 *
-	 * @private
-	 */
-	_setupLinkHighlight() {
-		const editor = this.editor;
-		const view = editor.editing.view;
-		const highlightedLinks = new Set();
-
-		// Adding the class.
-		view.document.registerPostFixer( writer => {
-			const selection = editor.model.document.selection;
-			let changed = false;
-
-			if ( selection.hasAttribute( 'linkHref' ) ) {
-				const modelRange = findLinkRange( selection.getFirstPosition(), selection.getAttribute( 'linkHref' ), editor.model );
-				const viewRange = editor.editing.mapper.toViewRange( modelRange );
-
-				// There might be multiple `a` elements in the `viewRange`, for example, when the `a` element is
-				// broken by a UIElement.
-				for ( const item of viewRange.getItems() ) {
-					if ( item.is( 'a' ) && !item.hasClass( HIGHLIGHT_CLASS ) ) {
-						writer.addClass( HIGHLIGHT_CLASS, item );
-						highlightedLinks.add( item );
-						changed = true;
-					}
-				}
-			}
-
-			return changed;
-		} );
-
-		// Removing the class.
-		editor.conversion.for( 'editingDowncast' ).add( dispatcher => {
-			// Make sure the highlight is removed on every possible event, before conversion is started.
-			dispatcher.on( 'insert', removeHighlight, { priority: 'highest' } );
-			dispatcher.on( 'remove', removeHighlight, { priority: 'highest' } );
-			dispatcher.on( 'attribute', removeHighlight, { priority: 'highest' } );
-			dispatcher.on( 'selection', removeHighlight, { priority: 'highest' } );
-
-			function removeHighlight() {
-				view.change( writer => {
-					for ( const item of highlightedLinks.values() ) {
-						writer.removeClass( HIGHLIGHT_CLASS, item );
-						highlightedLinks.delete( item );
-					}
-				} );
-			}
-		} );
-	}
-
 	/**
 	 * Starts listening to {@link module:engine/model/model~Model#event:insertContent} and corrects the model
 	 * selection attributes if the selection is at the end of a link after inserting the content.
@@ -407,7 +347,7 @@ export default class LinkEditing extends Plugin {
 			}
 
 			const position = selection.getFirstPosition();
-			const linkRange = findLinkRange( position, selection.getAttribute( 'linkHref' ), editor.model );
+			const linkRange = findAttributeRange( position, 'linkHref', selection.getAttribute( 'linkHref' ), editor.model );
 
 			// ...check whether clicked start/end boundary of the link.
 			// If so, remove the `linkHref` attribute.
@@ -516,7 +456,7 @@ function shouldCopyAttributes( model ) {
 	}
 
 	// ...or it isn't the text node...
-	if ( !nodeAtFirstPosition.is( 'text' ) ) {
+	if ( !nodeAtFirstPosition.is( '$text' ) ) {
 		return false;
 	}
 
@@ -536,7 +476,7 @@ function shouldCopyAttributes( model ) {
 
 	// If nodes are not equal, maybe the link nodes has defined additional attributes inside.
 	// First, we need to find the entire link range.
-	const linkRange = findLinkRange( firstPosition, nodeAtFirstPosition.getAttribute( 'linkHref' ), model );
+	const linkRange = findAttributeRange( firstPosition, 'linkHref', nodeAtFirstPosition.getAttribute( 'linkHref' ), model );
 
 	// Then we can check whether selected range is inside the found link range. If so, attributes should be preserved.
 	return linkRange.containsRange( model.createRange( firstPosition, lastPosition ), true );

+ 2 - 2
packages/ckeditor5-link/src/linkimageediting.js

@@ -121,7 +121,7 @@ function upcastLink() {
 			// figure > a > img: parent of the link element is an image element.
 			let modelElement = data.modelCursor.parent;
 
-			if ( !modelElement.is( 'image' ) ) {
+			if ( !modelElement.is( 'element', 'image' ) ) {
 				// a > img: parent of the link is not the image element. We need to convert it manually.
 				const conversionResult = conversionApi.convertItem( imageInLink, data.modelCursor );
 
@@ -134,7 +134,7 @@ function upcastLink() {
 				modelElement = data.modelCursor.nodeBefore;
 			}
 
-			if ( modelElement && modelElement.is( 'image' ) ) {
+			if ( modelElement && modelElement.is( 'element', 'image' ) ) {
 				// Set the linkHref attribute from link element on model image element.
 				conversionApi.writer.setAttribute( 'linkHref', linkHref, modelElement );
 			}

+ 1 - 1
packages/ckeditor5-link/src/linkimageui.js

@@ -116,5 +116,5 @@ function isImageLinked( element ) {
 		return false;
 	}
 
-	return element.getChild( 0 ).is( 'a' );
+	return element.getChild( 0 ).is( 'element', 'a' );
 }

+ 8 - 2
packages/ckeditor5-link/src/unlinkcommand.js

@@ -8,8 +8,8 @@
  */
 
 import Command from '@ckeditor/ckeditor5-core/src/command';
+import findAttributeRange from '@ckeditor/ckeditor5-typing/src/utils/findattributerange';
 import first from '@ckeditor/ckeditor5-utils/src/first';
-import findLinkRange from './findlinkrange';
 import { isImageAllowed } from './utils';
 
 /**
@@ -58,7 +58,13 @@ export default class UnlinkCommand extends Command {
 		model.change( writer => {
 			// Get ranges to unlink.
 			const rangesToUnlink = selection.isCollapsed ?
-				[ findLinkRange( selection.getFirstPosition(), selection.getAttribute( 'linkHref' ), model ) ] : selection.getRanges();
+				[ findAttributeRange(
+					selection.getFirstPosition(),
+					'linkHref',
+					selection.getAttribute( 'linkHref' ),
+					model
+				) ] :
+				selection.getRanges();
 
 			// Remove `linkHref` attribute from specified ranges.
 			for ( const range of rangesToUnlink ) {

+ 1 - 1
packages/ckeditor5-link/src/utils.js

@@ -132,5 +132,5 @@ export function isImageAllowed( element, schema ) {
 		return false;
 	}
 
-	return element.is( 'image' ) && schema.checkAttribute( 'image', 'linkHref' );
+	return element.is( 'element', 'image' ) && schema.checkAttribute( 'image', 'linkHref' );
 }

+ 26 - 20
packages/ckeditor5-link/tests/linkediting.js

@@ -22,6 +22,8 @@ import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils
 import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 import { isLinkElement } from '../src/utils';
 
+import '@ckeditor/ckeditor5-core/tests/_utils/assertions/attribute';
+
 /* global document */
 
 describe( 'LinkEditing', () => {
@@ -89,7 +91,7 @@ describe( 'LinkEditing', () => {
 			setModelData( editor.model, '<paragraph>foo[]<$text linkHref="url">b</$text>ar</paragraph>' );
 
 			// The selection's gravity should read attributes from the left.
-			expect( selection.hasAttribute( 'linkHref' ), 'hasAttribute( \'linkHref\' )' ).to.be.false;
+			expect( selection ).not.to.have.attribute( 'linkHref' );
 
 			// So let's simulate the `keydown` event.
 			editor.editing.view.document.fire( 'keydown', {
@@ -100,8 +102,8 @@ describe( 'LinkEditing', () => {
 
 			expect( getModelData( model ) ).to.equal( '<paragraph>foo<$text linkHref="url">[]b</$text>ar</paragraph>' );
 			// Selection should get the attributes from the right.
-			expect( selection.hasAttribute( 'linkHref' ), 'hasAttribute( \'linkHref\' )' ).to.be.true;
-			expect( selection.getAttribute( 'linkHref' ), 'linkHref attribute' ).to.equal( 'url' );
+			expect( selection ).to.have.attribute( 'linkHref' );
+			expect( selection ).to.have.attribute( 'linkHref', 'url' );
 		} );
 
 		it( 'should be bound to the `linkHref` attribute (RTL)', async () => {
@@ -120,7 +122,7 @@ describe( 'LinkEditing', () => {
 			setModelData( editor.model, '<paragraph>foo[]<$text linkHref="url">b</$text>ar</paragraph>' );
 
 			// The selection's gravity should read attributes from the left.
-			expect( selection.hasAttribute( 'linkHref' ), 'hasAttribute( \'linkHref\' )' ).to.be.false;
+			expect( selection ).not.to.have.attribute( 'linkHref' );
 
 			// So let's simulate the `keydown` event.
 			editor.editing.view.document.fire( 'keydown', {
@@ -131,8 +133,8 @@ describe( 'LinkEditing', () => {
 
 			expect( getModelData( model ) ).to.equal( '<paragraph>foo<$text linkHref="url">[]b</$text>ar</paragraph>' );
 			// Selection should get the attributes from the right.
-			expect( selection.hasAttribute( 'linkHref' ), 'hasAttribute( \'linkHref\' )' ).to.be.true;
-			expect( selection.getAttribute( 'linkHref' ), 'linkHref attribute' ).to.equal( 'url' );
+			expect( selection ).to.have.attribute( 'linkHref' );
+			expect( selection ).to.have.attribute( 'linkHref', 'url' );
 
 			await editor.destroy();
 		} );
@@ -182,7 +184,7 @@ describe( 'LinkEditing', () => {
 				'</paragraph>'
 			);
 
-			expect( [ ...model.document.selection.getAttributeKeys() ] ).to.have.members( [ 'bold' ] );
+			expect( model.document.selection ).to.have.attribute( 'bold' );
 		} );
 
 		it( 'should not remove link atttributes when pasting in the middle of a link with the same URL', () => {
@@ -193,7 +195,7 @@ describe( 'LinkEditing', () => {
 			} );
 
 			expect( getModelData( model ) ).to.equal( '<paragraph><$text linkHref="ckeditor.com">foINSERTED[]o</$text></paragraph>' );
-			expect( [ ...model.document.selection.getAttributeKeys() ] ).to.have.members( [ 'linkHref' ] );
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
 		} );
 
 		it( 'should not remove link atttributes from the selection when pasting before a link when the gravity is overridden', () => {
@@ -205,7 +207,7 @@ describe( 'LinkEditing', () => {
 				domTarget: document.body
 			} );
 
-			expect( model.document.selection.isGravityOverridden ).to.be.true;
+			expect( model.document.selection ).to.have.property( 'isGravityOverridden', true );
 
 			model.change( writer => {
 				model.insertContent( writer.createText( 'INSERTED', { bold: true } ) );
@@ -219,8 +221,8 @@ describe( 'LinkEditing', () => {
 				'</paragraph>'
 			);
 
-			expect( model.document.selection.isGravityOverridden ).to.be.true;
-			expect( [ ...model.document.selection.getAttributeKeys() ] ).to.have.members( [ 'linkHref' ] );
+			expect( model.document.selection ).to.have.property( 'isGravityOverridden', true );
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
 		} );
 
 		it( 'should not remove link atttributes when pasting a link into another link (different URLs, no merge)', () => {
@@ -238,13 +240,13 @@ describe( 'LinkEditing', () => {
 				'</paragraph>'
 			);
 
-			expect( [ ...model.document.selection.getAttributeKeys() ] ).to.have.members( [ 'linkHref' ] );
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
 		} );
 
 		it( 'should not remove link atttributes when pasting before another link (different URLs, no merge)', () => {
 			setModelData( model, '<paragraph>[]<$text linkHref="ckeditor.com">foo</$text></paragraph>' );
 
-			expect( model.document.selection.isGravityOverridden ).to.be.false;
+			expect( model.document.selection ).to.have.property( 'isGravityOverridden', false );
 
 			model.change( writer => {
 				model.insertContent( writer.createText( 'INSERTED', { linkHref: 'http://INSERTED' } ) );
@@ -257,8 +259,8 @@ describe( 'LinkEditing', () => {
 				'</paragraph>'
 			);
 
-			expect( [ ...model.document.selection.getAttributeKeys() ] ).to.have.members( [ 'linkHref' ] );
-			expect( model.document.selection.getAttribute( 'linkHref' ) ).to.equal( 'http://INSERTED' );
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
+			expect( model.document.selection ).to.have.attribute( 'linkHref', 'http://INSERTED' );
 		} );
 	} );
 
@@ -375,7 +377,7 @@ describe( 'LinkEditing', () => {
 				'<paragraph>foo <$text linkHref="url">b{}ar</$text> baz</paragraph>'
 			);
 
-			expect( model.document.selection.hasAttribute( 'linkHref' ) ).to.be.true;
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
 			expect( getViewData( view ) ).to.equal(
 				'<p>foo <a class="ck-link_selected" href="url">b{}ar</a> baz</p>'
 			);
@@ -386,13 +388,13 @@ describe( 'LinkEditing', () => {
 				'<paragraph>foo {}<$text linkHref="url">bar</$text> baz</paragraph>'
 			);
 
-			expect( model.document.selection.hasAttribute( 'linkHref' ) ).to.be.false;
+			expect( model.document.selection ).to.not.have.attribute( 'linkHref' );
 
 			model.change( writer => {
 				writer.setSelectionAttribute( 'linkHref', 'url' );
 			} );
 
-			expect( model.document.selection.hasAttribute( 'linkHref' ) ).to.be.true;
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
 			expect( getViewData( view ) ).to.equal(
 				'<p>foo <a class="ck-link_selected" href="url">{}bar</a> baz</p>'
 			);
@@ -403,7 +405,7 @@ describe( 'LinkEditing', () => {
 				'<paragraph>foo <$text linkHref="url">bar</$text>{} baz</paragraph>'
 			);
 
-			expect( model.document.selection.hasAttribute( 'linkHref' ) ).to.be.true;
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
 			expect( getViewData( view ) ).to.equal(
 				'<p>foo <a class="ck-link_selected" href="url">bar{}</a> baz</p>'
 			);
@@ -421,7 +423,11 @@ describe( 'LinkEditing', () => {
 				'<paragraph><$text linkHref="url">[]nk</$text> baz</paragraph>'
 			);
 
-			expect( model.document.selection.hasAttribute( 'linkHref' ) ).to.be.true;
+			expect( model.document.selection ).to.have.attribute( 'linkHref' );
+			expect( getViewData( view ) ).to.equal(
+				'<p>foo <a href="url">li</a></p>' +
+				'<p><a class="ck-link_selected" href="url">{}nk</a> baz</p>'
+			);
 		} );
 
 		it( 'should remove classes when selection is moved out from the link', () => {

+ 21 - 20
packages/ckeditor5-list/src/converters.js

@@ -57,7 +57,8 @@ export function modelViewInsertion( model ) {
  */
 export function modelViewRemove( model ) {
 	return ( evt, data, conversionApi ) => {
-		const viewStart = conversionApi.mapper.toViewPosition( data.position ).getLastMatchingPosition( value => !value.item.is( 'li' ) );
+		const viewPosition = conversionApi.mapper.toViewPosition( data.position );
+		const viewStart = viewPosition.getLastMatchingPosition( value => !value.item.is( 'element', 'li' ) );
 		const viewItem = viewStart.nodeAfter;
 		const viewWriter = conversionApi.writer;
 
@@ -421,7 +422,7 @@ export function cleanList( evt, data, conversionApi ) {
 		const children = Array.from( data.viewItem.getChildren() );
 
 		for ( const child of children ) {
-			const isWrongElement = !( child.is( 'li' ) || isList( child ) );
+			const isWrongElement = !( child.is( 'element', 'li' ) || isList( child ) );
 
 			if ( isWrongElement ) {
 				child._remove();
@@ -454,7 +455,7 @@ export function cleanListItem( evt, data, conversionApi ) {
 				child._remove();
 			}
 
-			if ( child.is( 'text' ) ) {
+			if ( child.is( '$text' ) ) {
 				// If this is the first node and it's a text node, left-trim it.
 				if ( firstNode ) {
 					child._data = child.data.replace( /^\s+/, '' );
@@ -491,13 +492,13 @@ export function modelToViewPosition( view ) {
 
 		const modelItem = data.modelPosition.nodeBefore;
 
-		if ( modelItem && modelItem.is( 'listItem' ) ) {
+		if ( modelItem && modelItem.is( 'element', 'listItem' ) ) {
 			const viewItem = data.mapper.toViewElement( modelItem );
 			const topmostViewList = viewItem.getAncestors().find( isList );
 			const walker = view.createPositionAt( viewItem, 0 ).getWalker();
 
 			for ( const value of walker ) {
-				if ( value.type == 'elementStart' && value.item.is( 'li' ) ) {
+				if ( value.type == 'elementStart' && value.item.is( 'element', 'li' ) ) {
 					data.viewPosition = value.previousPosition;
 
 					break;
@@ -624,7 +625,7 @@ export function modelChangePostFixer( model, writer ) {
 					applied = true;
 				}
 
-				for ( const innerItem of Array.from( model.createRangeIn( item ) ).filter( e => e.item.is( 'listItem' ) ) ) {
+				for ( const innerItem of Array.from( model.createRangeIn( item ) ).filter( e => e.item.is( 'element', 'listItem' ) ) ) {
 					_addListToFix( innerItem.previousPosition );
 				}
 			}
@@ -651,10 +652,10 @@ export function modelChangePostFixer( model, writer ) {
 	function _addListToFix( position ) {
 		const previousNode = position.nodeBefore;
 
-		if ( !previousNode || !previousNode.is( 'listItem' ) ) {
+		if ( !previousNode || !previousNode.is( 'element', 'listItem' ) ) {
 			const item = position.nodeAfter;
 
-			if ( item && item.is( 'listItem' ) ) {
+			if ( item && item.is( 'element', 'listItem' ) ) {
 				itemToListHead.set( item, item );
 			}
 		} else {
@@ -667,7 +668,7 @@ export function modelChangePostFixer( model, writer ) {
 			for (
 				// Cache previousSibling and reuse for performance reasons. See #6581.
 				let previousSibling = listHead.previousSibling;
-				previousSibling && previousSibling.is( 'listItem' );
+				previousSibling && previousSibling.is( 'element', 'listItem' );
 				previousSibling = listHead.previousSibling
 			) {
 				listHead = previousSibling;
@@ -685,7 +686,7 @@ export function modelChangePostFixer( model, writer ) {
 		let maxIndent = 0;
 		let fixBy = null;
 
-		while ( item && item.is( 'listItem' ) ) {
+		while ( item && item.is( 'element', 'listItem' ) ) {
 			const itemIndent = item.getAttribute( 'listIndent' );
 
 			if ( itemIndent > maxIndent ) {
@@ -718,7 +719,7 @@ export function modelChangePostFixer( model, writer ) {
 		let typesStack = [];
 		let prev = null;
 
-		while ( item && item.is( 'listItem' ) ) {
+		while ( item && item.is( 'element', 'listItem' ) ) {
 			const itemIndent = item.getAttribute( 'listIndent' );
 
 			if ( prev && prev.getAttribute( 'listIndent' ) > itemIndent ) {
@@ -784,14 +785,14 @@ export function modelIndentPasteFixer( evt, [ content, selectable ] ) {
 		selection = this.createSelection( selectable );
 	}
 
-	if ( item && item.is( 'listItem' ) ) {
+	if ( item && item.is( 'element', 'listItem' ) ) {
 		// Get a reference list item. Inserted list items will be fixed according to that item.
 		const pos = selection.getFirstPosition();
 		let refItem = null;
 
-		if ( pos.parent.is( 'listItem' ) ) {
+		if ( pos.parent.is( 'element', 'listItem' ) ) {
 			refItem = pos.parent;
-		} else if ( pos.nodeBefore && pos.nodeBefore.is( 'listItem' ) ) {
+		} else if ( pos.nodeBefore && pos.nodeBefore.is( 'element', 'listItem' ) ) {
 			refItem = pos.nodeBefore;
 		}
 
@@ -805,7 +806,7 @@ export function modelIndentPasteFixer( evt, [ content, selectable ] ) {
 			// Fix only if there is anything to fix.
 			if ( indentChange > 0 ) {
 				// Adjust indent of all "first" list items in inserted data.
-				while ( item && item.is( 'listItem' ) ) {
+				while ( item && item.is( 'element', 'listItem' ) ) {
 					item._setAttribute( 'listIndent', item.getAttribute( 'listIndent' ) + indentChange );
 
 					item = item.nextSibling;
@@ -873,7 +874,7 @@ function viewToModelListItemChildrenConverter( listItemModel, viewChildren, conv
 				//
 				// We need to check for such cases and use proper list item and position based on it.
 				//
-				if ( result.modelCursor.parent.is( 'listItem' ) ) {
+				if ( result.modelCursor.parent.is( 'element', 'listItem' ) ) {
 					// (1).
 					listItemModel = result.modelCursor.parent;
 				} else {
@@ -897,7 +898,7 @@ function findNextListItem( startPosition ) {
 
 	do {
 		value = treeWalker.next();
-	} while ( !value.value.item.is( 'listItem' ) );
+	} while ( !value.value.item.is( 'element', 'listItem' ) );
 
 	return value.value.item;
 }
@@ -1004,7 +1005,7 @@ function hoistNestedLists( nextIndent, modelRemoveStartPosition, viewRemoveStart
 // @param {module:engine/view/element~Element} viewElement
 // @returns {Boolean}
 function isList( viewElement ) {
-	return viewElement.is( 'ol' ) || viewElement.is( 'ul' );
+	return viewElement.is( 'element', 'ol' ) || viewElement.is( 'element', 'ul' );
 }
 
 // Calculates the indent value for a list item. Handles HTML compliant and non-compliant lists.
@@ -1044,7 +1045,7 @@ function getIndent( listItem ) {
 
 	while ( parent ) {
 		// Each LI in the tree will result in an increased indent for HTML compliant lists.
-		if ( parent.is( 'li' ) ) {
+		if ( parent.is( 'element', 'li' ) ) {
 			indent++;
 		} else {
 			// If however the list is nested in other list we should check previous sibling of any of the list elements...
@@ -1056,7 +1057,7 @@ function getIndent( listItem ) {
 			//		|-> LI (parent LIs: 0)            |-> LI         (indent: 0)
 			//		|-> OL                                |-> OL
 			//		    |-> LI (parent LIs: 0)                |-> LI (indent: 1)
-			if ( previousSibling && previousSibling.is( 'li' ) ) {
+			if ( previousSibling && previousSibling.is( 'element', 'li' ) ) {
 				indent++;
 			}
 		}

+ 2 - 2
packages/ckeditor5-list/src/indentcommand.js

@@ -104,7 +104,7 @@ export default class IndentCommand extends Command {
 		const listItem = first( this.editor.model.document.selection.getSelectedBlocks() );
 
 		// If selection is not in a list item, the command is disabled.
-		if ( !listItem || !listItem.is( 'listItem' ) ) {
+		if ( !listItem || !listItem.is( 'element', 'listItem' ) ) {
 			return false;
 		}
 
@@ -116,7 +116,7 @@ export default class IndentCommand extends Command {
 
 			let prev = listItem.previousSibling;
 
-			while ( prev && prev.is( 'listItem' ) && prev.getAttribute( 'listIndent' ) >= indent ) {
+			while ( prev && prev.is( 'element', 'listItem' ) && prev.getAttribute( 'listIndent' ) >= indent ) {
 				if ( prev.getAttribute( 'listIndent' ) == indent ) {
 					// The item is on the same level.
 					// If it has same type, it means that we found a preceding sibling from the same list.

+ 4 - 4
packages/ckeditor5-list/src/listcommand.js

@@ -176,7 +176,7 @@ export default class ListCommand extends Command {
 				let lowestIndent = Number.POSITIVE_INFINITY;
 
 				for ( const item of blocks ) {
-					if ( item.is( 'listItem' ) && item.getAttribute( 'listIndent' ) < lowestIndent ) {
+					if ( item.is( 'element', 'listItem' ) && item.getAttribute( 'listIndent' ) < lowestIndent ) {
 						lowestIndent = item.getAttribute( 'listIndent' );
 					}
 				}
@@ -224,7 +224,7 @@ export default class ListCommand extends Command {
 		// Check whether closest `listItem` ancestor of the position has a correct type.
 		const listItem = first( this.editor.model.document.selection.getSelectedBlocks() );
 
-		return !!listItem && listItem.is( 'listItem' ) && listItem.getAttribute( 'listType' ) == this.type;
+		return !!listItem && listItem.is( 'element', 'listItem' ) && listItem.getAttribute( 'listType' ) == this.type;
 	}
 
 	/**
@@ -265,7 +265,7 @@ function _fixType( blocks, isBackward, lowestIndent ) {
 	// We need to check previous sibling of first changed item and next siblings of last changed item.
 	const startingItem = isBackward ? blocks[ 0 ] : blocks[ blocks.length - 1 ];
 
-	if ( startingItem.is( 'listItem' ) ) {
+	if ( startingItem.is( 'element', 'listItem' ) ) {
 		let item = startingItem[ isBackward ? 'previousSibling' : 'nextSibling' ];
 		// During processing items, keeps the lowest indent of already processed items.
 		// This saves us from changing too many items.
@@ -284,7 +284,7 @@ function _fixType( blocks, isBackward, lowestIndent ) {
 
 		// Look back until a list item with indent lower than reference `lowestIndent`.
 		// That would be the parent of nested sublist which contains item having `lowestIndent`.
-		while ( item && item.is( 'listItem' ) && item.getAttribute( 'listIndent' ) >= lowestIndent ) {
+		while ( item && item.is( 'element', 'listItem' ) && item.getAttribute( 'listIndent' ) >= lowestIndent ) {
 			if ( currentIndent > item.getAttribute( 'listIndent' ) ) {
 				currentIndent = item.getAttribute( 'listIndent' );
 			}

Неке датотеке нису приказане због велике количине промена