1- const ua = navigator . userAgent ;
2- const touch = "ontouchstart" in window || navigator . maxTouchPoints > 0 ;
3- const ie = / ( m s i e | t r i d e n t ) / i. test ( ua ) ;
4- const chrome = ! ie && / ( C h r o m e | C r i O S ) / . test ( ua ) ;
5- const firefox = / F i r e f o x / . test ( ua ) ;
6- const safari = ! ie && ! chrome && / ( V e r s i o n | P h a n t o m J S ) \/ ( \d + \. \d + ) .* S a f a r i / . test ( ua ) ;
7- const webkit = ! ie && / w e b k i t / . test ( ua ) ;
8- const windows = navigator . platform . indexOf ( "Win" ) !== - 1 ;
9- const iOS = ! ! ( navigator . platform . match ( / i P h o n e | i P a d | i P o d / ) ) || ! ! ( navigator . userAgent . match ( / M a c / ) && "ontouchend" in document ) ;
10- const android = ! windows && / A n d r o i d / . test ( ua ) ;
11- const androidPhone = android && / (? = a n d r o i d ) (? = .* m o b i l e ) / i. test ( ua ) ;
12- const ipad = / i p a d / i. test ( ua ) || ( / M a c i n t o s h / i. test ( ua ) && "ontouchend" in document ) ;
13- // With iOS 13 the string 'iPad' was removed from the user agent string through a browser setting, which is applied on all sites by default:
14- // "Request Desktop Website -> All websites" (for more infos see: https://forums.developer.apple.com/thread/119186).
15- // Therefore the OS is detected as MACINTOSH instead of iOS and the device is a tablet if the Device.support.touch is true.
1+ const isSSR = typeof document === "undefined" ;
2+
3+ const internals = {
4+ get userAgent ( ) {
5+ if ( isSSR ) {
6+ return "" ;
7+ }
8+ return navigator . userAgent ;
9+ } ,
10+ get touch ( ) {
11+ if ( isSSR ) {
12+ return false ;
13+ }
14+ return "ontouchstart" in window || navigator . maxTouchPoints > 0 ;
15+ } ,
16+ get ie ( ) {
17+ if ( isSSR ) {
18+ return false ;
19+ }
20+ return / ( m s i e | t r i d e n t ) / i. test ( internals . userAgent ) ;
21+ } ,
22+ get chrome ( ) {
23+ if ( isSSR ) {
24+ return false ;
25+ }
26+ return ! internals . ie && / ( C h r o m e | C r i O S ) / . test ( internals . userAgent ) ;
27+ } ,
28+ get firefox ( ) {
29+ if ( isSSR ) {
30+ return false ;
31+ }
32+ return / F i r e f o x / . test ( internals . userAgent ) ;
33+ } ,
34+ get safari ( ) {
35+ if ( isSSR ) {
36+ return false ;
37+ }
38+ return ! internals . ie && ! internals . chrome && / ( V e r s i o n | P h a n t o m J S ) \/ ( \d + \. \d + ) .* S a f a r i / . test ( internals . userAgent ) ;
39+ } ,
40+ get webkit ( ) {
41+ if ( isSSR ) {
42+ return false ;
43+ }
44+ return ! internals . ie && / w e b k i t / . test ( internals . userAgent ) ;
45+ } ,
46+ get windows ( ) {
47+ if ( isSSR ) {
48+ return false ;
49+ }
50+ return navigator . platform . indexOf ( "Win" ) !== - 1 ;
51+ } ,
52+ get iOS ( ) {
53+ if ( isSSR ) {
54+ return false ;
55+ }
56+ return ! ! ( navigator . platform . match ( / i P h o n e | i P a d | i P o d / ) ) || ! ! ( internals . userAgent . match ( / M a c / ) && "ontouchend" in document ) ;
57+ } ,
58+ get android ( ) {
59+ if ( isSSR ) {
60+ return false ;
61+ }
62+ return ! internals . windows && / A n d r o i d / . test ( internals . userAgent ) ;
63+ } ,
64+ get androidPhone ( ) {
65+ if ( isSSR ) {
66+ return false ;
67+ }
68+ return internals . android && / (? = a n d r o i d ) (? = .* m o b i l e ) / i. test ( internals . userAgent ) ;
69+ } ,
70+ get ipad ( ) {
71+ if ( isSSR ) {
72+ return false ;
73+ }
74+ // With iOS 13 the string 'iPad' was removed from the user agent string through a browser setting, which is applied on all sites by default:
75+ // "Request Desktop Website -> All websites" (for more infos see: https://forums.developer.apple.com/thread/119186).
76+ // Therefore the OS is detected as MACINTOSH instead of iOS and the device is a tablet if the Device.support.touch is true.
77+ return / i p a d / i. test ( internals . userAgent ) || ( / M a c i n t o s h / i. test ( internals . userAgent ) && "ontouchend" in document ) ;
78+ } ,
79+ } ;
1680
1781let windowsVersion : number ;
1882let webkitVersion : number ;
1983let tablet : boolean ;
2084
2185const isWindows8OrAbove = ( ) => {
22- if ( ! windows ) {
86+ if ( isSSR ) {
87+ return false ;
88+ }
89+
90+ if ( ! internals . windows ) {
2391 return false ;
2492 }
2593
2694 if ( windowsVersion === undefined ) {
27- const matches = ua . match ( / W i n d o w s N T ( \d + ) .( \d ) / ) ;
95+ const matches = internals . userAgent . match ( / W i n d o w s N T ( \d + ) .( \d ) / ) ;
2896 windowsVersion = matches ? parseFloat ( matches [ 1 ] ) : 0 ;
2997 }
3098
3199 return windowsVersion >= 8 ;
32100} ;
33101
34102const isWebkit537OrAbove = ( ) => {
35- if ( ! webkit ) {
103+ if ( isSSR ) {
104+ return false ;
105+ }
106+
107+ if ( ! internals . webkit ) {
36108 return false ;
37109 }
38110
39111 if ( webkitVersion === undefined ) {
40- const matches = ua . match ( / ( w e b k i t ) [ / ] ( [ \w . ] + ) / ) ;
112+ const matches = internals . userAgent . match ( / ( w e b k i t ) [ / ] ( [ \w . ] + ) / ) ;
41113 webkitVersion = matches ? parseFloat ( matches [ 1 ] ) : 0 ;
42114 }
43115
44116 return webkitVersion >= 537.10 ;
45117} ;
46118
47119const detectTablet = ( ) => {
120+ if ( isSSR ) {
121+ return false ;
122+ }
123+
48124 if ( tablet !== undefined ) {
49125 return ;
50126 }
51127
52- if ( ipad ) {
128+ if ( internals . ipad ) {
53129 tablet = true ;
54130 return ;
55131 }
56132
57- if ( touch ) {
133+ if ( internals . touch ) {
58134 if ( isWindows8OrAbove ( ) ) {
59135 tablet = true ;
60136 return ;
61137 }
62138
63- if ( chrome && android ) {
64- tablet = ! / M o b i l e S a f a r i \/ [ . 0 - 9 ] + / . test ( ua ) ;
139+ if ( internals . chrome && internals . android ) {
140+ tablet = ! / M o b i l e S a f a r i \/ [ . 0 - 9 ] + / . test ( internals . userAgent ) ;
65141 return ;
66142 }
67143
68144 let densityFactor = window . devicePixelRatio ? window . devicePixelRatio : 1 ; // may be undefined in Windows Phone devices
69- if ( android && isWebkit537OrAbove ( ) ) {
145+ if ( internals . android && isWebkit537OrAbove ( ) ) {
70146 densityFactor = 1 ;
71147 }
72148
73149 tablet = ( Math . min ( window . screen . width / densityFactor , window . screen . height / densityFactor ) >= 600 ) ;
74150 return ;
75151 }
76152
77- tablet = ( ie && ua . indexOf ( "Touch" ) !== - 1 ) || ( android && ! androidPhone ) ;
153+ tablet = ( internals . ie && internals . userAgent . indexOf ( "Touch" ) !== - 1 ) || ( internals . android && ! internals . androidPhone ) ;
78154} ;
79155
80- const supportsTouch = ( ) : boolean => touch ;
81- const isIE = ( ) : boolean => ie ;
82- const isSafari = ( ) : boolean => safari ;
83- const isChrome = ( ) : boolean => chrome ;
84- const isFirefox = ( ) : boolean => firefox ;
156+ const supportsTouch = ( ) : boolean => internals . touch ;
157+ const isIE = ( ) : boolean => internals . ie ;
158+ const isSafari = ( ) : boolean => internals . safari ;
159+ const isChrome = ( ) : boolean => internals . chrome ;
160+ const isFirefox = ( ) : boolean => internals . firefox ;
85161
86162const isTablet = ( ) : boolean => {
87163 detectTablet ( ) ;
88- return ( touch || isWindows8OrAbove ( ) ) && tablet ;
164+ return ( internals . touch || isWindows8OrAbove ( ) ) && tablet ;
89165} ;
90166
91167const isPhone = ( ) : boolean => {
92168 detectTablet ( ) ;
93- return touch && ! tablet ;
169+ return internals . touch && ! tablet ;
94170} ;
95171
96172const isDesktop = ( ) : boolean => {
173+ if ( isSSR ) {
174+ return false ;
175+ }
97176 return ( ! isTablet ( ) && ! isPhone ( ) ) || isWindows8OrAbove ( ) ;
98177} ;
99178
@@ -102,11 +181,11 @@ const isCombi = (): boolean => {
102181} ;
103182
104183const isIOS = ( ) : boolean => {
105- return iOS ;
184+ return internals . iOS ;
106185} ;
107186
108187const isAndroid = ( ) : boolean => {
109- return android || androidPhone ;
188+ return internals . android || internals . androidPhone ;
110189} ;
111190
112191export {
0 commit comments