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

Tests and code refactoring in the InputTextView class.

Aleksander Nowodzinski 5 лет назад
Родитель
Сommit
e57fd79071

+ 36 - 24
packages/ckeditor5-ui/src/inputtext/inputtextview.js

@@ -83,18 +83,26 @@ export default class InputTextView extends View {
 		this.focusTracker = new FocusTracker();
 
 		/**
-		 * TODO
+		 * An observable flag set to `true` when the input is currently focused by the user.
+		 * `false` otherwise.
 		 *
+		 * @readonly
+		 * @observable
 		 * @member {Boolean} #isFocused
+		 * @default false
 		 */
 		this.bind( 'isFocused' ).to( this.focusTracker );
 
 		/**
-		 * TODO
+		 * An observable flag set to `true` when the input contains no text, i.e.
+		 * when {@link #value} is `''`, `null`, or `false`.
 		 *
+		 * @readonly
+		 * @observable
 		 * @member {Boolean} #isEmpty
+		 * @default true
 		 */
-		this.set( 'isEmpty', false );
+		this.set( 'isEmpty', true );
 
 		const bind = this.bindTemplate;
 
@@ -117,10 +125,7 @@ export default class InputTextView extends View {
 				'aria-describedby': bind.to( 'ariaDescribedById' )
 			},
 			on: {
-				input: bind.to( 'input' ),
-				change: bind.to( () => {
-					this.isEmpty = isInputElementEmpty( this.element );
-				} )
+				input: bind.to( 'input' )
 			}
 		} );
 
@@ -140,22 +145,14 @@ export default class InputTextView extends View {
 
 		this.focusTracker.add( this.element );
 
-		const setValue = value => {
-			this.element.value = ( !value && value !== 0 ) ? '' : value;
-		};
-
-		const setIsEmpty = () => {
-			this.isEmpty = isInputElementEmpty( this.element );
-		};
-
-		setValue( this.value );
-		setIsEmpty();
+		this._setDomElementValue( this.value );
+		this._updateIsEmpty();
 
 		// Bind `this.value` to the DOM element's value.
 		// We cannot use `value` DOM attribute because removing it on Edge does not clear the DOM element's value property.
 		this.on( 'change:value', ( evt, name, value ) => {
-			setValue( value );
-			setIsEmpty();
+			this._setDomElementValue( value );
+			this._updateIsEmpty();
 		} );
 	}
 
@@ -172,11 +169,26 @@ export default class InputTextView extends View {
 	focus() {
 		this.element.focus();
 	}
+
+	/**
+	 * Updates the {@link #isEmpty} property value on demand.
+	 *
+	 * @private
+	 */
+	_updateIsEmpty() {
+		this.isEmpty = isInputElementEmpty( this.element );
+	}
+
+	/**
+	 * Sets the `value` property of the {@link #element DOM element} on demand.
+	 *
+	 * @private
+	 */
+	_setDomElementValue( value ) {
+		this.element.value = ( !value && value !== 0 ) ? '' : value;
+	}
 }
 
-/**
- * TODO
- */
-function isInputElementEmpty( element ) {
-	return element.value === '';
+function isInputElementEmpty( domElement ) {
+	return !domElement.value;
 }

+ 42 - 1
packages/ckeditor5-ui/tests/inputtext/inputtextview.js

@@ -5,9 +5,10 @@
 
 /* global Event */
 
+import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
 import InputTextView from '../../src/inputtext/inputtextview';
 
-describe( 'InputTextView', () => {
+describe.only( 'InputTextView', () => {
 	let view, ariaDescribedById;
 
 	beforeEach( () => {
@@ -29,6 +30,18 @@ describe( 'InputTextView', () => {
 			expect( view.element.classList.contains( 'ck-input' ) ).to.be.true;
 			expect( view.element.classList.contains( 'ck-input-text' ) ).to.be.true;
 		} );
+
+		it( 'should set the #isFocused observable property', () => {
+			expect( view.isFocused ).to.be.false;
+		} );
+
+		it( 'should set the #isEmpty observable property', () => {
+			expect( view.isEmpty ).to.be.true;
+		} );
+
+		it( 'should create an instance of FocusTracker under #focusTracker property', () => {
+			expect( view.focusTracker ).to.be.instanceOf( FocusTracker );
+		} );
 	} );
 
 	describe( 'DOM bindings', () => {
@@ -110,6 +123,24 @@ describe( 'InputTextView', () => {
 
 				expect( view.element.classList.contains( 'ck-error' ) ).to.be.true;
 			} );
+
+			it( 'should react on view#isFocused', () => {
+				expect( view.element.classList.contains( 'ck-input_focused' ) ).to.be.false;
+
+				view.isFocused = true;
+
+				expect( view.element.classList.contains( 'ck-input_focused' ) ).to.be.true;
+			} );
+
+			it( 'should react on view#isEmpty', () => {
+				view.value = '';
+
+				expect( view.element.classList.contains( 'ck-input-text_empty' ) ).to.be.true;
+
+				view.value = 'bar';
+
+				expect( view.element.classList.contains( 'ck-input-text_empty' ) ).to.be.false;
+			} );
 		} );
 
 		describe( 'aria-invalid', () => {
@@ -144,6 +175,16 @@ describe( 'InputTextView', () => {
 		} );
 	} );
 
+	describe( 'render()', () => {
+		it( 'registers #element in the #focusTracker', () => {
+			expect( view.isFocused ).to.be.false;
+
+			view.element.dispatchEvent( new Event( 'focus' ) );
+
+			expect( view.isFocused ).to.be.true;
+		} );
+	} );
+
 	describe( 'select()', () => {
 		it( 'should select input value', () => {
 			const selectSpy = sinon.spy( view.element, 'select' );