diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/AngularPublic.js | 1 | ||||
| -rw-r--r-- | src/ng/directive/input.js | 121 | ||||
| -rw-r--r-- | src/ngScenario/Scenario.js | 2 | ||||
| -rw-r--r-- | src/ngScenario/dsl.js | 3 | 
4 files changed, 48 insertions, 79 deletions
| diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 8597de9c..1326bf8c 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -98,7 +98,6 @@ function publishExternalAPI(angular){              ngModel: ngModelDirective,              ngList: ngListDirective,              ngChange: ngChangeDirective, -            ngModelInstant: ngModelInstantDirective,              required: requiredDirective,              ngRequired: requiredDirective,              ngValue: ngValueDirective diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 3d53f7ca..aab12e34 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -367,12 +367,43 @@ function isEmpty(value) {  } -function textInputType(scope, element, attr, ctrl) { -  element.bind('blur', function() { -    scope.$apply(function() { -      ctrl.$setViewValue(trim(element.val())); +function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { + +  var listener = function() { +    var value = trim(element.val()); + +    if (ctrl.$viewValue !== value) { +      scope.$apply(function() { +        ctrl.$setViewValue(value); +      }); +    } +  }; + +  // if the browser does support "input" event, we are fine +  if ($sniffer.hasEvent('input')) { +    element.bind('input', listener); +  } else { +    var timeout; + +    element.bind('keydown', function(event) { +      var key = event.keyCode; + +      // ignore +      //    command            modifiers                   arrows +      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; + +      if (!timeout) { +        timeout = $browser.defer(function() { +          listener(); +          timeout = null; +        }); +      }      }); -  }); + +    // if user paste into input using mouse, we need "change" event to catch it +    element.bind('change', listener); +  } +    ctrl.$render = function() {      element.val(isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue); @@ -448,8 +479,8 @@ function textInputType(scope, element, attr, ctrl) {    }  }; -function numberInputType(scope, element, attr, ctrl) { -  textInputType(scope, element, attr, ctrl); +function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { +  textInputType(scope, element, attr, ctrl, $sniffer, $browser);    ctrl.$parsers.push(function(value) {      var empty = isEmpty(value); @@ -510,8 +541,8 @@ function numberInputType(scope, element, attr, ctrl) {    });  } -function urlInputType(scope, element, attr, ctrl) { -  textInputType(scope, element, attr, ctrl); +function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) { +  textInputType(scope, element, attr, ctrl, $sniffer, $browser);    var urlValidator = function(value) {      if (isEmpty(value) || URL_REGEXP.test(value)) { @@ -527,8 +558,8 @@ function urlInputType(scope, element, attr, ctrl) {    ctrl.$parsers.push(urlValidator);  } -function emailInputType(scope, element, attr, ctrl) { -  textInputType(scope, element, attr, ctrl); +function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) { +  textInputType(scope, element, attr, ctrl, $sniffer, $browser);    var emailValidator = function(value) {      if (isEmpty(value) || EMAIL_REGEXP.test(value)) { @@ -709,13 +740,14 @@ function checkboxInputType(scope, element, attr, ctrl) {        </doc:scenario>      </doc:example>   */ -var inputDirective = [function() { +var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) {    return {      restrict: 'E',      require: '?ngModel',      link: function(scope, element, attr, ctrl) {        if (ctrl) { -        (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrl); +        (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrl, $sniffer, +                                                            $browser);        }      }    }; @@ -1004,69 +1036,6 @@ var ngChangeDirective = valueFn({  }); -/** - * @ngdoc directive - * @name angular.module.ng.$compileProvider.directive.ng-model-instant - * - * @element input - * - * @description - * By default, Angular udpates the model only on `blur` event - when the input looses focus. - * If you want to update after every key stroke, use `ng-model-instant`. - * - * @example - * <doc:example> - *   <doc:source> - *     First name: <input type="text" ng-model="firstName" /><br /> - *     Last name: <input type="text" ng-model="lastName" ng-model-instant /><br /> - * - *     First name ({{firstName}}) is only updated on `blur` event, but the last name ({{lastName}}) - *     is updated immediately, because of using `ng-model-instant`. - *   </doc:source> - *   <doc:scenario> - *     it('should update first name on blur', function() { - *       input('firstName').enter('santa', 'blur'); - *       expect(binding('firstName')).toEqual('santa'); - *     }); - * - *     it('should update last name immediately', function() { - *       input('lastName').enter('santa', 'keydown'); - *       expect(binding('lastName')).toEqual('santa'); - *     }); - *   </doc:scenario> - * </doc:example> - */ -var ngModelInstantDirective = ['$browser', function($browser) { -  return { -    require: 'ngModel', -    link: function(scope, element, attr, ctrl) { -      var handler = function() { -        scope.$apply(function() { -          ctrl.$setViewValue(trim(element.val())); -        }); -      }; - -      var timeout; -      element.bind('keydown', function(event) { -        var key = event.keyCode; - -        //    command            modifiers                   arrows -        if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; - -        if (!timeout) { -          timeout = $browser.defer(function() { -            handler(); -            timeout = null; -          }); -        } -      }); - -      element.bind('change input', handler); -    } -  }; -}]; - -  var requiredDirective = [function() {    return {      require: '?ngModel', diff --git a/src/ngScenario/Scenario.js b/src/ngScenario/Scenario.js index cd3c335f..7335d5de 100644 --- a/src/ngScenario/Scenario.js +++ b/src/ngScenario/Scenario.js @@ -327,7 +327,7 @@ function browserTrigger(element, type, keys) {  (function(fn){    var parentTrigger = fn.trigger;    fn.trigger = function(type) { -    if (/(click|change|keydown|blur)/.test(type)) { +    if (/(click|change|keydown|blur|input)/.test(type)) {        var processDefaults = [];        this.each(function(index, node) {          processDefaults.push(browserTrigger(node, type)); diff --git a/src/ngScenario/dsl.js b/src/ngScenario/dsl.js index 8a1bccb1..7f399394 100644 --- a/src/ngScenario/dsl.js +++ b/src/ngScenario/dsl.js @@ -198,12 +198,13 @@ angular.scenario.dsl('binding', function() {   */  angular.scenario.dsl('input', function() {    var chain = {}; +  var supportInputEvent = 'oninput' in document.createElement('div');    chain.enter = function(value, event) {      return this.addFutureAction("input '" + this.name + "' enter '" + value + "'", function($window, $document, done) {        var input = $document.elements('[ng\\:model="$1"]', this.name).filter(':input');        input.val(value); -      input.trigger(event || 'blur'); +      input.trigger(event || supportInputEvent && 'input' || 'change');        done();      });    }; | 
