diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index aaabd1033398..797600075537 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -413,6 +413,15 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { } else { var timeout; + var deferListener = function() { + if (!timeout) { + timeout = $browser.defer(function() { + listener(); + timeout = null; + }); + } + }; + element.bind('keydown', function(event) { var key = event.keyCode; @@ -420,16 +429,16 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { // command modifiers arrows if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return; - if (!timeout) { - timeout = $browser.defer(function() { - listener(); - timeout = null; - }); - } + deferListener(); }); // if user paste into input using mouse, we need "change" event to catch it element.bind('change', listener); + + // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it + if ($sniffer.hasEvent('paste')) { + element.bind('paste cut', deferListener); + } } diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 4dcb79a38d12..e1f24afd30f9 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -309,7 +309,7 @@ describe('ngModel', function() { describe('input', function() { - var formElm, inputElm, scope, $compile, changeInputValueTo; + var formElm, inputElm, scope, $compile, $sniffer, $browser, changeInputValueTo; function compileInput(inputHtml) { inputElm = jqLite(inputHtml); @@ -318,7 +318,9 @@ describe('input', function() { $compile(formElm)(scope); } - beforeEach(inject(function($injector, $sniffer) { + beforeEach(inject(function($injector, _$sniffer_, _$browser_) { + $sniffer = _$sniffer_; + $browser = _$browser_; $compile = $injector.get('$compile'); scope = $injector.get('$rootScope'); @@ -385,6 +387,34 @@ describe('input', function() { expect(scope.name).toEqual('adam'); }); + describe('"paste" and "cut" events', function() { + beforeEach(function() { + // Force browser to report a lack of an 'input' event + $sniffer.hasEvent = function(eventName) { + return eventName !== 'input'; + }; + }); + + it('should update the model on "paste" event', function() { + compileInput(''); + + inputElm.val('mark'); + browserTrigger(inputElm, 'paste'); + $browser.defer.flush(); + expect(scope.name).toEqual('mark'); + }); + + it('should update the model on "cut" event', function() { + compileInput(''); + + inputElm.val('john'); + browserTrigger(inputElm, 'cut'); + $browser.defer.flush(); + expect(scope.name).toEqual('john'); + }); + + }); + it('should update the model and trim the value', function() { compileInput('');