1 /*
2 * Copyright (c) 2002-2026 Gargoyle Software Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 * https://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package org.htmlunit;
16
17 import static org.htmlunit.javascript.configuration.SupportedBrowser.CHROME;
18 import static org.htmlunit.javascript.configuration.SupportedBrowser.EDGE;
19 import static org.htmlunit.javascript.configuration.SupportedBrowser.FF;
20 import static org.htmlunit.javascript.configuration.SupportedBrowser.FF_ESR;
21
22 import org.htmlunit.javascript.configuration.BrowserFeature;
23
24 /**
25 * Constants of various features of each {@link BrowserVersion}.
26 *
27 * @author Ahmed Ashour
28 * @author Marc Guillemot
29 * @author Sudhan Moghe
30 * @author Ronald Brill
31 * @author Frank Danek
32 * @author Carsten Steul
33 * @author Anton Demydenko
34 */
35 public enum BrowserVersionFeatures {
36
37 /** Ignore target when {@code href} is a javascript snippet. */
38 @BrowserFeature({CHROME, EDGE})
39 ANCHOR_SEND_PING_REQUEST,
40
41 /** Screen colorDepth is 32 instead of 24. */
42 @BrowserFeature({CHROME, EDGE})
43 COLOR_DEPHT_32,
44
45 /** Background image is 'initial'. */
46 @BrowserFeature({CHROME, EDGE})
47 CSS_BACKGROUND_INITIAL,
48
49 /** Background image is 'rgba(0, 0, 0, 0)'. */
50 @BrowserFeature({FF, FF_ESR})
51 CSS_BACKGROUND_RGBA,
52
53 /** Is display style 'block'. */
54 @BrowserFeature({FF, FF_ESR})
55 CSS_DISPLAY_BLOCK,
56
57 /** The default value of the display property for the 'noscript' tag is 'inline' instead of the default one. */
58 @BrowserFeature({CHROME, EDGE})
59 CSS_NOSCRIPT_DISPLAY_INLINE,
60
61 /** The default value of the display property for the 'rp' tag is 'none'. */
62 @BrowserFeature({FF, FF_ESR})
63 CSS_RP_DISPLAY_NONE,
64
65 /** The default value of the display property for the 'rt' tag is always 'ruby-text'. */
66 @BrowserFeature({FF, FF_ESR})
67 CSS_RT_DISPLAY_RUBY_TEXT_ALWAYS,
68
69 /** The context menu MouseEvent has a detail of 1. */
70 @BrowserFeature({FF, FF_ESR})
71 EVENT_CONTEXT_MENU_HAS_DETAIL_1,
72
73 /** Triggers the onfocus event when focusing the body on load. */
74 @BrowserFeature({FF, FF_ESR})
75 EVENT_FOCUS_ON_LOAD,
76
77 /** Scroll events are of type 'UIEvent'. */
78 @BrowserFeature({FF, FF_ESR})
79 EVENT_SCROLL_UIEVENT,
80
81 /** Supports event type 'MutationEvent'. */
82 @BrowserFeature(FF_ESR)
83 EVENT_TYPE_MUTATIONEVENT,
84
85 /** Form elements are able to refer to the for by using the form attribute. */
86 @BrowserFeature({CHROME, EDGE})
87 FORM_IGNORE_REL_NOREFERRER,
88
89 /** Form submit includes the Cache-Control: max-age=0 header. */
90 @BrowserFeature({CHROME, EDGE})
91 FORM_SUBMISSION_HEADER_CACHE_CONTROL_MAX_AGE,
92
93 /** Should org.htmlunit.javascript.host.html.HTMLBaseFontElement#isEndTagForbidden(). */
94 @BrowserFeature({FF, FF_ESR})
95 HTMLBASEFONT_END_TAG_FORBIDDEN,
96
97 /** HtmlCollection.namedItem searches by id first. */
98 @BrowserFeature({CHROME, EDGE})
99 HTMLCOLLECTION_NAMED_ITEM_ID_FIRST,
100
101 /**
102 /** {@code document.getElementsByName} returns an empty list if called with the empty string.
103 */
104 @BrowserFeature({FF, FF_ESR})
105 HTMLDOCUMENT_ELEMENTS_BY_NAME_EMPTY,
106
107 /** Removing the active element from the dom tree triggers the onblur event. */
108 @BrowserFeature({CHROME, EDGE})
109 HTMLELEMENT_REMOVE_ACTIVE_TRIGGERS_BLUR_EVENT,
110
111 /** Handle blank source like empty. */
112 @BrowserFeature({CHROME, EDGE})
113 HTMLIMAGE_BLANK_SRC_AS_EMPTY,
114
115 /** Empty src attribute sets display to false. */
116 @BrowserFeature({FF, FF_ESR})
117 HTMLIMAGE_EMPTY_SRC_DISPLAY_FALSE,
118
119 /** Is document.cretaeElement('image') an HTMLElement. */
120 @BrowserFeature({FF, FF_ESR})
121 HTMLIMAGE_HTMLELEMENT,
122
123 /** Is document.cretaeElement('image') an HTMLUnknownElement. */
124 @BrowserFeature({CHROME, EDGE})
125 HTMLIMAGE_HTMLUNKNOWNELEMENT,
126
127 /** HTMLInputElement image type is not supported. */
128 @BrowserFeature({CHROME, EDGE})
129 HTMLINPUT_TYPE_IMAGE_IGNORES_CUSTOM_VALIDITY,
130
131 /** HTMLInputElement month type is supported. */
132 @BrowserFeature({CHROME, EDGE})
133 HTMLINPUT_TYPE_MONTH_SUPPORTED,
134
135 /** HTMLInputElement week type is supported. */
136 @BrowserFeature({CHROME, EDGE})
137 HTMLINPUT_TYPE_WEEK_SUPPORTED,
138
139 /** For a stylesheet link report an error if the response type is not text/css. */
140 @BrowserFeature({FF, FF_ESR})
141 HTMLLINK_CHECK_RESPONSE_TYPE_FOR_STYLESHEET,
142
143 /** If the type is present for a link only use if type is text/css. */
144 @BrowserFeature({CHROME, EDGE})
145 HTMLLINK_CHECK_TYPE_FOR_STYLESHEET,
146
147 /** Should org.htmlunit.javascript.host.html.HTMLTrackElement#isEndTagForbidden(). */
148 @BrowserFeature({FF, FF_ESR})
149 HTMLTRACK_END_TAG_FORBIDDEN,
150
151 /** HTML parser supports the 'layer' tag. */
152 @BrowserFeature({CHROME, EDGE})
153 HTML_LAYER_TAG,
154
155 /** Additionally support dates in format "d/M/yyyy". */
156 @BrowserFeature({FF, FF_ESR})
157 HTTP_COOKIE_EXTENDED_DATE_PATTERNS_1,
158
159 /** Dates format pattern 2. */
160 @BrowserFeature({CHROME, EDGE})
161 HTTP_COOKIE_EXTENDED_DATE_PATTERNS_2,
162
163 /** domain '.org' is handled as 'org'. */
164 @BrowserFeature({FF, FF_ESR})
165 HTTP_COOKIE_REMOVE_DOT_FROM_ROOT_DOMAINS,
166
167 /** Browser sends Sec-ch headers. */
168 @BrowserFeature({CHROME, EDGE})
169 HTTP_HEADER_CH_UA,
170
171 /** Browser sends Priority headers. */
172 @BrowserFeature({FF, FF_ESR})
173 HTTP_HEADER_PRIORITY,
174
175 /** The anchor hostname setter ignores blank url's. */
176 @BrowserFeature({FF, FF_ESR})
177 JS_ANCHOR_HOSTNAME_IGNORE_BLANK,
178
179 /**
180 * The anchor pathname detects url's starting with one letter as file url's
181 * and replaces them with the file protocol. */
182 @BrowserFeature({CHROME, EDGE})
183 JS_ANCHOR_PATHNAME_DETECT_WIN_DRIVES_URL_REPLACE,
184
185 /** The anchor pathname prefixes file url's with '/'. */
186 @BrowserFeature({CHROME, EDGE})
187 JS_ANCHOR_PATHNAME_PREFIX_WIN_DRIVES_URL,
188
189 /** The anchor protocol property converts drive letters to uppercase. */
190 @BrowserFeature({CHROME, EDGE})
191 JS_ANCHOR_PROTOCOL_COLON_UPPER_CASE_DRIVE_LETTERS,
192
193 /** An area element without a href attribute is focusable. */
194 @BrowserFeature({FF, FF_ESR})
195 JS_AREA_WITHOUT_HREF_FOCUSABLE,
196
197 /** Sorting an array using a user defined comperator accepts inconsistent iterators. */
198 @BrowserFeature({FF, FF_ESR})
199 JS_ARRAY_SORT_ACCEPTS_INCONSISTENT_COMPERATOR,
200
201 /** AudioProcessingEvent ctor is callable. */
202 @BrowserFeature({CHROME, EDGE})
203 JS_AUDIO_PROCESSING_EVENT_CTOR,
204
205 /** toDataURL for canvas returns the CHROME version of the PNG. */
206 @BrowserFeature({CHROME, EDGE})
207 JS_CANVAS_DATA_URL_CHROME_PNG,
208
209 /** ClientHeight for input is 17. */
210 @BrowserFeature({CHROME, EDGE})
211 JS_CLIENTHEIGHT_INPUT_17,
212
213 /** ClientHeight for input is 18. */
214 @BrowserFeature({FF, FF_ESR})
215 JS_CLIENTHEIGHT_INPUT_18,
216
217 /** ClientHeight for radio button and checkbox is 14. */
218 @BrowserFeature({FF, FF_ESR})
219 JS_CLIENTHEIGHT_RADIO_CHECKBOX_14,
220
221 /** ClientHeight for rb is 17. */
222 @BrowserFeature({FF, FF_ESR})
223 JS_CLIENTHEIGHT_RB_17,
224
225 /** ClientHeight for rt is 9. */
226 @BrowserFeature({FF, FF_ESR})
227 JS_CLIENTHEIGHT_RT_9,
228
229 /** ClientHeight for ruby is 17. */
230 @BrowserFeature({FF, FF_ESR})
231 JS_CLIENTHEIGHT_RUBY_17,
232
233 /** ClientWidth for text/password input is 157. */
234 @BrowserFeature(FF)
235 JS_CLIENTWIDTH_INPUT_TEXT_157,
236
237 /** ClientWidth for text/password input is 173. */
238 @BrowserFeature({CHROME, EDGE})
239 JS_CLIENTWIDTH_INPUT_TEXT_173,
240
241 /** ClientWidth for radio button and checkbox is 14. */
242 @BrowserFeature({FF, FF_ESR})
243 JS_CLIENTWIDTH_RADIO_CHECKBOX_14,
244
245 /** item is enumerated before length property of CSSRuleList. */
246 @BrowserFeature({FF, FF_ESR})
247 JS_CSSRULELIST_ENUM_ITEM_LENGTH,
248
249 /** Javascript document.evaluate() creates a new result object even if provided as param. */
250 @BrowserFeature({CHROME, EDGE})
251 JS_DOCUMENT_EVALUATE_RECREATES_RESULT,
252
253 /** The browser has selection {@code rangeCount}. */
254 @BrowserFeature({FF, FF_ESR})
255 JS_DOCUMENT_SELECTION_RANGE_COUNT,
256
257 /** Javascript {@code Error.stackTraceLimit}. */
258 @BrowserFeature({CHROME, EDGE})
259 JS_ERROR_STACK_TRACE_LIMIT,
260
261 /** Javascript InputEvent reads the inputType property from data. */
262 @BrowserFeature({FF, FF_ESR})
263 JS_EVENT_INPUT_CTOR_INPUTTYPE,
264
265 /** Javascript KeyboardEvent reads the which property from data. */
266 @BrowserFeature({FF, FF_ESR})
267 JS_EVENT_KEYBOARD_CTOR_WHICH,
268
269 /** form.dispatchEvent(e) submits the form if the event is of type 'submit'. */
270 @BrowserFeature({FF, FF_ESR})
271 JS_FORM_DISPATCHEVENT_SUBMITS,
272
273 /** Executes the {@code onload} handler, regardless of the element was already attached to the page. */
274 @BrowserFeature({FF, FF_ESR})
275 JS_IFRAME_ALWAYS_EXECUTE_ONLOAD,
276
277 /**
278 * Getting the width and height of an image tag without a source returns 16x16;
279 * for invalid values returns 0.
280 */
281 @BrowserFeature({CHROME, EDGE})
282 JS_IMAGE_WIDTH_HEIGHT_RETURNS_16x16_0x0,
283
284 /**
285 * Getting the width and height of an image tag without a source returns 24x24;
286 * for invalid values returns 0x0.
287 */
288 @BrowserFeature({FF, FF_ESR})
289 JS_IMAGE_WIDTH_HEIGHT_RETURNS_24x24_0x0,
290
291 /** Indicates that innerText add a nl when reaching svg element. */
292 @BrowserFeature({CHROME, EDGE})
293 JS_INNER_TEXT_SVG_NL,
294
295 /** The value is ignored when the type of the week/month input is changed. */
296 @BrowserFeature({CHROME, EDGE})
297 JS_INPUT_CHANGE_TYPE_DROPS_VALUE_WEEK_MONTH,
298
299 /** FF accepts all chars. */
300 @BrowserFeature({FF, FF_ESR})
301 JS_INPUT_NUMBER_ACCEPT_ALL,
302
303 /** FF comma at end is not an integer. */
304 @BrowserFeature({FF, FF_ESR})
305 JS_INPUT_NUMBER_DOT_AT_END_IS_DOUBLE,
306
307 /** Indicates that Intl.v8BreakIterator is supported. */
308 @BrowserFeature({CHROME, EDGE})
309 JS_INTL_V8_BREAK_ITERATOR,
310
311 /** For the 'about' protocol the location always returns an empty query. */
312 @BrowserFeature({FF, FF_ESR})
313 JS_LOCATION_IGNORE_QUERY_FOR_ABOUT_PROTOCOL,
314
315 /** Reload sends a referrer header. */
316 @BrowserFeature({CHROME, EDGE})
317 JS_LOCATION_RELOAD_REFERRER,
318
319 /** Type property of menu returns the current (maybe invalid) value. */
320 @BrowserFeature({FF, FF_ESR})
321 JS_MENU_TYPE_PASS,
322
323 /** Indicates if the String representation of a native function is without newline. */
324 @BrowserFeature({CHROME, EDGE})
325 JS_NATIVE_FUNCTION_TOSTRING_COMPACT,
326
327 /** Indicates if the String representation of a native function has a newline for empty parameter list. */
328 @BrowserFeature({FF, FF_ESR})
329 JS_NATIVE_FUNCTION_TOSTRING_NL,
330
331 /** Navigator.doNotTrack returns unspecified if not set. */
332 @BrowserFeature({FF, FF_ESR})
333 JS_NAVIGATOR_DO_NOT_TRACK_UNSPECIFIED,
334
335 /** Indicates that someObj.offsetParent returns null, it someObj has fixed style. */
336 @BrowserFeature({CHROME, EDGE, FF})
337 JS_OFFSET_PARENT_NULL_IF_FIXED,
338
339 /** element.outerHTML removes all children from detached node. */
340 @BrowserFeature({CHROME, EDGE})
341 JS_OUTER_HTML_THROWS_FOR_DETACHED,
342
343 /** Indicates that the {@code Object.getOwnPropertyDescriptor.get} contains name. */
344 @BrowserFeature({FF, FF_ESR})
345 JS_PROPERTY_DESCRIPTOR_NAME,
346
347 /** script tags created from js as child of templates is processed if added to the dom. */
348 @BrowserFeature({CHROME, EDGE})
349 JS_SCRIPT_IN_TEMPLATE_EXECUTED_ON_ATTACH,
350
351 /** Javascript selectorText property returns selectors in lower case. */
352 @BrowserFeature({CHROME, EDGE})
353 JS_SELECTOR_TEXT_LOWERCASE,
354
355 /** Indicates that select.options.remove ignores the call if index is too large. */
356 @BrowserFeature({FF, FF_ESR})
357 JS_SELECT_REMOVE_IGNORE_IF_INDEX_OUTSIDE,
358
359 /** Whether to add to the storage even preserved words. */
360 @BrowserFeature({FF, FF_ESR})
361 JS_STORAGE_PRESERVED_INCLUDED,
362
363 /** window.getComputedStyle works with pseudo selectors without colon in front. */
364 @BrowserFeature({CHROME, EDGE})
365 JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON,
366
367 /** Javascript InstallTrigger property set to null. */
368 @BrowserFeature({FF, FF_ESR})
369 JS_WINDOW_INSTALL_TRIGGER_NULL,
370
371 /**
372 * Difference of window.outer/inner height is 138.
373 */
374 @BrowserFeature(EDGE)
375 JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_138,
376
377 /**
378 * Difference of window.outer/inner height is 147.
379 */
380 @BrowserFeature(CHROME)
381 JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_147,
382
383 /**
384 * Difference of window.outer/inner height is 94.
385 */
386 @BrowserFeature({FF, FF_ESR})
387 JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_94,
388
389 /** Window.getSelection returns null, if the window is not visible. */
390 @BrowserFeature({FF, FF_ESR})
391 JS_WINDOW_SELECTION_NULL_IF_INVISIBLE,
392
393 /** {@code XSLTProcessor.transformToDocument} supports output indent attribute. */
394 @BrowserFeature({CHROME, EDGE})
395 JS_XSLT_TRANSFORM_INDENT,
396
397 /** With special keys [in .type(int)], should we trigger onkeypress event or not. */
398 @BrowserFeature({FF, FF_ESR})
399 KEYBOARD_EVENT_SPECIAL_KEYPRESS,
400
401 /**
402 * Indicates that the Browser handles async and sync network errors the same way.
403 */
404 @BrowserFeature({FF, FF_ESR})
405 XHR_HANDLE_SYNC_NETWORK_ERRORS,
406
407 /** XMLHttpRequest triggers the load events also if the abort was signaled. */
408 @BrowserFeature({FF, FF_ESR})
409 XHR_LOAD_ALWAYS_AFTER_DONE,
410
411 /** If state unsent the response text is empty even if the response type is wrong. */
412 @BrowserFeature({FF, FF_ESR})
413 XHR_RESPONSE_TEXT_EMPTY_UNSENT,
414
415 /** Indicates if the XMLHttpRequest.send() method will throw if aborted. */
416 @BrowserFeature({CHROME, EDGE})
417 XHR_SEND_NETWORK_ERROR_IF_ABORTED,
418 }