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