2c53f9c7b72c9614baf9adeaa49a73bdf320b91d439a824871e3fd247f963876b3fb6a29654daa2e944a1cdbef04c338f8591d2fc3c7628af86a56f847f4bc 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* @flow */
  2. // can we use __proto__?
  3. export const hasProto = '__proto__' in {}
  4. // Browser environment sniffing
  5. export const inBrowser = typeof window !== 'undefined'
  6. export const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
  7. export const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()
  8. export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
  9. export const isIE = UA && /msie|trident/.test(UA)
  10. export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
  11. export const isEdge = UA && UA.indexOf('edge/') > 0
  12. export const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android')
  13. export const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios')
  14. export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
  15. export const isPhantomJS = UA && /phantomjs/.test(UA)
  16. export const isFF = UA && UA.match(/firefox\/(\d+)/)
  17. // Firefox has a "watch" function on Object.prototype...
  18. export const nativeWatch = ({}).watch
  19. export let supportsPassive = false
  20. if (inBrowser) {
  21. try {
  22. const opts = {}
  23. Object.defineProperty(opts, 'passive', ({
  24. get () {
  25. /* istanbul ignore next */
  26. supportsPassive = true
  27. }
  28. }: Object)) // https://github.com/facebook/flow/issues/285
  29. window.addEventListener('test-passive', null, opts)
  30. } catch (e) {}
  31. }
  32. // this needs to be lazy-evaled because vue may be required before
  33. // vue-server-renderer can set VUE_ENV
  34. let _isServer
  35. export const isServerRendering = () => {
  36. if (_isServer === undefined) {
  37. /* istanbul ignore if */
  38. if (!inBrowser && !inWeex && typeof global !== 'undefined') {
  39. // detect presence of vue-server-renderer and avoid
  40. // Webpack shimming the process
  41. _isServer = global['process'] && global['process'].env.VUE_ENV === 'server'
  42. } else {
  43. _isServer = false
  44. }
  45. }
  46. return _isServer
  47. }
  48. // detect devtools
  49. export const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__
  50. /* istanbul ignore next */
  51. export function isNative (Ctor: any): boolean {
  52. return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
  53. }
  54. export const hasSymbol =
  55. typeof Symbol !== 'undefined' && isNative(Symbol) &&
  56. typeof Reflect !== 'undefined' && isNative(Reflect.ownKeys)
  57. let _Set
  58. /* istanbul ignore if */ // $flow-disable-line
  59. if (typeof Set !== 'undefined' && isNative(Set)) {
  60. // use native Set when available.
  61. _Set = Set
  62. } else {
  63. // a non-standard Set polyfill that only works with primitive keys.
  64. _Set = class Set implements SimpleSet {
  65. set: Object;
  66. constructor () {
  67. this.set = Object.create(null)
  68. }
  69. has (key: string | number) {
  70. return this.set[key] === true
  71. }
  72. add (key: string | number) {
  73. this.set[key] = true
  74. }
  75. clear () {
  76. this.set = Object.create(null)
  77. }
  78. }
  79. }
  80. export interface SimpleSet {
  81. has(key: string | number): boolean;
  82. add(key: string | number): mixed;
  83. clear(): void;
  84. }
  85. export { _Set }