ソースを参照

Added "#document" property to "view.Node" (and inherited classes) and "view.DocumentFragment".

Kamil Piechaczek 6 年 前
コミット
03967b59a0

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

@@ -471,7 +471,9 @@ class RangeParser {
 			}
 
 			text = text.replace( regexp, '' );
+
 			node._data = text;
+
 			const index = node.index;
 			const parent = node.parent;
 
@@ -927,7 +929,10 @@ class ViewStringify {
 function _convertViewElements( rootNode ) {
 	if ( rootNode.is( 'element' ) || rootNode.is( 'documentFragment' ) ) {
 		// Convert element or leave document fragment.
-		const convertedElement = rootNode.is( 'documentFragment' ) ? new ViewDocumentFragment() : _convertElement( rootNode );
+
+		const convertedElement = rootNode.is( 'documentFragment' ) ?
+			new ViewDocumentFragment( rootNode.document ) :
+			_convertElement( rootNode.document, rootNode );
 
 		// Convert all child nodes.
 		// Cache the nodes in array. Otherwise, we would skip some nodes because during iteration we move nodes
@@ -973,10 +978,10 @@ function _convertViewElements( rootNode ) {
 // module:engine/view/emptyelement~EmptyElement|module:engine/view/uielement~UIElement|
 // module:engine/view/containerelement~ContainerElement} A tree view
 // element converted according to its name.
-function _convertElement( viewElement ) {
+function _convertElement( viewDocument, viewElement ) {
 	const info = _convertElementNameAndInfo( viewElement );
 	const ElementConstructor = allowedTypes[ info.type ];
-	const newElement = ElementConstructor ? new ElementConstructor( info.name ) : new ViewElement( info.name );
+	const newElement = ElementConstructor ? new ElementConstructor( viewDocument, info.name ) : new ViewElement( viewDocument, info.name );
 
 	if ( newElement.is( 'attributeElement' ) ) {
 		if ( info.priority !== null ) {

+ 7 - 2
packages/ckeditor5-engine/src/view/attributeelement.js

@@ -33,9 +33,14 @@ export default class AttributeElement extends Element {
 	 * @see module:engine/view/downcastwriter~DowncastWriter#createAttributeElement
 	 * @see module:engine/view/element~Element
 	 * @protected
+	 * @param {module:engine/view/document~Document} document A document where the element belongs to.
+	 * @param {String} name Node name.
+	 * @param {Object|Iterable} [attrs] Collection of attributes.
+	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
+	 * A list of nodes to be inserted into created element.
 	 */
-	constructor( name, attrs, children ) {
-		super( name, attrs, children );
+	constructor( document, name, attrs, children ) {
+		super( document, name, attrs, children );
 
 		/**
 		 * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.

+ 7 - 2
packages/ckeditor5-engine/src/view/containerelement.js

@@ -37,9 +37,14 @@ export default class ContainerElement extends Element {
 	 * @see module:engine/view/downcastwriter~DowncastWriter#createContainerElement
 	 * @see module:engine/view/element~Element
 	 * @protected
+	 * @param {module:engine/view/document~Document} document A document where the element belongs to.
+	 * @param {String} name Node name.
+	 * @param {Object|Iterable} [attrs] Collection of attributes.
+	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
+	 * A list of nodes to be inserted into created element.
 	 */
-	constructor( name, attrs, children ) {
-		super( name, attrs, children );
+	constructor( document, name, attrs, children ) {
+		super( document, name, attrs, children );
 
 		/**
 		 * Returns block {@link module:engine/view/filler filler} offset or `null` if block filler is not needed.

+ 13 - 5
packages/ckeditor5-engine/src/view/documentfragment.js

@@ -25,10 +25,18 @@ export default class DocumentFragment {
 	 * Creates new DocumentFragment instance.
 	 *
 	 * @protected
+	 * @param {module:engine/view/document~Document} document A document where the document fragment belongs to.
 	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
 	 * A list of nodes to be inserted into the created document fragment.
 	 */
-	constructor( children ) {
+	constructor( document, children ) {
+		/**
+		 * A document where the document fragment belongs to.
+		 *
+		 * @member {module:engine/view/document~Document}
+		 */
+		this.document = document;
+
 		/**
 		 * Array of child nodes.
 		 *
@@ -164,7 +172,7 @@ export default class DocumentFragment {
 		this._fireChange( 'children', this );
 		let count = 0;
 
-		const nodes = normalize( items );
+		const nodes = normalize( this.document, items );
 
 		for ( const node of nodes ) {
 			// If node that is being added to this element is already inside another element, first remove it from the old parent.
@@ -238,7 +246,7 @@ mix( DocumentFragment, EmitterMixin );
 //
 // @param {String|module:engine/view/item~Item|Iterable.<String|module:engine/view/item~Item>}
 // @returns {Iterable.<module:engine/view/node~Node>}
-function normalize( nodes ) {
+function normalize( document, nodes ) {
 	// Separate condition because string is iterable.
 	if ( typeof nodes == 'string' ) {
 		return [ new Text( nodes ) ];
@@ -252,11 +260,11 @@ function normalize( nodes ) {
 	return Array.from( nodes )
 		.map( node => {
 			if ( typeof node == 'string' ) {
-				return new Text( node );
+				return new Text( document, node );
 			}
 
 			if ( node instanceof TextProxy ) {
-				return new Text( node.data );
+				return new Text( document, node.data );
 			}
 
 			return node;

+ 6 - 3
packages/ckeditor5-engine/src/view/domconverter.js

@@ -14,6 +14,7 @@ import ViewElement from './element';
 import ViewPosition from './position';
 import ViewRange from './range';
 import ViewSelection from './selection';
+import ViewDocument from './document';
 import ViewDocumentFragment from './documentfragment';
 import ViewTreeWalker from './treewalker';
 import { BR_FILLER, getDataWithoutFiller, INLINE_FILLER_LENGTH, isInlineFiller, NBSP_FILLER, startsWithFiller } from './filler';
@@ -386,6 +387,8 @@ export default class DomConverter {
 			return null;
 		}
 
+		const viewDocument = new ViewDocument();
+
 		// When node is inside UIElement return that UIElement as it's view representation.
 		const uiElement = this.getParentUIElement( domNode, this._domToViewMapping );
 
@@ -399,7 +402,7 @@ export default class DomConverter {
 			} else {
 				const textData = this._processDataFromDomText( domNode );
 
-				return textData === '' ? null : new ViewText( textData );
+				return textData === '' ? null : new ViewText( viewDocument, textData );
 			}
 		} else if ( this.isComment( domNode ) ) {
 			return null;
@@ -412,7 +415,7 @@ export default class DomConverter {
 
 			if ( this.isDocumentFragment( domNode ) ) {
 				// Create view document fragment.
-				viewElement = new ViewDocumentFragment();
+				viewElement = new ViewDocumentFragment( viewDocument );
 
 				if ( options.bind ) {
 					this.bindDocumentFragments( domNode, viewElement );
@@ -420,7 +423,7 @@ export default class DomConverter {
 			} else {
 				// Create view element.
 				const viewName = options.keepOriginalCase ? domNode.tagName : domNode.tagName.toLowerCase();
-				viewElement = new ViewElement( viewName );
+				viewElement = new ViewElement( viewDocument, viewName );
 
 				if ( options.bind ) {
 					this.bindElements( domNode, viewElement );

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

@@ -145,7 +145,7 @@ export default class DowncastWriter {
 	 * @returns {module:engine/view/text~Text} The created text node.
 	 */
 	createText( data ) {
-		return new Text( data );
+		return new Text( this.document, data );
 	}
 
 	/**
@@ -168,7 +168,7 @@ export default class DowncastWriter {
 	 * @returns {module:engine/view/attributeelement~AttributeElement} Created element.
 	 */
 	createAttributeElement( name, attributes, options = {} ) {
-		const attributeElement = new AttributeElement( name, attributes );
+		const attributeElement = new AttributeElement( this.document, name, attributes );
 
 		if ( options.priority ) {
 			attributeElement._priority = options.priority;
@@ -200,7 +200,7 @@ export default class DowncastWriter {
 	 * @returns {module:engine/view/containerelement~ContainerElement} Created element.
 	 */
 	createContainerElement( name, attributes ) {
-		return new ContainerElement( name, attributes );
+		return new ContainerElement( this.document, name, attributes );
 	}
 
 	/**
@@ -214,7 +214,7 @@ export default class DowncastWriter {
 	 * @returns {module:engine/view/editableelement~EditableElement} Created element.
 	 */
 	createEditableElement( name, attributes ) {
-		const editableElement = new EditableElement( name, attributes );
+		const editableElement = new EditableElement( this.document, name, attributes );
 		editableElement._document = this.document;
 
 		return editableElement;
@@ -231,7 +231,7 @@ export default class DowncastWriter {
 	 * @returns {module:engine/view/emptyelement~EmptyElement} Created element.
 	 */
 	createEmptyElement( name, attributes ) {
-		return new EmptyElement( name, attributes );
+		return new EmptyElement( this.document, name, attributes );
 	}
 
 	/**
@@ -255,7 +255,7 @@ export default class DowncastWriter {
 	 * @returns {module:engine/view/uielement~UIElement} Created element.
 	 */
 	createUIElement( name, attributes, renderFunction ) {
-		const uiElement = new UIElement( name, attributes );
+		const uiElement = new UIElement( this.document, name, attributes );
 
 		if ( renderFunction ) {
 			uiElement.render = renderFunction;
@@ -1807,7 +1807,7 @@ function breakTextNode( position ) {
 	position.parent._data = position.parent.data.slice( 0, position.offset );
 
 	// Insert new text node after position's parent text node.
-	position.parent.parent._insertChild( position.parent.index + 1, new Text( textToMove ) );
+	position.parent.parent._insertChild( position.parent.index + 1, new Text( position.parent.document, textToMove ) );
 
 	// Return new position between two newly created text nodes.
 	return new Position( position.parent.parent, position.parent.index + 1 );

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

@@ -53,13 +53,14 @@ export default class Element extends Node {
 	 *		new Element( 'div', mapOfAttributes ); // map
 	 *
 	 * @protected
+	 * @param {module:engine/view/document~Document} document A document where the element belongs to.
 	 * @param {String} name Node name.
 	 * @param {Object|Iterable} [attrs] Collection of attributes.
 	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
 	 * A list of nodes to be inserted into created element.
 	 */
-	constructor( name, attrs, children ) {
-		super();
+	constructor( document, name, attrs, children ) {
+		super( document );
 
 		/**
 		 * Name of the element.

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

@@ -28,11 +28,14 @@ export default class EmptyElement extends Element {
 	 *
 	 * @see module:engine/view/downcastwriter~DowncastWriter#createEmptyElement
 	 * @protected
+	 * @param {module:engine/view/document~Document} document A document where the element belongs to.
 	 * @param {String} name Node name.
-	 * @param {Object|Iterable} [attributes] Collection of attributes.
+	 * @param {Object|Iterable} [attrs] Collection of attributes.
+	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
+	 * A list of nodes to be inserted into created element.
 	 */
-	constructor( name, attributes, children ) {
-		super( name, attributes, children );
+	constructor( document, name, attrs, children ) {
+		super( document, name, attrs, children );
 
 		/**
 		 * Returns `null` because filler is not needed for EmptyElements.

+ 18 - 9
packages/ckeditor5-engine/src/view/node.js

@@ -28,8 +28,17 @@ import '@ckeditor/ckeditor5-utils/src/version';
 export default class Node {
 	/**
 	 * Creates a tree view node.
+	 *
+	 * @param {module:engine/view/document~Document} document A document where the node belongs to.
 	 */
-	constructor() {
+	constructor( document ) {
+		/**
+		 * A document where the node belongs to.
+		 *
+		 * @member {module:engine/view/document~Document}
+		 */
+		this.document = document;
+
 		/**
 		 * Parent element. Null by default. Set by {@link module:engine/view/element~Element#_insertChild}.
 		 *
@@ -115,14 +124,14 @@ export default class Node {
 	 * @readonly
 	 * @type {module:engine/view/document~Document|null}
 	 */
-	get document() {
-		// Parent might be Node, null or DocumentFragment.
-		if ( this.parent instanceof Node ) {
-			return this.parent.document;
-		} else {
-			return null;
-		}
-	}
+	// get document() {
+	// 	// Parent might be Node, null or DocumentFragment.
+	// 	if ( this.parent instanceof Node ) {
+	// 		return this.parent.document;
+	// 	} else {
+	// 		return null;
+	// 	}
+	// }
 
 	/**
 	 * Gets a path to the node. The path is an array containing indices of consecutive ancestors of this node,

+ 4 - 3
packages/ckeditor5-engine/src/view/text.js

@@ -25,10 +25,11 @@ export default class Text extends Node {
 	 * Creates a tree view text node.
 	 *
 	 * @protected
+	 * @param {module:engine/view/document~Document} document A document where the text belongs to.
 	 * @param {String} data The text's data.
 	 */
-	constructor( data ) {
-		super();
+	constructor( document, data ) {
+		super( document );
 
 		/**
 		 * The text content.
@@ -125,7 +126,7 @@ export default class Text extends Node {
 	 * @returns {module:engine/view/text~Text} Text node that is a clone of this node.
 	 */
 	_clone() {
-		return new Text( this.data );
+		return new Text( this.document, this.data );
 	}
 
 	// @if CK_DEBUG_ENGINE // toString() {

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

@@ -41,11 +41,14 @@ export default class UIElement extends Element {
 	 *
 	 * @see module:engine/view/downcastwriter~DowncastWriter#createUIElement
 	 * @protected
+	 * @param {module:engine/view/document~Document} document A document where the element belongs to.
 	 * @param {String} name Node name.
-	 * @param {Object|Iterable} [attributes] Collection of attributes.
+	 * @param {Object|Iterable} [attrs] Collection of attributes.
+	 * @param {module:engine/view/node~Node|Iterable.<module:engine/view/node~Node>} [children]
+	 * A list of nodes to be inserted into created element.
 	 */
-	constructor( name, attributes, children ) {
-		super( name, attributes, children );
+	constructor( document, name, attrs, children ) {
+		super( document, name, attrs, children );
 
 		/**
 		 * Returns `null` because filler is not needed for UIElements.

+ 1 - 0
packages/ckeditor5-engine/tests/view/downcastwriter/insert.js

@@ -29,6 +29,7 @@ describe( 'DowncastWriter', () => {
 			const { view, selection } = parse( input );
 
 			const newRange = writer.insert( selection.getFirstPosition(), nodesToInsert );
+
 			expect( stringify( view.root, newRange, { showType: true, showPriority: true } ) ).to.equal( expected );
 		}