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