aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Minar2012-05-06 09:27:10 -0700
committerIgor Minar2012-05-06 23:01:33 -0700
commit49dfdf8f0238ef8c473fcb44694f6b5696ecde70 (patch)
treedb9e407863a264356d52172e089159bb5fb647a1
parent5bcb749abb91dba0847cb9bc900777a67fd55aa8 (diff)
downloadangular.js-49dfdf8f0238ef8c473fcb44694f6b5696ecde70.tar.bz2
fix(ngModel): use keydown/change events on IE9 instead of input
On IE9 the input event is not fired when backspace or delete key are pressed or when cut is performed. This makes listening on the input event unreliable and therefore it's better for us to just use keydown/change events instead. Closes #879
-rw-r--r--src/ng/directive/input.js3
-rw-r--r--src/ng/sniffer.js5
-rw-r--r--test/ng/directive/inputSpec.js2
-rw-r--r--test/ng/snifferSpec.js20
4 files changed, 22 insertions, 8 deletions
diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js
index dadf07c4..6e394afd 100644
--- a/src/ng/directive/input.js
+++ b/src/ng/directive/input.js
@@ -379,7 +379,8 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
}
};
- // if the browser does support "input" event, we are fine
+ // 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.bind('input', listener);
} else {
diff --git a/src/ng/sniffer.js b/src/ng/sniffer.js
index 5389dc86..b19e7ccf 100644
--- a/src/ng/sniffer.js
+++ b/src/ng/sniffer.js
@@ -22,6 +22,11 @@ function $SnifferProvider() {
// IE8 compatible mode lies
(!$window.document.documentMode || $window.document.documentMode > 7),
hasEvent: function(event) {
+ // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have
+ // it. In particular the event is not fired when backspace or delete key are pressed or
+ // when cut operation is performed.
+ if (event == 'input' && msie == 9) return false;
+
if (isUndefined(eventSupport[event])) {
var divElm = $window.document.createElement('div');
eventSupport[event] = 'on' + event in divElm;
diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js
index 6cecf125..45e3e1bf 100644
--- a/test/ng/directive/inputSpec.js
+++ b/test/ng/directive/inputSpec.js
@@ -254,7 +254,7 @@ describe('ngModel', function() {
expect(element.hasClass('ng-invalid-email')).toBe(true);
element.val('invalid-again');
- browserTrigger(element, $sniffer.hasEvent('input') ? 'input' : 'change');
+ browserTrigger(element, ($sniffer.hasEvent('input')) ? 'input' : 'change');
expect(element).toBeInvalid();
expect(element).toBeDirty();
expect(element.hasClass('ng-valid-email')).toBe(false);
diff --git a/test/ng/snifferSpec.js b/test/ng/snifferSpec.js
index 4e5f50ec..81a0db5e 100644
--- a/test/ng/snifferSpec.js
+++ b/test/ng/snifferSpec.js
@@ -45,10 +45,10 @@ describe('$sniffer', function() {
});
- it('should return true if "oninput" is present in a div element', function() {
- mockDivElement = {oninput: noop};
+ it('should return true if "onchange" is present in a div element', function() {
+ mockDivElement = {onchange: noop};
- expect($sniffer.hasEvent('input')).toBe(true);
+ expect($sniffer.hasEvent('change')).toBe(true);
});
@@ -62,11 +62,19 @@ describe('$sniffer', function() {
it('should only create the element once', function() {
mockDivElement = {};
- $sniffer.hasEvent('input');
- $sniffer.hasEvent('input');
- $sniffer.hasEvent('input');
+ $sniffer.hasEvent('change');
+ $sniffer.hasEvent('change');
+ $sniffer.hasEvent('change');
expect(mockDocument.createElement).toHaveBeenCalledOnce();
});
+
+
+ it('should claim that IE9 doesn\'t have support for "oninput"', function() {
+ // IE9 implementation is fubared, so it's better to pretend that it doesn't have the support
+ mockDivElement = {oninput: noop};
+
+ expect($sniffer.hasEvent('input')).toBe((msie == 9) ? false : true);
+ });
});
});