* !!! This is an undocumented "private" service !!! * * @name $sniffer * @requires $window * @requires $document * @this * * @property {boolean} history Does the browser support html5 history api ? * @property {boolean} transitions Does the browser support CSS transition events ? * @propert
()
| 20186 | * This is very simple implementation of testing browser's features. |
| 20187 | */ |
| 20188 | function $SnifferProvider() { |
| 20189 | this.$get = ['$window', '$document', function($window, $document) { |
| 20190 | var eventSupport = {}, |
| 20191 | // Chrome Packaged Apps are not allowed to access `history.pushState`. |
| 20192 | // If not sandboxed, they can be detected by the presence of `chrome.app.runtime` |
| 20193 | // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by |
| 20194 | // the presence of an extension runtime ID and the absence of other Chrome runtime APIs |
| 20195 | // (see https://developer.chrome.com/apps/manifest/sandbox). |
| 20196 | // (NW.js apps have access to Chrome APIs, but do support `history`.) |
| 20197 | isNw = $window.nw && $window.nw.process, |
| 20198 | isChromePackagedApp = |
| 20199 | !isNw && |
| 20200 | $window.chrome && |
| 20201 | ($window.chrome.app && $window.chrome.app.runtime || |
| 20202 | !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id), |
| 20203 | hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, |
| 20204 | android = |
| 20205 | toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), |
| 20206 | boxee = /Boxee/i.test(($window.navigator || {}).userAgent), |
| 20207 | document = $document[0] || {}, |
| 20208 | bodyStyle = document.body && document.body.style, |
| 20209 | transitions = false, |
| 20210 | animations = false; |
| 20211 | |
| 20212 | if (bodyStyle) { |
| 20213 | // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x |
| 20214 | // Mentioned browsers need a -webkit- prefix for transitions & animations. |
| 20215 | transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle); |
| 20216 | animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle); |
| 20217 | } |
| 20218 | |
| 20219 | |
| 20220 | return { |
| 20221 | // Android has history.pushState, but it does not update location correctly |
| 20222 | // so let's not use the history API at all. |
| 20223 | // http://code.google.com/p/android/issues/detail?id=17471 |
| 20224 | // https://github.com/angular/angular.js/issues/904 |
| 20225 | |
| 20226 | // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has |
| 20227 | // so let's not use the history API also |
| 20228 | // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined |
| 20229 | history: !!(hasHistoryPushState && !(android < 4) && !boxee), |
| 20230 | hasEvent: function(event) { |
| 20231 | // Support: IE 9-11 only |
| 20232 | // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have |
| 20233 | // it. In particular the event is not fired when backspace or delete key are pressed or |
| 20234 | // when cut operation is performed. |
| 20235 | // IE10+ implements 'input' event but it erroneously fires under various situations, |
| 20236 | // e.g. when placeholder changes, or a form is focused. |
| 20237 | if (event === 'input' && msie) return false; |
| 20238 | |
| 20239 | if (isUndefined(eventSupport[event])) { |
| 20240 | var divElm = document.createElement('div'); |
| 20241 | eventSupport[event] = 'on' + event in divElm; |
| 20242 | } |
| 20243 | |
| 20244 | return eventSupport[event]; |
| 20245 | }, |
nothing calls this directly
no test coverage detected