diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 969d53c634d2..103410973b59 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -34,6 +34,8 @@ var WEEK_REGEXP = /^(\d{4,})-W(\d\d)$/; var MONTH_REGEXP = /^(\d{4,})-(\d\d)$/; var TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/; +var IE_INPUTS_WITH_CLEARING = ['text', 'number', 'date', 'datetime-local', 'email', 'month', 'time', 'url', 'week']; + var PARTIAL_VALIDATION_EVENTS = 'keydown wheel mousedown'; var PARTIAL_VALIDATION_TYPES = createMap(); forEach('date,datetime-local,month,time,week'.split(','), function(type) { @@ -1126,7 +1128,11 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { }); } - var timeout; + var timeout, oldVal; + var viewValueUpdated = false, msieInput = msie >= 10 && msie <= 11; + if (msieInput && attr.type in IE_INPUTS_WITH_CLEARING) { + oldVal = element.val(); + } var listener = function(ev) { if (timeout) { @@ -1152,10 +1158,18 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { } }; + function ieListener(ev) { + var val = element.val(); + if (val === oldVal && !viewValueUpdated) return; + oldVal = val; + viewValueUpdated = false; + listener(ev); + } + // if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the // input event on backspace, delete or cut if ($sniffer.hasEvent('input')) { - element.on('input', listener); + element.on('input', msie ? ieListener : listener); } else { var deferListener = function(ev, input, origValue) { if (!timeout) { @@ -1212,6 +1226,10 @@ function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { // Workaround for Firefox validation #12102. var value = ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue; if (element.val() !== value) { + // Workaround for IE 10 & 11 input updates #11193 + if (msieInput) { + viewValueUpdated = true; + } element.val(value); } }; diff --git a/src/ng/sniffer.js b/src/ng/sniffer.js index 5bc32fdf1db6..b03dc119c2ab 100644 --- a/src/ng/sniffer.js +++ b/src/ng/sniffer.js @@ -73,7 +73,7 @@ function $SnifferProvider() { // when cut operation is performed. // IE10+ implements 'input' event but it erroneously fires under various situations, // e.g. when placeholder changes, or a form is focused. - if (event === 'input' && msie <= 11) return false; + if (event === 'input' && msie <= 9) return false; if (isUndefined(eventSupport[event])) { var divElm = document.createElement('div'); diff --git a/test/ng/snifferSpec.js b/test/ng/snifferSpec.js index dd52de11ff29..8db37378c0cb 100644 --- a/test/ng/snifferSpec.js +++ b/test/ng/snifferSpec.js @@ -135,7 +135,7 @@ describe('$sniffer', function() { // IE10+ implementation is fubared when mixed with placeholders mockDivElement = {oninput: noop}; - expect($sniffer.hasEvent('input')).toBe(!(msie && msie <= 11)); + expect($sniffer.hasEvent('input')).toBe(!(msie && msie <= 9)); }); });