From ebece0bcb9d64e59beb1c9b3418bed25e50ceef4 Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Thu, 17 Jul 2014 21:44:48 -0400 Subject: [PATCH] fix(input): by default, do not trim input[type=password] values Do not trim input[type=password] values BREAKING CHANGE: Previously, input[type=password] would trim values by default, and would require an explicit ng-trim="false" to disable the trimming behaviour. After this CL, ng-trim no longer effects input[type=password], and will never trim the password value. Closes #8250 Closes #8230 Conflicts: src/ng/directive/input.js --- src/ng/directive/input.js | 16 +++++++++++++--- test/ng/directive/inputSpec.js | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index f21b84669737..64d7f70b08ea 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -17,7 +17,9 @@ var inputType = { * @name input[text] * * @description - * Standard HTML text input with angular data binding. + * Standard HTML text input with angular data binding, inherited by most of the `input` elements. + * + * *NOTE* Not every feature offered is available for all input types. * * @param {string} ngModel Assignable angular expression to data-bind to. * @param {string=} name Property name of the form under which the control is published. @@ -35,6 +37,8 @@ var inputType = { * @param {string=} ngChange Angular expression to be executed when input changes due to user * interaction with the input element. * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * This parameter is ignored for input[type=password] controls, which will never trim the + * input. * * @example @@ -474,6 +478,7 @@ function addNativeHtml5Validators(ctrl, validatorName, badFlags, ignoreFlags, va function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { var validity = element.prop(VALIDITY_STATE_PROPERTY); var placeholder = element[0].placeholder, noevent = {}; + var type = element[0].type.toLowerCase(); ctrl.$$validityState = validity; // In composition mode, users are still inputing intermediate text buffer, @@ -507,8 +512,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { // By default we will trim the value // If the attribute ng-trim exists we will avoid trimming - // e.g. - if (toBoolean(attr.ngTrim || 'T')) { + // If input type is 'password', the value is never trimmed + if (type !== 'password' && (toBoolean(attr.ngTrim || 'T'))) { value = trim(value); } @@ -783,6 +788,8 @@ function checkboxInputType(scope, element, attr, ctrl) { * HTML input element control with angular data-binding. Input control follows HTML5 input types * and polyfills the HTML5 validation behavior for older browsers. * + * *NOTE* Not every feature offered is available for all input types. + * * @param {string} ngModel Assignable angular expression to data-bind to. * @param {string=} name Property name of the form under which the control is published. * @param {string=} required Sets `required` validation error key if the value is not entered. @@ -796,6 +803,9 @@ function checkboxInputType(scope, element, attr, ctrl) { * patterns defined as scope expressions. * @param {string=} ngChange Angular expression to be executed when input changes due to user * interaction with the input element. + * @param {boolean=} [ngTrim=true] If set to false Angular will not automatically trim the input. + * This parameter is ignored for input[type=password] controls, which will never trim the + * input. * * @example diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 1fc9bf57ecea..e5dd5e7e0895 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -1546,6 +1546,30 @@ describe('input', function() { expect(scope.items[0].selected).toBe(false); }); }); + + + describe('password', function() { + // Under no circumstances should input[type=password] trim inputs + it('should not trim if ngTrim is unspecified', function() { + compileInput(''); + changeInputValueTo(' - - untrimmed - - '); + expect(scope.password.length).toBe(' - - untrimmed - - '.length); + }); + + + it('should not trim if ngTrim !== false', function() { + compileInput(''); + changeInputValueTo(' - - untrimmed - - '); + expect(scope.password.length).toBe(' - - untrimmed - - '.length); + }); + + + it('should not trim if ngTrim === false', function() { + compileInput(''); + changeInputValueTo(' - - untrimmed - - '); + expect(scope.password.length).toBe(' - - untrimmed - - '.length); + }); + }); }); describe('NgModel animations', function() {