mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
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 #3682
345 lines
9.2 KiB
JavaScript
345 lines
9.2 KiB
JavaScript
'use strict';
|
|
|
|
describe('$sniffer', function() {
|
|
|
|
function sniffer($window, $document) {
|
|
$window.navigator = {};
|
|
$document = jqLite($document || {});
|
|
if (!$document[0].body) {
|
|
$document[0].body = window.document.body;
|
|
}
|
|
return new $SnifferProvider().$get[2]($window, $document);
|
|
}
|
|
|
|
describe('history', function() {
|
|
it('should be true if history.pushState defined', function() {
|
|
expect(sniffer({history: {pushState: noop, replaceState: noop}}).history).toBe(true);
|
|
});
|
|
|
|
it('should be false if history or pushState not defined', function() {
|
|
expect(sniffer({history: {}}).history).toBe(false);
|
|
expect(sniffer({}).history).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('hashchange', function() {
|
|
it('should be true if onhashchange property defined', function() {
|
|
expect(sniffer({onhashchange: true}).hashchange).toBe(true);
|
|
});
|
|
|
|
it('should be false if onhashchange property not defined', function() {
|
|
expect(sniffer({}).hashchange).toBe(false);
|
|
});
|
|
|
|
it('should be false if documentMode is 7 (IE8 comp mode)', function() {
|
|
expect(sniffer({onhashchange: true}, {documentMode: 7}).hashchange).toBe(false);
|
|
});
|
|
});
|
|
|
|
|
|
describe('hasEvent', function() {
|
|
var mockDocument, mockDivElement, $sniffer;
|
|
|
|
beforeEach(function() {
|
|
mockDocument = {createElement: jasmine.createSpy('createElement')};
|
|
mockDocument.createElement.andCallFake(function(elm) {
|
|
if (elm === 'div') return mockDivElement;
|
|
});
|
|
|
|
$sniffer = sniffer({}, mockDocument);
|
|
});
|
|
|
|
|
|
it('should return true if "onchange" is present in a div element', function() {
|
|
mockDivElement = {onchange: noop};
|
|
|
|
expect($sniffer.hasEvent('change')).toBe(true);
|
|
});
|
|
|
|
|
|
it('should return false if "oninput" is not present in a div element', function() {
|
|
mockDivElement = {};
|
|
|
|
expect($sniffer.hasEvent('input')).toBe(false);
|
|
});
|
|
|
|
|
|
it('should only create the element once', function() {
|
|
mockDivElement = {};
|
|
|
|
$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);
|
|
});
|
|
});
|
|
|
|
|
|
describe('csp', function() {
|
|
it('should be false if document.securityPolicy.isActive not available', function() {
|
|
expect(sniffer({}).csp).toBe(false);
|
|
});
|
|
|
|
|
|
it('should use document.securityPolicy.isActive if available', function() {
|
|
var createDocumentWithCSP = function(csp) {
|
|
return {securityPolicy: {isActive: csp}};
|
|
};
|
|
|
|
expect(sniffer({}, createDocumentWithCSP(false)).csp).toBe(false);
|
|
expect(sniffer({}, createDocumentWithCSP(true)).csp).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('vendorPrefix', function() {
|
|
|
|
it('should return the correct vendor prefix based on the browser', function() {
|
|
inject(function($sniffer, $window) {
|
|
var expectedPrefix;
|
|
var ua = $window.navigator.userAgent.toLowerCase();
|
|
if(/chrome/i.test(ua) || /safari/i.test(ua) || /webkit/i.test(ua)) {
|
|
expectedPrefix = 'Webkit';
|
|
}
|
|
else if(/firefox/i.test(ua)) {
|
|
expectedPrefix = 'Moz';
|
|
}
|
|
else if(/ie/i.test(ua) || /trident/i.test(ua)) {
|
|
expectedPrefix = 'Ms';
|
|
}
|
|
else if(/opera/i.test(ua)) {
|
|
expectedPrefix = 'O';
|
|
}
|
|
expect($sniffer.vendorPrefix).toBe(expectedPrefix);
|
|
});
|
|
});
|
|
|
|
it('should still work for an older version of Webkit', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
WebkitOpacity: '0'
|
|
}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.vendorPrefix).toBe('webkit');
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
describe('animations', function() {
|
|
it('should be either true or false', function() {
|
|
inject(function($sniffer) {
|
|
expect($sniffer.animations).not.toBe(undefined);
|
|
});
|
|
});
|
|
|
|
it('should be false when there is no animation style', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.animations).toBe(false);
|
|
});
|
|
});
|
|
|
|
it('should be true with vendor-specific animations', function() {
|
|
module(function($provide) {
|
|
var animationStyle = 'some_animation 2s linear';
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
WebkitAnimation : animationStyle,
|
|
MozAnimation : animationStyle,
|
|
OAnimation : animationStyle
|
|
}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.animations).toBe(true);
|
|
});
|
|
});
|
|
|
|
it('should be true with w3c-style animations', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
animation : 'some_animation 2s linear'
|
|
}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.animations).toBe(true);
|
|
});
|
|
});
|
|
|
|
it('should be true on android with older body style properties', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
webkitAnimation: ''
|
|
}
|
|
}
|
|
};
|
|
var win = {
|
|
navigator: {
|
|
userAgent: 'android 2'
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
$provide.value('$window', win);
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.animations).toBe(true);
|
|
});
|
|
});
|
|
|
|
it('should be true when an older version of Webkit is used', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
WebkitOpacity: '0'
|
|
}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.animations).toBe(false);
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
describe('transitions', function() {
|
|
|
|
it('should be either true or false', function() {
|
|
inject(function($sniffer) {
|
|
expect($sniffer.transitions).not.toBe(undefined);
|
|
});
|
|
});
|
|
|
|
it('should be false when there is no transition style', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.transitions).toBe(false);
|
|
});
|
|
});
|
|
|
|
it('should be true with vendor-specific transitions', function() {
|
|
module(function($provide) {
|
|
var transitionStyle = '1s linear all';
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
WebkitTransition : transitionStyle,
|
|
MozTransition : transitionStyle,
|
|
OTransition : transitionStyle
|
|
}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.transitions).toBe(true);
|
|
});
|
|
});
|
|
|
|
it('should be true with w3c-style transitions', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
transition : '1s linear all'
|
|
}
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.transitions).toBe(true);
|
|
});
|
|
});
|
|
|
|
it('should be true on android with older body style properties', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {
|
|
webkitTransition: ''
|
|
}
|
|
}
|
|
};
|
|
var win = {
|
|
navigator: {
|
|
userAgent: 'android 2'
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
$provide.value('$window', win);
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.transitions).toBe(true);
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
|
|
describe('history', function() {
|
|
it('should be true on Boxee box with an older version of Webkit', function() {
|
|
module(function($provide) {
|
|
var doc = {
|
|
body : {
|
|
style : {}
|
|
}
|
|
};
|
|
var win = {
|
|
history: {
|
|
pushState: noop
|
|
},
|
|
navigator: {
|
|
userAgent: 'boxee (alpha/Darwin 8.7.1 i386 - 0.9.11.5591)'
|
|
}
|
|
};
|
|
$provide.value('$document', jqLite(doc));
|
|
$provide.value('$window', win);
|
|
});
|
|
inject(function($sniffer) {
|
|
expect($sniffer.history).toBe(false);
|
|
});
|
|
});
|
|
});
|
|
});
|