diff --git a/src/Angular.js b/src/Angular.js
index 90c7234a33bf..9e2f93f2eac6 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -58,7 +58,7 @@ if ('i' !== 'I'.toLowerCase()) {
var /** holds major version number for IE or NaN for real browsers */
- msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
+ msie,
jqLite, // delay binding since jQuery could be loaded after us.
jQuery, // delay binding
slice = [].slice,
@@ -74,6 +74,16 @@ var /** holds major version number for IE or NaN for real browsers */
nodeName_,
uid = ['0', '0', '0'];
+/**
+ * IE 11 changed the format of the UserAgent string.
+ * See http://msdn.microsoft.com/en-us/library/ms537503.aspx
+ */
+msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
+if (isNaN(msie)) {
+ msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
+}
+
+
/**
* @private
* @param {*} obj
diff --git a/src/ng/urlUtils.js b/src/ng/urlUtils.js
index c747ad9ace95..f1e31d7a3f7e 100644
--- a/src/ng/urlUtils.js
+++ b/src/ng/urlUtils.js
@@ -75,7 +75,7 @@ function $$UrlUtilsProvider() {
*/
function resolve(url, parse) {
var href = url;
- if (msie) {
+ if (msie <= 11) {
// Normalize before parse. Refer Implementation Notes on why this is
// done in two steps on IE.
urlParsingNode.setAttribute("href", href);
diff --git a/test/AngularSpec.js b/test/AngularSpec.js
index 344e2ead3c11..f6796496e74a 100644
--- a/test/AngularSpec.js
+++ b/test/AngularSpec.js
@@ -1003,4 +1003,19 @@ describe('angular', function() {
});
});
+ describe('msie UA parsing', function() {
+ if (/ Trident\/.*; rv:/.test(window.navigator.userAgent)) {
+ it('should fail when the Trident and the rv versions disagree for IE11+', function() {
+ // When this test fails, we can think about whether we want to use the version from the
+ // Trident token in the UA string or stick with the version from rv: as we currently do.
+ // Refer https://github.com/angular/angular.js/pull/3758#issuecomment-23529245 for the
+ // discussion.
+ var UA = window.navigator.userAgent;
+ var tridentVersion = parseInt((/Trident\/(\d+)/.exec(UA) || [])[1], 10) + 4;
+ var rvVersion = parseInt((/Trident\/.*; rv:(\d+)/.exec(UA) || [])[1], 10);
+ expect(tridentVersion).toBe(rvVersion);
+ });
+ }
+ });
+
});
diff --git a/test/ng/compileSpec.js b/test/ng/compileSpec.js
index 13604f6fa131..d26438783d70 100755
--- a/test/ng/compileSpec.js
+++ b/test/ng/compileSpec.js
@@ -2897,7 +2897,7 @@ describe('$compile', function() {
}));
- // Fails on IE < 10 with "TypeError: Access is denied" when trying to set img[src]
+ // Fails on IE <= 10 with "TypeError: Access is denied" when trying to set img[src]
if (!msie || msie > 10) {
it('should sanitize mailto: urls', inject(function($compile, $rootScope) {
element = $compile('')($rootScope);
@@ -3008,9 +3008,9 @@ describe('$compile', function() {
inject(function($compile, $rootScope) {
element = $compile('')($rootScope);
- // Fails on IE < 10 with "TypeError: Object doesn't support this property or method" when
+ // Fails on IE <= 11 with "TypeError: Object doesn't support this property or method" when
// trying to set img[src]
- if (!msie || msie > 10) {
+ if (!msie || msie > 11) {
$rootScope.testUrl = "javascript:doEvilStuff()";
$rootScope.$apply();
expect(element.attr('src')).toBe('javascript:doEvilStuff()');
diff --git a/test/ng/snifferSpec.js b/test/ng/snifferSpec.js
index 1bf29f735ec2..6edf9f61d740 100644
--- a/test/ng/snifferSpec.js
+++ b/test/ng/snifferSpec.js
@@ -112,7 +112,7 @@ describe('$sniffer', function() {
else if(/firefox/i.test(ua)) {
expectedPrefix = 'Moz';
}
- else if(/ie/i.test(ua)) {
+ else if(/ie/i.test(ua) || /trident/i.test(ua)) {
expectedPrefix = 'Ms';
}
else if(/opera/i.test(ua)) {