Skip to content

Commit

Permalink
fix(core): parse IE11 UA string correctly
Browse files Browse the repository at this point in the history
It's great that IE11 wants to be compatible enough that it doesn't want
to be special cased and treated differently.

However, as long as one has to have a different code path for IE than
for the other supported browsers, we still need to detect and special
case it.  For instance, our URL parsing code still needs the same
workaround the we used for IE10.  We still see the same Access denied /
TypeError exceptions when setting certain values.  FYI, Angular doesn't
generally blindly test for IE – we also check the version number.

Thanks to modern.ie for the free IE11 test VM.

Closes angular#3682
  • Loading branch information
chirayuk authored and jamesdaily committed Jan 27, 2014
1 parent bb9c58a commit 1ba87a8
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/Angular.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/ng/urlUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 15 additions & 0 deletions test/AngularSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
});

});
6 changes: 3 additions & 3 deletions test/ng/compileSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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('<img src="{{testUrl}}"></a>')($rootScope);
Expand Down Expand Up @@ -3008,9 +3008,9 @@ describe('$compile', function() {
inject(function($compile, $rootScope) {
element = $compile('<img src="{{testUrl}}"></img>')($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()');
Expand Down
2 changes: 1 addition & 1 deletion test/ng/snifferSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down

0 comments on commit 1ba87a8

Please sign in to comment.