* !!! This is an undocumented "private" service !!! * * @name $sniffer * @requires $window * @requires $document * * @property {boolean} history Does the browser support html5 history api ? * @property {boolean} transitions Does the browser support CSS transition events ? * @property {boolea
()
| 18394 | * This is very simple implementation of testing browser's features. |
| 18395 | */ |
| 18396 | function $SnifferProvider() { |
| 18397 | this.$get = ['$window', '$document', function($window, $document) { |
| 18398 | var eventSupport = {}, |
| 18399 | android = |
| 18400 | toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), |
| 18401 | boxee = /Boxee/i.test(($window.navigator || {}).userAgent), |
| 18402 | document = $document[0] || {}, |
| 18403 | vendorPrefix, |
| 18404 | vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/, |
| 18405 | bodyStyle = document.body && document.body.style, |
| 18406 | transitions = false, |
| 18407 | animations = false, |
| 18408 | match; |
| 18409 | |
| 18410 | if (bodyStyle) { |
| 18411 | for (var prop in bodyStyle) { |
| 18412 | if (match = vendorRegex.exec(prop)) { |
| 18413 | vendorPrefix = match[0]; |
| 18414 | vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1); |
| 18415 | break; |
| 18416 | } |
| 18417 | } |
| 18418 | |
| 18419 | if (!vendorPrefix) { |
| 18420 | vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit'; |
| 18421 | } |
| 18422 | |
| 18423 | transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle)); |
| 18424 | animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle)); |
| 18425 | |
| 18426 | if (android && (!transitions || !animations)) { |
| 18427 | transitions = isString(bodyStyle.webkitTransition); |
| 18428 | animations = isString(bodyStyle.webkitAnimation); |
| 18429 | } |
| 18430 | } |
| 18431 | |
| 18432 | |
| 18433 | return { |
| 18434 | // Android has history.pushState, but it does not update location correctly |
| 18435 | // so let's not use the history API at all. |
| 18436 | // http://code.google.com/p/android/issues/detail?id=17471 |
| 18437 | // https://github.com/angular/angular.js/issues/904 |
| 18438 | |
| 18439 | // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has |
| 18440 | // so let's not use the history API also |
| 18441 | // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined |
| 18442 | // jshint -W018 |
| 18443 | history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee), |
| 18444 | // jshint +W018 |
| 18445 | hasEvent: function(event) { |
| 18446 | // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have |
| 18447 | // it. In particular the event is not fired when backspace or delete key are pressed or |
| 18448 | // when cut operation is performed. |
| 18449 | // IE10+ implements 'input' event but it erroneously fires under various situations, |
| 18450 | // e.g. when placeholder changes, or a form is focused. |
| 18451 | if (event === 'input' && msie <= 11) return false; |
| 18452 | |
| 18453 | if (isUndefined(eventSupport[event])) { |
nothing calls this directly
no test coverage detected