Browse Source

Sort DomCoverter methods. User DOM utils.

Piotr Jasiun 9 years ago
parent
commit
e4c0022971

+ 114 - 123
packages/ckeditor5-engine/src/treeview/domconverter.js

@@ -12,6 +12,8 @@ import ViewRange from './range.js';
 import ViewSelection from './selection.js';
 import ViewDocumentFragment from './documentfragment.js';
 
+import indexOf from '../../utils/dom/indexof.js';
+
 export const BR_FILLER = ( domDocument ) => {
 	const fillerBr = domDocument.createElement( 'br' );
 	fillerBr.dataset.filler = true;
@@ -45,7 +47,7 @@ export default class DomConverter {
 	/**
 	 * Creates DOM converter.
 	 */
-	constructor( options = { blockFiller: BR_FILLER } ) {
+	constructor( options = {} ) {
 		// Using WeakMap prevent memory leaks: when the converter will be destroyed all referenced between View and DOM
 		// will be removed. Also because it is a *Weak*Map when both view and DOM elements will be removed referenced
 		// will be also removed, isn't it brilliant?
@@ -70,9 +72,9 @@ export default class DomConverter {
 		 */
 		this._viewToDomMapping = new WeakMap();
 
-		this.blockFillerCreator = options.blockFiller;
+		this.blockFillerCreator = options.blockFiller || BR_FILLER;
 
-		this._templateBlockFiller = options.blockFiller( window.document );
+		this._templateBlockFiller = this.blockFillerCreator( window.document );
 	}
 
 	/**
@@ -172,6 +174,51 @@ export default class DomConverter {
 		}
 	}
 
+	viewRangeToDom( viewRange ) {
+		const domStart = this.viewPositionToDom( viewRange.start );
+		const domEnd = this.viewPositionToDom( viewRange.end );
+
+		const domRange = new Range();
+		domRange.setStart( domStart.parent, domStart.offset );
+		domRange.setEnd( domEnd.parent, domEnd.offset );
+
+		return domRange;
+	}
+
+	viewPositionToDom( viewPosition ) {
+		const viewParent = viewPosition.parent;
+
+		if ( viewParent instanceof ViewText ) {
+			const domParent = this.getCorrespondingDomText( viewParent );
+			let offset = viewPosition.offset;
+
+			if ( this.startsWithFiller( domParent ) ) {
+				offset += INLINE_FILLER_SIZE;
+			}
+
+			return { parent: domParent, offset: offset };
+		} else {
+			let domParent, domBefore, domAfter;
+
+			if ( viewPosition.offset === 0 ) {
+				domParent = this.getCorrespondingDom( viewPosition.parent );
+				domAfter = domParent.childNodes[ 0 ];
+			} else {
+				domBefore = this.getCorrespondingDom( viewPosition.nodeBefore );
+				domParent = domBefore.parentNode;
+				domAfter = domBefore.nextSibling;
+			}
+
+			if ( domAfter instanceof Text && this.startsWithFiller( domAfter ) ) {
+				return { parent: domAfter, offset: INLINE_FILLER_SIZE };
+			}
+
+			const offset = domBefore ? indexOf( domBefore ) + 1 : 0;
+
+			return { parent: domParent, offset: offset };
+		}
+	}
+
 	/**
 	 * Converts DOM to view. For all text nodes, not bound elements and document fragments new items will
 	 * be created. For bound elements and document fragments function will return corresponding items.
@@ -266,6 +313,70 @@ export default class DomConverter {
 		return undefined;
 	}
 
+	domSelectionToView( domSelection ) {
+		const viewSelection = new ViewSelection();
+
+		for ( let i = 0; i < domSelection.rangeCount; i++ ) {
+			const domRange = domSelection.getRangeAt( i );
+			const viewRange = this.domRangeToView( domRange );
+
+			if ( viewRange ) {
+				viewSelection.addRange( viewRange );
+			}
+		}
+
+		return viewSelection;
+	}
+
+	domRangeToView( domRange ) {
+		const viewStart = this.domPositionToView( domRange.startContainer, domRange.startOffset );
+		const viewEnd = this.domPositionToView( domRange.endContainer, domRange.endOffset );
+
+		if ( viewStart && viewEnd ) {
+			return new ViewRange( viewStart, viewEnd );
+		}
+
+		return undefined;
+	}
+
+	domPositionToView( domParent, domOffset ) {
+		if ( this.isBlockFiller( domParent ) ) {
+			return this.domPositionToView( domParent.parentNode, indexOf( domParent ) );
+		}
+
+		if ( domParent instanceof Text ) {
+			if ( this.isInlineFiller( domParent ) ) {
+				return this.domPositionToView( domParent.parentNode, indexOf( domParent ) );
+			}
+
+			const viewParent = this.getCorrespondingViewText( domParent );
+			let offset = domOffset;
+
+			if ( this.startsWithFiller( domParent ) ) {
+				offset -= INLINE_FILLER_SIZE;
+				offset = offset < 0 ? 0 : offset;
+			}
+
+			return new ViewPosition( viewParent, offset );
+		} else {
+			if ( domOffset === 0 ) {
+				const viewParent = this.getCorrespondingView( domParent );
+
+				if ( viewParent ) {
+					return new ViewPosition( viewParent, 0 );
+				}
+			} else {
+				const viewBefore = this.getCorrespondingView( domParent.childNodes[ domOffset - 1 ] );
+
+				if ( viewBefore ) {
+					return new ViewPosition( viewBefore.parent, viewBefore.getIndex() + 1 );
+				}
+			}
+
+			return undefined;
+		}
+	}
+
 	/**
 	 * Gets corresponding view element. Returns element if an view element was
 	 * {@link engine.treeView.DomConverter#bindElements bound} to the given DOM element or null otherwise.
@@ -421,115 +532,6 @@ export default class DomConverter {
 		return null;
 	}
 
-	viewPositionToDom( viewPosition ) {
-		const viewParent = viewPosition.parent;
-
-		if ( viewParent instanceof ViewText ) {
-			const domParent = this.getCorrespondingDomText( viewParent );
-			let offset = viewPosition.offset;
-
-			if ( this.startsWithFiller( domParent ) ) {
-				offset += INLINE_FILLER_SIZE;
-			}
-
-			return { parent: domParent, offset: offset };
-		} else {
-			let domParent, domBefore, domAfter;
-
-			if ( viewPosition.offset === 0 ) {
-				domParent = this.getCorrespondingDom( viewPosition.parent );
-				domAfter = domParent.childNodes[ 0 ];
-			} else {
-				domBefore = this.getCorrespondingDom( viewPosition.nodeBefore );
-				domParent = domBefore.parentNode;
-				domAfter = domBefore.nextSibling;
-			}
-
-			if ( domAfter instanceof Text && this.startsWithFiller( domAfter ) ) {
-				return { parent: domAfter, offset: INLINE_FILLER_SIZE };
-			}
-
-			const offset = domBefore ? indexOf( domBefore ) + 1 : 0;
-
-			return { parent: domParent, offset: offset };
-		}
-	}
-
-	domPositionToView( domParent, domOffset ) {
-		if ( this.isBlockFiller( domParent ) ) {
-			return this.domPositionToView( domParent.parentNode, indexOf( domParent ) );
-		}
-
-		if ( domParent instanceof Text ) {
-			if ( this.isInlineFiller( domParent ) ) {
-				return this.domPositionToView( domParent.parentNode, indexOf( domParent ) );
-			}
-
-			const viewParent = this.getCorrespondingViewText( domParent );
-			let offset = domOffset;
-
-			if ( this.startsWithFiller( domParent ) ) {
-				offset -= INLINE_FILLER_SIZE;
-				offset = offset < 0 ? 0 : offset;
-			}
-
-			return new ViewPosition( viewParent, offset );
-		} else {
-			if ( domOffset === 0 ) {
-				const viewParent = this.getCorrespondingView( domParent );
-
-				if ( viewParent ) {
-					return new ViewPosition( viewParent, 0 );
-				}
-			} else {
-				const viewBefore = this.getCorrespondingView( domParent.childNodes[ domOffset - 1 ] );
-
-				if ( viewBefore ) {
-					return new ViewPosition( viewBefore.parent, viewBefore.getIndex() + 1 );
-				}
-			}
-
-			return undefined;
-		}
-	}
-
-	viewRangeToDom( viewRange ) {
-		const domStart = this.viewPositionToDom( viewRange.start );
-		const domEnd = this.viewPositionToDom( viewRange.end );
-
-		const domRange = new Range();
-		domRange.setStart( domStart.parent, domStart.offset );
-		domRange.setEnd( domEnd.parent, domEnd.offset );
-
-		return domRange;
-	}
-
-	domRangeToView( domRange ) {
-		const viewStart = this.domPositionToView( domRange.startContainer, domRange.startOffset );
-		const viewEnd = this.domPositionToView( domRange.endContainer, domRange.endOffset );
-
-		if ( viewStart && viewEnd ) {
-			return new ViewRange( viewStart, viewEnd );
-		}
-
-		return undefined;
-	}
-
-	domSelectionToView( domSelection ) {
-		const viewSelection = new ViewSelection();
-
-		for ( let i = 0; i < domSelection.rangeCount; i++ ) {
-			const domRange = domSelection.getRangeAt( i );
-			const viewRange = this.domRangeToView( domRange );
-
-			if ( viewRange ) {
-				viewSelection.addRange( viewRange );
-			}
-		}
-
-		return viewSelection;
-	}
-
 	startsWithFiller( domText ) {
 		return ( domText.data.substr( 0, INLINE_FILLER_SIZE ) === INLINE_FILLER );
 	}
@@ -549,15 +551,4 @@ export default class DomConverter {
 	isBlockFiller( domNode ) {
 		return domNode.isEqualNode( this._templateBlockFiller );
 	}
-}
-
-function indexOf( domNode ) {
-	let index = 0;
-
-	while ( domNode.previousSibling ) {
-		domNode = domNode.previousSibling;
-		index++;
-	}
-
-	return index;
 }

+ 4 - 2
packages/ckeditor5-engine/src/treeview/renderer.js

@@ -11,6 +11,8 @@ import ViewPosition from './position.js';
 import { INLINE_FILLER, INLINE_FILLER_SIZE } from './domconverter.js';
 
 import diff from '../../utils/diff.js';
+import insertAt from '../../utils/dom/insertat.js';
+import remove from '../../utils/dom/remove.js';
 import CKEditorError from '../../utils/ckeditorerror.js';
 
 /**
@@ -306,10 +308,10 @@ export default class Renderer {
 
 		for ( let action of actions ) {
 			if ( action === 'INSERT' ) {
-				domElement.insertBefore( expectedDomChildren[ i ], actualDomChildren[ i ] || null );
+				insertAt( domElement, i, expectedDomChildren[ i ] );
 				i++;
 			} else if ( action === 'DELETE' ) {
-				domElement.removeChild( actualDomChildren[ i ] );
+				remove( actualDomChildren[ i ] );
 			} else { // 'EQUAL'
 				i++;
 			}