* !!! 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
()
| 16113 | * This is very simple implementation of testing browser's features. |
| 16114 | */ |
| 16115 | function $SnifferProvider() { |
| 16116 | this.$get = ['$window', '$document', function($window, $document) { |
| 16117 | var eventSupport = {}, |
| 16118 | android = |
| 16119 | int((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), |
| 16120 | boxee = /Boxee/i.test(($window.navigator || {}).userAgent), |
| 16121 | document = $document[0] || {}, |
| 16122 | vendorPrefix, |
| 16123 | vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/, |
| 16124 | bodyStyle = document.body && document.body.style, |
| 16125 | transitions = false, |
| 16126 | animations = false, |
| 16127 | match; |
| 16128 | |
| 16129 | if (bodyStyle) { |
| 16130 | for (var prop in bodyStyle) { |
| 16131 | if (match = vendorRegex.exec(prop)) { |
| 16132 | vendorPrefix = match[0]; |
| 16133 | vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1); |
| 16134 | break; |
| 16135 | } |
| 16136 | } |
| 16137 | |
| 16138 | if (!vendorPrefix) { |
| 16139 | vendorPrefix = ('WebkitOpacity' in bodyStyle) && 'webkit'; |
| 16140 | } |
| 16141 | |
| 16142 | transitions = !!(('transition' in bodyStyle) || (vendorPrefix + 'Transition' in bodyStyle)); |
| 16143 | animations = !!(('animation' in bodyStyle) || (vendorPrefix + 'Animation' in bodyStyle)); |
| 16144 | |
| 16145 | if (android && (!transitions || !animations)) { |
| 16146 | transitions = isString(document.body.style.webkitTransition); |
| 16147 | animations = isString(document.body.style.webkitAnimation); |
| 16148 | } |
| 16149 | } |
| 16150 | |
| 16151 | |
| 16152 | return { |
| 16153 | // Android has history.pushState, but it does not update location correctly |
| 16154 | // so let's not use the history API at all. |
| 16155 | // http://code.google.com/p/android/issues/detail?id=17471 |
| 16156 | // https://github.com/angular/angular.js/issues/904 |
| 16157 | |
| 16158 | // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has |
| 16159 | // so let's not use the history API also |
| 16160 | // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined |
| 16161 | // jshint -W018 |
| 16162 | history: !!($window.history && $window.history.pushState && !(android < 4) && !boxee), |
| 16163 | // jshint +W018 |
| 16164 | hasEvent: function(event) { |
| 16165 | // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have |
| 16166 | // it. In particular the event is not fired when backspace or delete key are pressed or |
| 16167 | // when cut operation is performed. |
| 16168 | // IE10+ implements 'input' event but it erroneously fires under various situations, |
| 16169 | // e.g. when placeholder changes, or a form is focused. |
| 16170 | if (event === 'input' && msie <= 11) return false; |
| 16171 | |
| 16172 | if (isUndefined(eventSupport[event])) { |
nothing calls this directly
no test coverage detected