8
0
Просмотр исходного кода

Expose more granular utils so we can optimize code outside the position module.

Piotrek Koszuliński 5 лет назад
Родитель
Сommit
d27cb83f04

+ 21 - 17
packages/ckeditor5-engine/src/model/position.js

@@ -225,16 +225,10 @@ export default class Position {
 	 * @type {module:engine/model/node~Node|null}
 	 */
 	get nodeAfter() {
-		// Cache parent and reuse for performance reasons. This also means that we cannot use the #index property.
-		// See #6579.
+		// Cache the parent and reuse for performance reasons. See #6579 and #6582.
 		const parent = this.parent;
-		const textNode = getTextNode( this, parent );
 
-		if ( textNode !== null ) {
-			return null;
-		}
-
-		return parent.getChild( parent.offsetToIndex( this.offset ) );
+		return getNodeAfter( this, parent, getTextNode( this, parent ) );
 	}
 
 	/**
@@ -244,16 +238,10 @@ export default class Position {
 	 * @type {module:engine/model/node~Node|null}
 	 */
 	get nodeBefore() {
-		// Cache parent and reuse for performance reasons. This also means that we cannot use the #index property.
-		// See #6579.
+		// Cache the parent and reuse for performance reasons. See #6579 and #6582.
 		const parent = this.parent;
-		const textNode = getTextNode( this, parent );
-
-		if ( textNode !== null ) {
-			return null;
-		}
 
-		return parent.getChild( parent.offsetToIndex( this.offset ) - 1 );
+		return getNodeBefore( this, parent, getTextNode( this, parent ) );
 	}
 
 	/**
@@ -1078,7 +1066,7 @@ export default class Position {
 // Helper function used to inline text node access by using a cached parent.
 // Reduces the access to the Position#parent property 3 times (in total, when taken into account what #nodeAfter and #nodeBefore do).
 // See #6579.
-function getTextNode( position, positionParent ) {
+export function getTextNode( position, positionParent ) {
 	const node = positionParent.getChild( positionParent.offsetToIndex( position.offset ) );
 
 	if ( node && node.is( 'text' ) && node.startOffset < position.offset ) {
@@ -1087,3 +1075,19 @@ function getTextNode( position, positionParent ) {
 
 	return null;
 }
+
+export function getNodeAfter( position, positionParent, textNode ) {
+	if ( textNode !== null ) {
+		return null;
+	}
+
+	return positionParent.getChild( positionParent.offsetToIndex( position.offset ) );
+}
+
+export function getNodeBefore( position, positionParent, textNode ) {
+	if ( textNode !== null ) {
+		return null;
+	}
+
+	return positionParent.getChild( positionParent.offsetToIndex( position.offset ) - 1 );
+}

+ 14 - 5
packages/ckeditor5-engine/src/model/treewalker.js

@@ -10,7 +10,12 @@
 import Text from './text';
 import TextProxy from './textproxy';
 import Element from './element';
-import Position from './position';
+import {
+	default as Position,
+	getTextNode as getTextNodeAtPosition,
+	getNodeAfter as getNodeAfterPosition,
+	getNodeBefore as getNodeBeforePosition
+} from './position';
 import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
@@ -226,8 +231,10 @@ export default class TreeWalker {
 		}
 
 		// Get node just after the current position.
-		const textNodeAtPosition = position.textNode;
-		const node = textNodeAtPosition ? textNodeAtPosition : position.nodeAfter;
+		// Use a highly optimized version instead of checking the text node first and then getting the node after. See #6582.
+		const positionParent = position.parent;
+		const textNodeAtPosition = getTextNodeAtPosition( position, positionParent );
+		const node = textNodeAtPosition ? textNodeAtPosition : getNodeAfterPosition( position, positionParent, textNodeAtPosition );
 
 		if ( node instanceof Element ) {
 			if ( !this.shallow ) {
@@ -302,8 +309,10 @@ export default class TreeWalker {
 		}
 
 		// Get node just before the current position.
-		const textNodeAtPosition = position.textNode;
-		const node = textNodeAtPosition ? textNodeAtPosition : position.nodeBefore;
+		// Use a highly optimized version instead of checking the text node first and then getting the node before. See #6582.
+		const positionParent = position.parent;
+		const textNodeAtPosition = getTextNodeAtPosition( position, positionParent );
+		const node = textNodeAtPosition ? textNodeAtPosition : getNodeBeforePosition( position, positionParent, textNodeAtPosition );
 
 		if ( node instanceof Element ) {
 			position.offset--;