* !!! 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
()
| 21172 | * This is very simple implementation of testing browser's features. |
| 21173 | */ |
| 21174 | function $SnifferProvider() { |
| 21175 | this.$get = ['$window', '$document', function($window, $document) { |
| 21176 | var eventSupport = {}, |
| 21177 | // Chrome Packaged Apps are not allowed to access `history.pushState`. |
| 21178 | // If not sandboxed, they can be detected by the presence of `chrome.app.runtime` |
| 21179 | // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by |
| 21180 | // the presence of an extension runtime ID and the absence of other Chrome runtime APIs |
| 21181 | // (see https://developer.chrome.com/apps/manifest/sandbox). |
| 21182 | // (NW.js apps have access to Chrome APIs, but do support `history`.) |
| 21183 | isNw = $window.nw && $window.nw.process, |
| 21184 | isChromePackagedApp = |
| 21185 | !isNw && |
| 21186 | $window.chrome && |
| 21187 | ($window.chrome.app && $window.chrome.app.runtime || |
| 21188 | !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id), |
| 21189 | hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, |
| 21190 | android = |
| 21191 | toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), |
| 21192 | boxee = /Boxee/i.test(($window.navigator || {}).userAgent), |
| 21193 | document = $document[0] || {}, |
| 21194 | bodyStyle = document.body && document.body.style, |
| 21195 | transitions = false, |
| 21196 | animations = false; |
| 21197 | |
| 21198 | if (bodyStyle) { |
| 21199 | // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x |
| 21200 | // Mentioned browsers need a -webkit- prefix for transitions & animations. |
| 21201 | transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle); |
| 21202 | animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle); |
| 21203 | } |
| 21204 | |
| 21205 | |
| 21206 | return { |
| 21207 | // Android has history.pushState, but it does not update location correctly |
| 21208 | // so let's not use the history API at all. |
| 21209 | // http://code.google.com/p/android/issues/detail?id=17471 |
| 21210 | // https://github.com/angular/angular.js/issues/904 |
| 21211 | |
| 21212 | // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has |
| 21213 | // so let's not use the history API also |
| 21214 | // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined |
| 21215 | history: !!(hasHistoryPushState && !(android < 4) && !boxee), |
| 21216 | hasEvent: function(event) { |
| 21217 | // Support: IE 9-11 only |
| 21218 | // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have |
| 21219 | // it. In particular the event is not fired when backspace or delete key are pressed or |
| 21220 | // when cut operation is performed. |
| 21221 | // IE10+ implements 'input' event but it erroneously fires under various situations, |
| 21222 | // e.g. when placeholder changes, or a form is focused. |
| 21223 | if (event === 'input' && msie) return false; |
| 21224 | |
| 21225 | if (isUndefined(eventSupport[event])) { |
| 21226 | var divElm = document.createElement('div'); |
| 21227 | eventSupport[event] = 'on' + event in divElm; |
| 21228 | } |
| 21229 | |
| 21230 | return eventSupport[event]; |
| 21231 | }, |
nothing calls this directly
no test coverage detected