1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit;
16
17 import java.io.File;
18 import java.io.Serializable;
19 import java.lang.reflect.Field;
20 import java.util.EnumSet;
21 import java.util.HashMap;
22 import java.util.Locale;
23 import java.util.Map;
24 import java.util.Objects;
25 import java.util.Set;
26 import java.util.TimeZone;
27
28 import org.apache.commons.io.FilenameUtils;
29 import org.htmlunit.css.CssPixelValueConverter;
30 import org.htmlunit.javascript.configuration.BrowserFeature;
31 import org.htmlunit.javascript.configuration.SupportedBrowser;
32 import org.htmlunit.util.MimeType;
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 @SuppressWarnings({"PMD.AvoidDuplicateLiterals", "PMD.TooManyFields"})
65 public final class BrowserVersion implements Serializable {
66
67
68 public static final BrowserVersion FIREFOX = new BrowserVersion(141, "FF");
69
70 private static final int FIREFOX_ESR_NUMERIC = 128;
71
72
73 public static final BrowserVersion FIREFOX_ESR = new BrowserVersion(FIREFOX_ESR_NUMERIC, "FF-ESR");
74
75
76 public static final BrowserVersion EDGE = new BrowserVersion(139, "Edge");
77
78
79 public static final BrowserVersion CHROME = new BrowserVersion(139, "Chrome");
80
81
82
83
84 public static final BrowserVersion[] ALL_SUPPORTED_BROWSERS = {CHROME, EDGE, FIREFOX, FIREFOX_ESR};
85
86
87
88
89 public static final BrowserVersion BEST_SUPPORTED = CHROME;
90
91
92 private static BrowserVersion DefaultBrowserVersion_ = BEST_SUPPORTED;
93
94 static {
95 FIREFOX_ESR.applicationVersion_ = "5.0 (Windows)";
96 FIREFOX_ESR.userAgent_ = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:"
97 + FIREFOX_ESR.getBrowserVersionNumeric() + ".0) Gecko/20100101 Firefox/"
98 + FIREFOX_ESR.getBrowserVersionNumeric() + ".0";
99 FIREFOX_ESR.buildId_ = "20181001000000";
100 FIREFOX_ESR.vendor_ = "";
101 FIREFOX_ESR.productSub_ = "20100101";
102 FIREFOX_ESR.headerNamesOrdered_ = new String[] {
103 HttpHeader.HOST,
104 HttpHeader.USER_AGENT,
105 HttpHeader.ACCEPT,
106 HttpHeader.ACCEPT_LANGUAGE,
107 HttpHeader.ACCEPT_ENCODING,
108 HttpHeader.CONNECTION,
109 HttpHeader.REFERER,
110 HttpHeader.COOKIE,
111 HttpHeader.UPGRADE_INSECURE_REQUESTS,
112 HttpHeader.SEC_FETCH_DEST,
113 HttpHeader.SEC_FETCH_MODE,
114 HttpHeader.SEC_FETCH_SITE,
115 HttpHeader.SEC_FETCH_USER,
116 HttpHeader.PRIORITY};
117 FIREFOX_ESR.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
118 FIREFOX_ESR.acceptLanguageHeader_ = "en-US,en;q=0.5";
119 FIREFOX_ESR.xmlHttpRequestAcceptHeader_ = "*/*";
120 FIREFOX_ESR.imgAcceptHeader_ = "image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5";
121 FIREFOX_ESR.cssAcceptHeader_ = "text/css,*/*;q=0.1";
122 FIREFOX_ESR.fontHeights_ = new int[] {
123 0, 2, 3, 5, 6, 6, 7, 9, 10, 11, 12, 13, 15, 16, 16, 17, 18, 20, 21, 22, 23, 25, 26, 26, 28, 29,
124 31, 32, 33, 34, 35, 37, 38, 38, 39, 41, 42, 43, 44, 45, 47, 48, 48, 49, 51, 52, 53, 54, 56, 58, 59, 59,
125 60, 61, 63, 64, 65, 66, 68, 69, 69, 70, 71, 73, 74, 75, 76, 77, 79, 79,
126 80, 82, 84, 85, 86, 87, 88, 90, 91, 91, 92, 94, 95, 96, 97, 98,
127 100, 101, 101, 102, 103, 105, 106, 107, 108, 111, 112, 112, 113, 114, 116, 117, 118, 119,
128 120, 122, 122, 123, 124, 126, 127, 128, 129, 130, 132, 132, 133, 134, 137, 138, 139,
129 140, 141, 143, 143, 144, 145, 146, 148};
130
131 FIREFOX.applicationVersion_ = "5.0 (Windows)";
132 FIREFOX.userAgent_ = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:"
133 + FIREFOX.getBrowserVersionNumeric() + ".0) Gecko/20100101 Firefox/"
134 + FIREFOX.getBrowserVersionNumeric() + ".0";
135 FIREFOX.buildId_ = "20181001000000";
136 FIREFOX.vendor_ = "";
137 FIREFOX.productSub_ = "20100101";
138 FIREFOX.headerNamesOrdered_ = new String[] {
139 HttpHeader.HOST,
140 HttpHeader.USER_AGENT,
141 HttpHeader.ACCEPT,
142 HttpHeader.ACCEPT_LANGUAGE,
143 HttpHeader.ACCEPT_ENCODING,
144 HttpHeader.CONNECTION,
145 HttpHeader.REFERER,
146 HttpHeader.COOKIE,
147 HttpHeader.UPGRADE_INSECURE_REQUESTS,
148 HttpHeader.SEC_FETCH_DEST,
149 HttpHeader.SEC_FETCH_MODE,
150 HttpHeader.SEC_FETCH_SITE,
151 HttpHeader.SEC_FETCH_USER,
152 HttpHeader.PRIORITY};
153 FIREFOX.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
154 FIREFOX.acceptLanguageHeader_ = "en-US,en;q=0.5";
155 FIREFOX.xmlHttpRequestAcceptHeader_ = "*/*";
156 FIREFOX.imgAcceptHeader_ = "image/avif,image/webp,image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5";
157 FIREFOX.cssAcceptHeader_ = "text/css,*/*;q=0.1";
158 FIREFOX.fontHeights_ = new int[] {
159 0, 2, 3, 5, 6, 6, 7, 9, 10, 11, 12, 13, 15, 16, 16, 17, 18, 20, 21, 22, 23, 25, 26, 26, 28, 29,
160 31, 32, 33, 34, 35, 37, 38, 38, 39, 41, 42, 43, 44, 45, 47, 48, 48, 49, 51, 52, 53, 54, 56, 58, 59, 59,
161 60, 61, 63, 64, 65, 66, 68, 69, 69, 70, 71, 73, 74, 75, 76, 77, 79, 79,
162 80, 82, 84, 85, 86, 87, 88, 90, 91, 91, 92, 94, 95, 96, 97, 98,
163 100, 101, 101, 102, 103, 105, 106, 107, 108, 111, 112, 112, 113, 114, 116, 117, 118, 119,
164 120, 122, 122, 123, 124, 126, 127, 128, 129, 130, 132, 132, 133, 134, 137, 138, 139,
165 140, 141, 143, 143, 144, 145, 146, 148};
166
167
168 CHROME.applicationVersion_ = "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/"
169 + CHROME.getBrowserVersionNumeric() + ".0.0.0 Safari/537.36";
170 CHROME.userAgent_ = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/"
171 + CHROME.getBrowserVersionNumeric() + ".0.0.0 Safari/537.36";
172
173 CHROME.vendor_ = "Google Inc.";
174 CHROME.productSub_ = "20030107";
175 CHROME.headerNamesOrdered_ = new String[] {
176 HttpHeader.HOST,
177 HttpHeader.CONNECTION,
178 HttpHeader.SEC_CH_UA,
179 HttpHeader.SEC_CH_UA_MOBILE,
180 HttpHeader.SEC_CH_UA_PLATFORM,
181 "Upgrade-Insecure-Requests",
182 HttpHeader.USER_AGENT,
183 HttpHeader.ACCEPT,
184 HttpHeader.SEC_FETCH_SITE,
185 HttpHeader.SEC_FETCH_MODE,
186 HttpHeader.SEC_FETCH_USER,
187 HttpHeader.SEC_FETCH_DEST,
188 HttpHeader.REFERER,
189 HttpHeader.ACCEPT_ENCODING,
190 HttpHeader.ACCEPT_LANGUAGE,
191 HttpHeader.COOKIE};
192 CHROME.acceptLanguageHeader_ = "en-US,en;q=0.9";
193 CHROME.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;"
194 + "q=0.9,image/avif,image/webp,image/apng,*/*;"
195 + "q=0.8,application/signed-exchange;v=b3;q=0.7";
196 CHROME.imgAcceptHeader_ = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8";
197 CHROME.cssAcceptHeader_ = "text/css,*/*;q=0.1";
198 CHROME.scriptAcceptHeader_ = "*/*";
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 CHROME.secClientHintUserAgentHeader_ = "\"Not;A=Brand\";v=\"99\", \"Google Chrome\";v=\""
235 + CHROME.getBrowserVersionNumeric() + "\", \"Chromium\";v=\""
236 + CHROME.getBrowserVersionNumeric() + "\"";
237
238 CHROME.fontHeights_ = new int[] {
239 0, 1, 2, 4, 5, 5, 6, 8, 9, 10, 11, 12, 15, 16, 16, 17, 18, 20, 21, 22, 23, 25, 26, 26,
240 27, 28, 30, 31, 32, 33, 34, 36, 37, 37, 38, 40, 42, 43, 44, 45, 47, 48, 48, 49, 51, 52, 53, 54, 55, 57,
241 58, 58, 59, 60, 62, 63, 64, 65, 67, 69, 69, 70, 71, 73, 74, 75, 76, 77, 79, 79, 80, 81, 83, 84, 85, 86,
242 87, 89, 90, 90, 91, 93, 94, 96, 97, 98, 100, 101, 101, 102, 103, 105, 106, 107, 108, 110, 111, 111, 112,
243 113, 115, 116, 117, 118, 119, 121, 122, 123, 124, 126, 127, 128, 129, 130, 132, 132, 133, 134, 136, 137,
244 138, 139, 140, 142, 142, 143, 144, 145, 147};
245
246
247 EDGE.applicationVersion_ = "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/"
248 + EDGE.getBrowserVersionNumeric() + ".0.0.0 Safari/537.36 Edg/"
249 + EDGE.getBrowserVersionNumeric() + ".0.0.0";
250 EDGE.userAgent_ = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/"
251 + EDGE.getBrowserVersionNumeric() + ".0.0.0 Safari/537.36 Edg/"
252 + EDGE.getBrowserVersionNumeric() + ".0.0.0";
253
254 EDGE.vendor_ = "Google Inc.";
255 EDGE.productSub_ = "20030107";
256 EDGE.headerNamesOrdered_ = new String[] {
257 HttpHeader.HOST,
258 HttpHeader.CONNECTION,
259 HttpHeader.SEC_CH_UA,
260 HttpHeader.SEC_CH_UA_MOBILE,
261 HttpHeader.SEC_CH_UA_PLATFORM,
262 "Upgrade-Insecure-Requests",
263 HttpHeader.USER_AGENT,
264 HttpHeader.ACCEPT,
265 HttpHeader.SEC_FETCH_SITE,
266 HttpHeader.SEC_FETCH_MODE,
267 HttpHeader.SEC_FETCH_USER,
268 HttpHeader.SEC_FETCH_DEST,
269 HttpHeader.REFERER,
270 HttpHeader.ACCEPT_ENCODING,
271 HttpHeader.ACCEPT_LANGUAGE,
272 HttpHeader.COOKIE};
273 EDGE.acceptLanguageHeader_ = "en-US,en;q=0.9";
274 EDGE.htmlAcceptHeader_ = "text/html,application/xhtml+xml,application/xml;"
275 + "q=0.9,image/avif,image/webp,image/apng,*/*;"
276 + "q=0.8,application/signed-exchange;v=b3;q=0.7";
277 EDGE.imgAcceptHeader_ = "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8";
278 EDGE.cssAcceptHeader_ = "text/css,*/*;q=0.1";
279 EDGE.scriptAcceptHeader_ = "*/*";
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 EDGE.secClientHintUserAgentHeader_ = "\"Not;A=Brand\";v=\"99\", \"Microsoft Edge\";v=\""
316 + EDGE.getBrowserVersionNumeric() + "\", \"Chromium\";v=\""
317 + EDGE.getBrowserVersionNumeric() + "\"";
318
319 EDGE.fontHeights_ = new int[] {
320 0, 1, 2, 4, 5, 5, 6, 8, 9, 10, 11, 12, 15, 16, 16, 17, 18, 20, 21, 22, 23, 25, 26, 26,
321 27, 28, 30, 31, 32, 33, 34, 36, 37, 37, 38, 40, 42, 43, 44, 45, 47, 48, 48, 49, 51, 52, 53, 54, 55, 57,
322 58, 58, 59, 60, 62, 63, 64, 65, 67, 69, 69, 70, 71, 73, 74, 75, 76, 77, 79, 79, 80, 81, 83, 84, 85, 86,
323 87, 89, 90, 90, 91, 93, 94, 96, 97, 98, 100, 101, 101, 102, 103, 105, 106, 107, 108, 110, 111, 111, 112,
324 113, 115, 116, 117, 118, 119, 121, 122, 123, 124, 126, 127, 128, 129, 130, 132, 132, 133, 134, 136, 137,
325 138, 139, 140, 142, 142, 143, 144, 145, 147};
326
327
328 CHROME.registerUploadMimeType("html", MimeType.TEXT_HTML);
329 CHROME.registerUploadMimeType("htm", MimeType.TEXT_HTML);
330 CHROME.registerUploadMimeType("css", MimeType.TEXT_CSS);
331 CHROME.registerUploadMimeType("xml", MimeType.TEXT_XML);
332 CHROME.registerUploadMimeType("gif", MimeType.IMAGE_GIF);
333 CHROME.registerUploadMimeType("jpeg", MimeType.IMAGE_JPEG);
334 CHROME.registerUploadMimeType("jpg", MimeType.IMAGE_JPEG);
335 CHROME.registerUploadMimeType("png", MimeType.IMAGE_PNG);
336 CHROME.registerUploadMimeType("pdf", "application/pdf");
337 CHROME.registerUploadMimeType("webp", "image/webp");
338 CHROME.registerUploadMimeType("mp4", "video/mp4");
339 CHROME.registerUploadMimeType("m4v", "video/mp4");
340 CHROME.registerUploadMimeType("m4a", "audio/x-m4a");
341 CHROME.registerUploadMimeType("mp3", "audio/mpeg");
342 CHROME.registerUploadMimeType("ogv", "video/ogg");
343 CHROME.registerUploadMimeType("ogm", "video/ogg");
344 CHROME.registerUploadMimeType("ogg", "audio/ogg");
345 CHROME.registerUploadMimeType("oga", "audio/ogg");
346 CHROME.registerUploadMimeType("opus", "audio/ogg");
347 CHROME.registerUploadMimeType("webm", "video/webm");
348 CHROME.registerUploadMimeType("wav", "audio/wav");
349 CHROME.registerUploadMimeType("flac", "audio/flac");
350 CHROME.registerUploadMimeType("xhtml", "application/xhtml+xml");
351 CHROME.registerUploadMimeType("xht", "application/xhtml+xml");
352 CHROME.registerUploadMimeType("xhtm", "application/xhtml+xml");
353 CHROME.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
354 CHROME.registerUploadMimeType("text", MimeType.TEXT_PLAIN);
355
356 EDGE.registerUploadMimeType("html", MimeType.TEXT_HTML);
357 EDGE.registerUploadMimeType("htm", MimeType.TEXT_HTML);
358 EDGE.registerUploadMimeType("css", MimeType.TEXT_CSS);
359 EDGE.registerUploadMimeType("xml", MimeType.TEXT_XML);
360 EDGE.registerUploadMimeType("gif", MimeType.IMAGE_GIF);
361 EDGE.registerUploadMimeType("jpeg", MimeType.IMAGE_JPEG);
362 EDGE.registerUploadMimeType("jpg", MimeType.IMAGE_JPEG);
363 EDGE.registerUploadMimeType("png", MimeType.IMAGE_PNG);
364 EDGE.registerUploadMimeType("pdf", "application/pdf");
365 EDGE.registerUploadMimeType("webp", "image/webp");
366 EDGE.registerUploadMimeType("mp4", "video/mp4");
367 EDGE.registerUploadMimeType("m4v", "video/mp4");
368 EDGE.registerUploadMimeType("m4a", "audio/x-m4a");
369 EDGE.registerUploadMimeType("mp3", "audio/mpeg");
370 EDGE.registerUploadMimeType("ogv", "video/ogg");
371 EDGE.registerUploadMimeType("ogm", "video/ogg");
372 EDGE.registerUploadMimeType("ogg", "audio/ogg");
373 EDGE.registerUploadMimeType("oga", "audio/ogg");
374 EDGE.registerUploadMimeType("opus", "audio/ogg");
375 EDGE.registerUploadMimeType("webm", "video/webm");
376 EDGE.registerUploadMimeType("wav", "audio/wav");
377 EDGE.registerUploadMimeType("flac", "audio/flac");
378 EDGE.registerUploadMimeType("xhtml", "application/xhtml+xml");
379 EDGE.registerUploadMimeType("xht", "application/xhtml+xml");
380 EDGE.registerUploadMimeType("xhtm", "application/xhtml+xml");
381 EDGE.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
382 EDGE.registerUploadMimeType("text", MimeType.TEXT_PLAIN);
383
384 FIREFOX_ESR.registerUploadMimeType("html", MimeType.TEXT_HTML);
385 FIREFOX_ESR.registerUploadMimeType("htm", MimeType.TEXT_HTML);
386 FIREFOX_ESR.registerUploadMimeType("css", MimeType.TEXT_CSS);
387 FIREFOX_ESR.registerUploadMimeType("xml", MimeType.TEXT_XML);
388 FIREFOX_ESR.registerUploadMimeType("gif", MimeType.IMAGE_GIF);
389 FIREFOX_ESR.registerUploadMimeType("jpeg", MimeType.IMAGE_JPEG);
390 FIREFOX_ESR.registerUploadMimeType("jpg", MimeType.IMAGE_JPEG);
391 FIREFOX_ESR.registerUploadMimeType("pdf", "application/pdf");
392 FIREFOX_ESR.registerUploadMimeType("mp4", "video/mp4");
393 FIREFOX_ESR.registerUploadMimeType("m4v", "video/mp4");
394 FIREFOX_ESR.registerUploadMimeType("m4a", "audio/mp4");
395 FIREFOX_ESR.registerUploadMimeType("png", MimeType.IMAGE_PNG);
396 FIREFOX_ESR.registerUploadMimeType("mp3", "audio/mpeg");
397 FIREFOX_ESR.registerUploadMimeType("ogv", "video/ogg");
398 FIREFOX_ESR.registerUploadMimeType("ogm", "video/ogg");
399 FIREFOX_ESR.registerUploadMimeType("ogg", "video/ogg");
400 FIREFOX_ESR.registerUploadMimeType("oga", "audio/ogg");
401 FIREFOX_ESR.registerUploadMimeType("opus", "audio/ogg");
402 FIREFOX_ESR.registerUploadMimeType("webm", "video/webm");
403 FIREFOX_ESR.registerUploadMimeType("webp", "image/webp");
404 FIREFOX_ESR.registerUploadMimeType("wav", "audio/wav");
405 FIREFOX_ESR.registerUploadMimeType("flac", "audio/x-flac");
406 FIREFOX_ESR.registerUploadMimeType("xhtml", "application/xhtml+xml");
407 FIREFOX_ESR.registerUploadMimeType("xht", "application/xhtml+xml");
408 FIREFOX_ESR.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
409 FIREFOX_ESR.registerUploadMimeType("text", MimeType.TEXT_PLAIN);
410
411 FIREFOX.registerUploadMimeType("html", MimeType.TEXT_HTML);
412 FIREFOX.registerUploadMimeType("htm", MimeType.TEXT_HTML);
413 FIREFOX.registerUploadMimeType("css", MimeType.TEXT_CSS);
414 FIREFOX.registerUploadMimeType("xml", MimeType.TEXT_XML);
415 FIREFOX.registerUploadMimeType("gif", MimeType.IMAGE_GIF);
416 FIREFOX.registerUploadMimeType("jpeg", MimeType.IMAGE_JPEG);
417 FIREFOX.registerUploadMimeType("jpg", MimeType.IMAGE_JPEG);
418 FIREFOX.registerUploadMimeType("pdf", "application/pdf");
419 FIREFOX.registerUploadMimeType("mp4", "video/mp4");
420 FIREFOX.registerUploadMimeType("m4v", "video/mp4");
421 FIREFOX.registerUploadMimeType("m4a", "audio/mp4");
422 FIREFOX.registerUploadMimeType("png", MimeType.IMAGE_PNG);
423 FIREFOX.registerUploadMimeType("mp3", "audio/mpeg");
424 FIREFOX.registerUploadMimeType("ogv", "video/ogg");
425 FIREFOX.registerUploadMimeType("ogm", "video/ogg");
426 FIREFOX.registerUploadMimeType("ogg", "application/ogg");
427 FIREFOX.registerUploadMimeType("oga", "audio/ogg");
428 FIREFOX.registerUploadMimeType("opus", "audio/ogg");
429 FIREFOX.registerUploadMimeType("webm", "video/webm");
430 FIREFOX.registerUploadMimeType("webp", "image/webp");
431 FIREFOX.registerUploadMimeType("wav", "audio/wav");
432 FIREFOX.registerUploadMimeType("flac", "audio/x-flac");
433 FIREFOX.registerUploadMimeType("xhtml", "application/xhtml+xml");
434 FIREFOX.registerUploadMimeType("xht", "application/xhtml+xml");
435 FIREFOX.registerUploadMimeType("txt", MimeType.TEXT_PLAIN);
436 FIREFOX.registerUploadMimeType("text", MimeType.TEXT_PLAIN);
437 }
438
439 private final int browserVersionNumeric_;
440 private final String nickname_;
441
442 private String applicationCodeName_;
443 private String applicationMinorVersion_;
444 private String applicationName_;
445 private String applicationVersion_;
446 private String buildId_;
447 private String productSub_;
448 private String vendor_;
449 private Locale browserLocale_;
450 private boolean onLine_;
451 private String platform_;
452 private TimeZone systemTimezone_;
453 private String userAgent_;
454 private final Set<BrowserVersionFeatures> features_;
455 private String acceptEncodingHeader_;
456 private String acceptLanguageHeader_;
457 private String htmlAcceptHeader_;
458 private String imgAcceptHeader_;
459 private String cssAcceptHeader_;
460 private String scriptAcceptHeader_;
461 private String secClientHintUserAgentHeader_;
462 private String secClientHintUserAgentPlatformHeader_;
463 private String xmlHttpRequestAcceptHeader_;
464 private String[] headerNamesOrdered_;
465 private int[] fontHeights_;
466 private final Map<String, String> uploadMimeTypes_;
467
468
469
470
471
472
473
474 BrowserVersion(final int browserVersionNumeric, final String nickname) {
475 browserVersionNumeric_ = browserVersionNumeric;
476 nickname_ = nickname;
477
478 applicationCodeName_ = "Mozilla";
479 applicationMinorVersion_ = "0";
480 applicationName_ = "Netscape";
481 onLine_ = true;
482 platform_ = "Win32";
483
484 browserLocale_ = Locale.forLanguageTag("en-US");
485 systemTimezone_ = TimeZone.getTimeZone("America/New_York");
486
487 acceptEncodingHeader_ = "gzip, deflate, br";
488 htmlAcceptHeader_ = "*/*";
489 imgAcceptHeader_ = "*/*";
490 cssAcceptHeader_ = "*/*";
491 scriptAcceptHeader_ = "*/*";
492 xmlHttpRequestAcceptHeader_ = "*/*";
493 secClientHintUserAgentHeader_ = "";
494 secClientHintUserAgentPlatformHeader_ = "\"Windows\"";
495
496 features_ = EnumSet.noneOf(BrowserVersionFeatures.class);
497 uploadMimeTypes_ = new HashMap<>();
498
499 initFeatures();
500 }
501
502
503
504
505
506 public boolean isSameBrowser(final BrowserVersion other) {
507 return Objects.equals(nickname_, other.nickname_) && browserVersionNumeric_ == other.browserVersionNumeric_;
508 }
509
510 private void initFeatures() {
511 final SupportedBrowser expectedBrowser;
512 if (isEdge()) {
513 expectedBrowser = SupportedBrowser.EDGE;
514 }
515 else if (isFirefoxESR()) {
516 expectedBrowser = SupportedBrowser.FF_ESR;
517 }
518 else if (isFirefox()) {
519 expectedBrowser = SupportedBrowser.FF;
520 }
521 else {
522 expectedBrowser = SupportedBrowser.CHROME;
523 }
524
525 for (final BrowserVersionFeatures features : BrowserVersionFeatures.values()) {
526 try {
527 final Field field = BrowserVersionFeatures.class.getField(features.name());
528 final BrowserFeature browserFeature = field.getAnnotation(BrowserFeature.class);
529 if (browserFeature != null) {
530 for (final SupportedBrowser browser : browserFeature.value()) {
531 if (expectedBrowser == browser) {
532 features_.add(features);
533 }
534 }
535 }
536 }
537 catch (final NoSuchFieldException e) {
538
539 throw new IllegalStateException(e);
540 }
541 }
542 }
543
544
545
546
547
548
549 public static BrowserVersion getDefault() {
550 return DefaultBrowserVersion_;
551 }
552
553
554
555
556
557 public static void setDefault(final BrowserVersion newBrowserVersion) {
558 WebAssert.notNull("newBrowserVersion", newBrowserVersion);
559 DefaultBrowserVersion_ = newBrowserVersion;
560 }
561
562
563
564
565
566
567
568 public boolean isChrome() {
569 return getNickname().startsWith("Chrome");
570 }
571
572
573
574
575
576
577 public boolean isEdge() {
578 return getNickname().startsWith("Edge");
579 }
580
581
582
583
584
585
586 public boolean isFirefox() {
587 return getNickname().startsWith("FF");
588 }
589
590
591
592
593
594 public boolean isFirefoxESR() {
595 return isFirefox() && getBrowserVersionNumeric() == FIREFOX_ESR_NUMERIC;
596 }
597
598
599
600
601
602
603 public String getNickname() {
604 return nickname_;
605 }
606
607
608
609
610 public int getBrowserVersionNumeric() {
611 return browserVersionNumeric_;
612 }
613
614
615
616
617
618
619
620 public String getApplicationCodeName() {
621 return applicationCodeName_;
622 }
623
624
625
626
627
628
629
630 public String getApplicationMinorVersion() {
631 return applicationMinorVersion_;
632 }
633
634
635
636
637
638
639 public String getApplicationName() {
640 return applicationName_;
641 }
642
643
644
645
646
647
648 public String getApplicationVersion() {
649 return applicationVersion_;
650 }
651
652
653
654
655 public String getVendor() {
656 return vendor_;
657 }
658
659
660
661
662
663
664 public Locale getBrowserLocale() {
665 return browserLocale_;
666 }
667
668
669
670
671
672
673
674 public String getBrowserLanguage() {
675 return browserLocale_.toLanguageTag();
676 }
677
678
679
680
681
682
683
684 public boolean isOnLine() {
685 return onLine_;
686 }
687
688
689
690
691
692
693
694 public String getPlatform() {
695 return platform_;
696 }
697
698
699
700
701
702
703 public TimeZone getSystemTimezone() {
704 return systemTimezone_;
705 }
706
707
708
709
710
711 public String getUserAgent() {
712 return userAgent_;
713 }
714
715
716
717
718
719 public String getAcceptEncodingHeader() {
720 return acceptEncodingHeader_;
721 }
722
723
724
725
726
727 public String getAcceptLanguageHeader() {
728 return acceptLanguageHeader_;
729 }
730
731
732
733
734
735 public String getHtmlAcceptHeader() {
736 return htmlAcceptHeader_;
737 }
738
739
740
741
742
743
744 public String getScriptAcceptHeader() {
745 return scriptAcceptHeader_;
746 }
747
748
749
750
751
752
753 public String getXmlHttpRequestAcceptHeader() {
754 return xmlHttpRequestAcceptHeader_;
755 }
756
757
758
759
760
761
762 public String getImgAcceptHeader() {
763 return imgAcceptHeader_;
764 }
765
766
767
768
769
770
771 public String getCssAcceptHeader() {
772 return cssAcceptHeader_;
773 }
774
775
776
777
778
779 public String getSecClientHintUserAgentHeader() {
780 return secClientHintUserAgentHeader_;
781 }
782
783
784
785
786
787 public String getSecClientHintUserAgentPlatformHeader() {
788 return secClientHintUserAgentPlatformHeader_;
789 }
790
791
792
793
794
795
796 public boolean hasFeature(final BrowserVersionFeatures property) {
797 return features_.contains(property);
798 }
799
800
801
802
803
804 public String getBuildId() {
805 return buildId_;
806 }
807
808
809
810
811
812 public String getProductSub() {
813 return productSub_;
814 }
815
816
817
818
819
820 public String[] getHeaderNamesOrdered() {
821 return headerNamesOrdered_;
822 }
823
824
825
826
827
828
829 public void registerUploadMimeType(final String fileExtension, final String mimeType) {
830 if (fileExtension != null) {
831 uploadMimeTypes_.put(fileExtension.toLowerCase(Locale.ROOT), mimeType);
832 }
833 }
834
835
836
837
838
839
840 public String getUploadMimeType(final File file) {
841 if (file == null) {
842 return "";
843 }
844
845 final String fileExtension = FilenameUtils.getExtension(file.getName());
846
847 final String mimeType = uploadMimeTypes_.get(fileExtension.toLowerCase(Locale.ROOT));
848 if (mimeType != null) {
849 return mimeType;
850 }
851 return "";
852 }
853
854
855
856
857
858
859 public int getFontHeight(final String fontSize) {
860 if (fontHeights_ == null || fontSize.isEmpty()) {
861 return 18;
862 }
863
864 if ("xx-small".equalsIgnoreCase(fontSize)) {
865 return fontHeights_[9];
866 }
867 if ("x-small".equalsIgnoreCase(fontSize)) {
868 return fontHeights_[10];
869 }
870 if ("small".equalsIgnoreCase(fontSize)) {
871 return fontHeights_[13];
872 }
873 if ("medium".equalsIgnoreCase(fontSize)) {
874 return fontHeights_[16];
875 }
876 if ("large".equalsIgnoreCase(fontSize)) {
877 return fontHeights_[18];
878 }
879 if ("x-large".equalsIgnoreCase(fontSize)) {
880 return fontHeights_[24];
881 }
882 if ("xx-large".equalsIgnoreCase(fontSize)) {
883 return fontHeights_[32];
884 }
885 if ("xxx-large".equalsIgnoreCase(fontSize)) {
886 return fontHeights_[48];
887 }
888
889 if ("smaller".equalsIgnoreCase(fontSize)) {
890 return fontHeights_[13];
891 }
892 if ("larger".equalsIgnoreCase(fontSize)) {
893 return fontHeights_[19];
894 }
895
896 final int fontSizeInt = CssPixelValueConverter.pixelValue(fontSize);
897 if (fontSizeInt < fontHeights_.length) {
898 return fontHeights_[fontSizeInt];
899 }
900
901 return (int) (fontSizeInt * 1.2);
902 }
903
904
905
906
907 public int getPixesPerChar() {
908 return 10;
909 }
910
911 @Override
912 public String toString() {
913 return nickname_;
914 }
915
916
917
918
919
920 @SuppressWarnings("PMD.LinguisticNaming")
921 public static class BrowserVersionBuilder {
922 private final BrowserVersion workPiece_;
923
924
925
926
927
928
929 public BrowserVersionBuilder(final BrowserVersion version) {
930 workPiece_ = new BrowserVersion(version.getBrowserVersionNumeric(), version.getNickname());
931
932 setApplicationVersion(version.getApplicationVersion())
933 .setUserAgent(version.getUserAgent())
934 .setApplicationName(version.getApplicationName())
935 .setApplicationCodeName(version.getApplicationCodeName())
936 .setApplicationMinorVersion(version.getApplicationMinorVersion())
937 .setVendor(version.getVendor())
938 .setBrowserLanguage(version.getBrowserLanguage())
939 .setOnLine(version.isOnLine())
940 .setPlatform(version.getPlatform())
941 .setSystemTimezone(version.getSystemTimezone())
942 .setBuildId(version.getBuildId())
943 .setProductSub(version.getProductSub())
944 .setAcceptEncodingHeader(version.getAcceptEncodingHeader())
945 .setAcceptLanguageHeader(version.getAcceptLanguageHeader())
946 .setHtmlAcceptHeader(version.getHtmlAcceptHeader())
947 .setImgAcceptHeader(version.getImgAcceptHeader())
948 .setCssAcceptHeader(version.getCssAcceptHeader())
949 .setScriptAcceptHeader(version.getScriptAcceptHeader())
950 .setXmlHttpRequestAcceptHeader(version.getXmlHttpRequestAcceptHeader())
951 .setSecClientHintUserAgentHeader(version.getSecClientHintUserAgentHeader())
952 .setSecClientHintUserAgentPlatformHeader(version.getSecClientHintUserAgentPlatformHeader())
953 .setHeaderNamesOrdered(version.getHeaderNamesOrdered())
954 .setFontHeights(version.fontHeights_);
955
956 workPiece_.features_.addAll(version.features_);
957 workPiece_.uploadMimeTypes_.putAll(version.uploadMimeTypes_);
958 }
959
960
961
962
963 public BrowserVersion build() {
964 return workPiece_;
965 }
966
967
968
969
970
971 public BrowserVersionBuilder setApplicationMinorVersion(final String applicationMinorVersion) {
972 workPiece_.applicationMinorVersion_ = applicationMinorVersion;
973 return this;
974 }
975
976
977
978
979
980 public BrowserVersionBuilder setApplicationName(final String applicationName) {
981 workPiece_.applicationName_ = applicationName;
982 return this;
983 }
984
985
986
987
988
989 public BrowserVersionBuilder setApplicationVersion(final String applicationVersion) {
990 workPiece_.applicationVersion_ = applicationVersion;
991 return this;
992 }
993
994
995
996
997
998 public BrowserVersionBuilder setVendor(final String vendor) {
999 workPiece_.vendor_ = vendor;
1000 return this;
1001 }
1002
1003
1004
1005
1006
1007 public BrowserVersionBuilder setApplicationCodeName(final String applicationCodeName) {
1008 workPiece_.applicationCodeName_ = applicationCodeName;
1009 return this;
1010 }
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020 public BrowserVersionBuilder setBrowserLanguage(final String browserLanguage) {
1021 workPiece_.browserLocale_ = Locale.forLanguageTag(browserLanguage);
1022 return this;
1023 }
1024
1025
1026
1027
1028
1029 public BrowserVersionBuilder setOnLine(final boolean onLine) {
1030 workPiece_.onLine_ = onLine;
1031 return this;
1032 }
1033
1034
1035
1036
1037
1038 public BrowserVersionBuilder setPlatform(final String platform) {
1039 workPiece_.platform_ = platform;
1040 return this;
1041 }
1042
1043
1044
1045
1046
1047 public BrowserVersionBuilder setSystemTimezone(final TimeZone systemTimezone) {
1048 workPiece_.systemTimezone_ = systemTimezone;
1049 return this;
1050 }
1051
1052
1053
1054
1055
1056 public BrowserVersionBuilder setUserAgent(final String userAgent) {
1057 workPiece_.userAgent_ = userAgent;
1058 return this;
1059 }
1060
1061
1062
1063
1064
1065 public BrowserVersionBuilder setAcceptEncodingHeader(final String acceptEncodingHeader) {
1066 workPiece_.acceptEncodingHeader_ = acceptEncodingHeader;
1067 return this;
1068 }
1069
1070
1071
1072
1073
1074 public BrowserVersionBuilder setAcceptLanguageHeader(final String acceptLanguageHeader) {
1075 workPiece_.acceptLanguageHeader_ = acceptLanguageHeader;
1076 return this;
1077 }
1078
1079
1080
1081
1082
1083 public BrowserVersionBuilder setHtmlAcceptHeader(final String htmlAcceptHeader) {
1084 workPiece_.htmlAcceptHeader_ = htmlAcceptHeader;
1085 return this;
1086 }
1087
1088
1089
1090
1091
1092 public BrowserVersionBuilder setImgAcceptHeader(final String imgAcceptHeader) {
1093 workPiece_.imgAcceptHeader_ = imgAcceptHeader;
1094 return this;
1095 }
1096
1097
1098
1099
1100
1101 public BrowserVersionBuilder setCssAcceptHeader(final String cssAcceptHeader) {
1102 workPiece_.cssAcceptHeader_ = cssAcceptHeader;
1103 return this;
1104 }
1105
1106
1107
1108
1109
1110 public BrowserVersionBuilder setScriptAcceptHeader(final String scriptAcceptHeader) {
1111 workPiece_.scriptAcceptHeader_ = scriptAcceptHeader;
1112 return this;
1113 }
1114
1115
1116
1117
1118
1119
1120 public BrowserVersionBuilder setXmlHttpRequestAcceptHeader(final String xmlHttpRequestAcceptHeader) {
1121 workPiece_.xmlHttpRequestAcceptHeader_ = xmlHttpRequestAcceptHeader;
1122 return this;
1123 }
1124
1125
1126
1127
1128
1129 public BrowserVersionBuilder setSecClientHintUserAgentHeader(final String secClientHintUserAgentHeader) {
1130 workPiece_.secClientHintUserAgentHeader_ = secClientHintUserAgentHeader;
1131 return this;
1132 }
1133
1134
1135
1136
1137
1138 public BrowserVersionBuilder setSecClientHintUserAgentPlatformHeader(final String secClientHintUserAgentPlatformHeader) {
1139 workPiece_.secClientHintUserAgentPlatformHeader_ = secClientHintUserAgentPlatformHeader;
1140 return this;
1141 }
1142
1143
1144
1145
1146
1147 BrowserVersionBuilder setProductSub(final String productSub) {
1148 workPiece_.productSub_ = productSub;
1149 return this;
1150 }
1151
1152
1153
1154
1155
1156 BrowserVersionBuilder setHeaderNamesOrdered(final String[] headerNamesOrdered) {
1157 workPiece_.headerNamesOrdered_ = headerNamesOrdered;
1158 return this;
1159 }
1160
1161
1162
1163
1164
1165 BrowserVersionBuilder setFontHeights(final int[] fontHeights) {
1166 workPiece_.fontHeights_ = fontHeights;
1167 return this;
1168 }
1169
1170
1171
1172
1173
1174 BrowserVersionBuilder setBuildId(final String buildId) {
1175 workPiece_.buildId_ = buildId;
1176 return this;
1177 }
1178 }
1179 }