* !!! 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
()
| 20527 | * This is very simple implementation of testing browser's features. |
| 20528 | */ |
| 20529 | function $SnifferProvider() { |
| 20530 | this.$get = ['$window', '$document', function($window, $document) { |
| 20531 | var eventSupport = {}, |
| 20532 | // Chrome Packaged Apps are not allowed to access `history.pushState`. |
| 20533 | // If not sandboxed, they can be detected by the presence of `chrome.app.runtime` |
| 20534 | // (see https://developer.chrome.com/apps/api_index). If sandboxed, they can be detected by |
| 20535 | // the presence of an extension runtime ID and the absence of other Chrome runtime APIs |
| 20536 | // (see https://developer.chrome.com/apps/manifest/sandbox). |
| 20537 | // (NW.js apps have access to Chrome APIs, but do support `history`.) |
| 20538 | isNw = $window.nw && $window.nw.process, |
| 20539 | isChromePackagedApp = |
| 20540 | !isNw && |
| 20541 | $window.chrome && |
| 20542 | ($window.chrome.app && $window.chrome.app.runtime || |
| 20543 | !$window.chrome.app && $window.chrome.runtime && $window.chrome.runtime.id), |
| 20544 | hasHistoryPushState = !isChromePackagedApp && $window.history && $window.history.pushState, |
| 20545 | android = |
| 20546 | toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), |
| 20547 | boxee = /Boxee/i.test(($window.navigator || {}).userAgent), |
| 20548 | document = $document[0] || {}, |
| 20549 | bodyStyle = document.body && document.body.style, |
| 20550 | transitions = false, |
| 20551 | animations = false; |
| 20552 | |
| 20553 | if (bodyStyle) { |
| 20554 | // Support: Android <5, Blackberry Browser 10, default Chrome in Android 4.4.x |
| 20555 | // Mentioned browsers need a -webkit- prefix for transitions & animations. |
| 20556 | transitions = !!('transition' in bodyStyle || 'webkitTransition' in bodyStyle); |
| 20557 | animations = !!('animation' in bodyStyle || 'webkitAnimation' in bodyStyle); |
| 20558 | } |
| 20559 | |
| 20560 | |
| 20561 | return { |
| 20562 | // Android has history.pushState, but it does not update location correctly |
| 20563 | // so let's not use the history API at all. |
| 20564 | // http://code.google.com/p/android/issues/detail?id=17471 |
| 20565 | // https://github.com/angular/angular.js/issues/904 |
| 20566 | |
| 20567 | // older webkit browser (533.9) on Boxee box has exactly the same problem as Android has |
| 20568 | // so let's not use the history API also |
| 20569 | // We are purposefully using `!(android < 4)` to cover the case when `android` is undefined |
| 20570 | history: !!(hasHistoryPushState && !(android < 4) && !boxee), |
| 20571 | hasEvent: function(event) { |
| 20572 | // Support: IE 9-11 only |
| 20573 | // IE9 implements 'input' event it's so fubared that we rather pretend that it doesn't have |
| 20574 | // it. In particular the event is not fired when backspace or delete key are pressed or |
| 20575 | // when cut operation is performed. |
| 20576 | // IE10+ implements 'input' event but it erroneously fires under various situations, |
| 20577 | // e.g. when placeholder changes, or a form is focused. |
| 20578 | if (event === 'input' && msie) return false; |
| 20579 | |
| 20580 | if (isUndefined(eventSupport[event])) { |
| 20581 | var divElm = document.createElement('div'); |
| 20582 | eventSupport[event] = 'on' + event in divElm; |
| 20583 | } |
| 20584 | |
| 20585 | return eventSupport[event]; |
| 20586 | }, |
nothing calls this directly
no test coverage detected