* !!! 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
()
| 21107 | * This is very simple implementation of testing browser's features. |
| 21108 | */ |
| 21109 | function $SnifferProvider() { |
| 21110 | this.$get = ['$window', '$document', function($window, $document) { |
| 21111 | var eventSupport = {}, |
| 21112 | // Chrome Packaged Apps are not allowed to access `history.pushState`. |
| 21113 | // If not sandboxed, they can be detected by the presence of `chrome.app.runtime` |
| 21114 | // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by |
| 21115 | // the presence of an extension runtime ID and the absence of other Chrome runtime APIs |
| 21116 | // (see https://developer.chrome.com/apps/manifest/sandbox). |
| 21117 | // (NW.js apps have access to Chrome APIs, but do support `history`.) |
| 21118 | isNw = $window.nw && $window.nw.process, |
| 21119 | isChromePackagedApp = |
| 21120 | !isNw && |
| 21121 | $window.chrome && |
| 21122 | ($window.chrome.app && $window.chrome.app.runtime || |
| 21123 | !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id), |
| 21124 | hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, |
| 21125 | android = |
| 21126 | toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), |
| 21127 | boxee = /Boxee/i.test(($window.navigator || {}).userAgent), |
| 21128 | document = $document[0] || {}, |
| 21129 | bodyStyle = document.body && document.body.style, |
| 21130 | transitions = false, |
| 21131 | animations = false; |
| 21132 | |
| 21133 | if (bodyStyle) { |
| 21134 | // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x |
| 21135 | // Mentioned browsers need a -webkit- prefix for transitions & animations. |
| 21136 | transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle); |
| 21137 | animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle); |
| 21138 | } |
| 21139 | |
| 21140 | |
| 21141 | return { |
| 21142 | // Android has history.pushState, but it does not update location correctly |
| 21143 | // so let's not use the history API at all. |
| 21144 | // http://code.google.com/p/android/issues/detail?id=17471 |
| 21145 | // https://github.com/angular/angular.js/issues/904 |
| 21146 | |
| 21147 | // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has |
| 21148 | // so let's not use the history API also |
| 21149 | // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined |
| 21150 | history: !!(hasHistoryPushState && !(android < 4) && !boxee), |
| 21151 | hasEvent: function(event) { |
| 21152 | // Support: IE 9-11 only |
| 21153 | // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have |
| 21154 | // it. In particular the event is not fired when backspace or delete key are pressed or |
| 21155 | // when cut operation is performed. |
| 21156 | // IE10+ implements 'input' event but it erroneously fires under various situations, |
| 21157 | // e.g. when placeholder changes, or a form is focused. |
| 21158 | if (event === 'input' && msie) return false; |
| 21159 | |
| 21160 | if (isUndefined(eventSupport[event])) { |
| 21161 | var divElm = document.createElement('div'); |
| 21162 | eventSupport[event] = 'on' + event in divElm; |
| 21163 | } |
| 21164 | |
| 21165 | return eventSupport[event]; |
| 21166 | }, |
nothing calls this directly
no test coverage detected