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

Added findAncestor method to view.Element.

Szymon Kupś 9 лет назад
Родитель
Сommit
4b481d84ab

+ 24 - 0
packages/ckeditor5-engine/src/view/element.js

@@ -8,6 +8,7 @@ import Text from './text.js';
 import objectToMap from '../../utils/objecttomap.js';
 import isIterable from '../../utils/isiterable.js';
 import isPlainObject from '../../utils/lib/lodash/isPlainObject.js';
+import Matcher from './matcher.js';
 
 /**
  * View element.
@@ -568,6 +569,29 @@ export default class Element extends Node {
 		this._fireChange( 'attributes', this );
 		property.forEach( name => this._styles.delete( name ) );
 	}
+
+	/**
+	 * Returns ancestor element that match specified pattern.
+	 * Provided patterns should be compatible with {@link engine.view.Matcher Matcher} as it is used internally.
+	 *
+	 * @see engine.view.Matcher
+	 * @param {Object|String|RegExp|function} patterns Patterns used to match correct ancestor. See {@link engine.view.Matcher}.
+	 * @return {engine.view.Element|null} Found element or `null` if no matching ancestor was found.
+	 */
+	findAncestor( ...patterns ) {
+		const matcher = new Matcher( ...patterns );
+		let parent = this.parent;
+
+		while ( parent !== null ) {
+			if ( matcher.match( parent ) ) {
+				return parent;
+			}
+
+			parent = parent.parent;
+		}
+
+		return null;
+	}
 }
 
 // Parses inline styles and puts property - value pairs into styles map.

+ 33 - 0
packages/ckeditor5-engine/tests/view/element.js

@@ -784,4 +784,37 @@ describe( 'Element', () => {
 			} );
 		} );
 	} );
+
+	describe( 'findAncestor', () => {
+		it( 'should return null if element have no ancestor', () => {
+			const el = new Element( 'p' );
+
+			expect( el.findAncestor( 'div' ) ).to.be.null;
+		} );
+
+		it( 'should return ancestor if matching', () => {
+			const el1 = new Element( 'p' );
+			const el2 = new Element( 'div', null, el1 );
+
+			expect( el1.findAncestor( 'div' ) ).to.equal( el2 );
+		} );
+
+		it( 'should return parent\'s ancestor if matching', () => {
+			const el1 = new Element( 'p' );
+			const el2 = new Element( 'div', null, el1 );
+			const el3 = new Element( 'div', { class: 'foo bar' }, el2 );
+
+			expect( el1.findAncestor( { class: 'foo' } ) ).to.equal( el3 );
+		} );
+
+		it( 'should return null if no matches found', () => {
+			const el1 = new Element( 'p' );
+			new Element( 'div', null, el1 );
+
+			expect( el1.findAncestor( {
+				name: 'div',
+				class: 'container'
+			} ) ).to.be.null;
+		} );
+	} );
 } );