-
Notifications
You must be signed in to change notification settings - Fork 2
/
platform.go
325 lines (270 loc) · 8.02 KB
/
platform.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
package browser
import (
"regexp"
"strings"
"github.com/dineshgowda24/browser/platforms"
"github.com/dineshgowda24/browser/utils"
)
// PlatformMatcher is an interface for user agent platform matchers.
// A platform matcher is used to detect the platform from the user agent string.
type PlatformMatcher interface {
Matcher
Version() string // Version returns the version of the platforms.
}
// Platform is a struct that contains information about the user agent's platforms.
type Platform struct {
userAgent string // the user agent string
matcher PlatformMatcher // detected platform matcher
registered bool // indicates if the platform matcher has been registered
}
// NewPlatform creates a new platform based on the user agent string.
//
// UserAgentSizeError is returned if the user agent string is larger than the limit.
func NewPlatform(userAgent string) (*Platform, error) {
// if user agent is larger than the limit, return error
if len(userAgent) > userAgentSizeLimit {
return nil, ErrUserAgentSizeExceeded
}
p := &Platform{
userAgent: userAgent,
}
p.register()
return p, nil
}
// register registers the platform matcher detected from the user agent string.
func (p *Platform) register() {
parser := platforms.NewUAParser(p.userAgent)
// define all your platform matchers here
// the order of the matchers is important as some user agents may contain multiple platform keywords
matchers := []PlatformMatcher{
platforms.NewAdobeAir(parser),
platforms.NewBlackBerry(parser),
platforms.NewKaiOS(parser),
platforms.NewIOS(parser),
platforms.NewWatchOS(parser),
platforms.NewWindowsMobile(parser),
platforms.NewWindowsPhone(parser),
platforms.NewWindows(parser),
platforms.NewAndroid(parser),
platforms.NewLinux(parser),
platforms.NewFirefoxOS(parser),
platforms.NewChromeOS(parser),
platforms.NewUnknown(parser),
}
for _, matcher := range matchers {
if matcher.Match() {
p.matcher = matcher
break
}
}
p.registered = true
}
// getMatcher returns the platform matcher detected from the user agent string.
// If the platform matcher has not been registered, it will be registered.
func (p *Platform) getMatcher() PlatformMatcher {
if !p.registered {
p.register()
}
return p.matcher
}
// Name returns the name of the platform.
func (p *Platform) Name() string {
return p.getMatcher().Name()
}
// Version returns the version of the platform.
func (p *Platform) Version() string {
return p.getMatcher().Version()
}
// IsAdobeAir returns true if the user agent string matches Adobe AIR.
func (p *Platform) IsAdobeAir() bool {
if _, ok := p.getMatcher().(*platforms.AdobeAir); ok {
return true
}
return false
}
func (p *Platform) IsAdobeAirVersionCompatible(version string) bool {
actualVersion := p.getMatcher().Version()
return p.IsAdobeAir() && utils.VersionGTE(actualVersion, version)
}
// IsAndroid returns true if the user agent string matches Android.
func (p *Platform) IsAndroid() bool {
if _, ok := p.getMatcher().(*platforms.Android); ok {
return true
}
return false
}
// IsChromeOS returns true if the user agent string matches Chrome OS.
func (p *Platform) IsChromeOS() bool {
if _, ok := p.getMatcher().(*platforms.ChromeOS); ok {
return true
}
return false
}
// IsChromeOSVersionCompatible returns true if the user agent string matches Chrome OS and
// the version is greater than or equal to the specified version.
func (p *Platform) IsChromeOSVersionCompatible(version string) bool {
return p.IsChromeOS() &&
utils.VersionGTE(p.getMatcher().Version(), version)
}
// IsIOS returns true if the user agent string matches iOS.
func (p *Platform) IsIOS() bool {
if _, ok := p.getMatcher().(*platforms.IOS); ok {
return true
}
return false
}
// IsWatchOS returns true if the user agent string matches Watch OS.
func (p *Platform) IsWatchOS() bool {
if _, ok := p.getMatcher().(*platforms.WatchOS); ok {
return true
}
return false
}
// IsKaiOS returns true if the user agent string matches KaiOS.
func (p *Platform) IsKaiOS() bool {
if _, ok := p.getMatcher().(*platforms.KaiOS); ok {
return true
}
return false
}
// IsLinux returns true if the platform is Linux.
func (p *Platform) IsLinux() bool {
if _, ok := p.getMatcher().(*platforms.Linux); ok {
return true
}
return false
}
// IsBlackBerry returns true if platform is BlackBerry.
func (p *Platform) IsBlackBerry() bool {
if _, ok := p.getMatcher().(*platforms.BlackBerry); ok {
return true
}
return false
}
// IsWindowsMobile returns true if the platform is Windows Mobile.
func (p *Platform) IsWindowsMobile() bool {
if _, ok := p.getMatcher().(*platforms.WindowsMobile); ok {
return true
}
return false
}
// IsWindowsPhone returns true if the platform is Windows Phone.
func (p *Platform) IsWindowsPhone() bool {
if _, ok := p.getMatcher().(*platforms.WindowsPhone); ok {
return true
}
return false
}
// IsIOSApp returns true if the platform is iOS app and the user agent string does not contain Safari.
func (p *Platform) IsIOSApp() bool {
if p.IsIOS() && !strings.Contains(p.userAgent, "Safari") {
return true
}
return false
}
// IsIOSWebview is an alias for IsIOSApp.
func (p *Platform) IsIOSWebview() bool {
return p.IsIOSApp()
}
// IsAndroidApp returns true if the platform is Android app and the user agent string contains wv.
// https://developer.chrome.com/docs/multidevice/user-agent/#webview_user_agent
func (p *Platform) IsAndroidApp() bool {
rg := regexp.MustCompile(`\bwv\b`)
if p.IsAndroid() && rg.MatchString(p.userAgent) {
return true
}
return false
}
// IsAndroidWebview is an alias for IsAndroidApp.
func (p *Platform) IsAndroidWebview() bool {
return p.IsAndroidApp()
}
// IsWindows returns true if the platform is Windows.
func (p *Platform) IsWindows() bool {
if _, ok := p.getMatcher().(*platforms.Windows); ok {
return true
}
return false
}
// IsWindowsXP returns true if the platform is Windows XP.
func (p *Platform) IsWindowsXP() bool {
v := p.getMatcher().Version()
rg := regexp.MustCompile(`5\.[12]`)
if p.IsWindows() && rg.MatchString(v) {
return true
}
return false
}
// IsWindowsVista returns true if the platform is Windows Vista.
func (p *Platform) IsWindowsVista() bool {
v := p.getMatcher().Version()
if p.IsWindows() && v == "6.0" {
return true
}
return false
}
// IsWindows7 returns true if the platform is Windows 7.
func (p *Platform) IsWindows7() bool {
ver := p.getMatcher().Version()
if p.IsWindows() && ver == "6.1" {
return true
}
return false
}
// IsWindows8 returns true if the platform is Windows 8.
func (p *Platform) IsWindows8() bool {
ver := p.getMatcher().Version()
rg := regexp.MustCompile(`6\.[2-3]`)
if p.IsWindows() && rg.MatchString(ver) {
return true
}
return false
}
// IsWindows8_1 returns true if the platform is Windows 8.1.
func (p *Platform) IsWindows8_1() bool {
ver := p.getMatcher().Version()
if p.IsWindows() && ver == "6.3" {
return true
}
return false
}
// IsWindows10 returns true if the platform is Windows 10.
func (p *Platform) IsWindows10() bool {
ver := p.getMatcher().Version()
if p.IsWindows() && ver == "10.0" {
return true
}
return false
}
// IsWindowsRT returns true if the platform is Windows RT.
func (p *Platform) IsWindowsRT() bool {
if p.IsWindows8() && strings.Contains(p.userAgent, "ARM") {
return true
}
return false
}
// IsWindowsX64 returns true if the platform is Windows x64.
func (p *Platform) IsWindowsX64() bool {
rg := regexp.MustCompile(`(Win64|x64|Windows NT 5\.2)`)
if p.IsWindows() && rg.MatchString(p.userAgent) {
return true
}
return false
}
func (p *Platform) IsWindowsWOW64() bool {
rg := regexp.MustCompile(`(?i)WOW64`)
if p.IsWindows() && rg.MatchString(p.userAgent) {
return true
}
return false
}
func (p *Platform) IsWindowsX64Inclusive() bool {
return p.IsWindowsX64() || p.IsWindowsWOW64()
}
// IsWindowsTouchScreenDesktop returns true if the platform is Windows 8 and the user agent string contains Touch.
func (p *Platform) IsWindowsTouchScreenDesktop() bool {
if p.IsWindows() && strings.Contains(p.userAgent, "Touch") {
return true
}
return false
}