View Javadoc
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      /** Background image is 'initial'. */
42      @BrowserFeature({CHROME, EDGE})
43      CSS_BACKGROUND_INITIAL,
44  
45      /** Background image is 'rgba(0, 0, 0, 0)'. */
46      @BrowserFeature({FF, FF_ESR})
47      CSS_BACKGROUND_RGBA,
48  
49      /** Is display style 'block'. */
50      @BrowserFeature({FF, FF_ESR})
51      CSS_DISPLAY_BLOCK,
52  
53      /** The default value of the display property for the 'noscript' tag is 'inline' instead of the default one. */
54      @BrowserFeature({CHROME, EDGE})
55      CSS_NOSCRIPT_DISPLAY_INLINE,
56  
57      /** The default value of the display property for the 'rp' tag is 'none'. */
58      @BrowserFeature({FF, FF_ESR})
59      CSS_RP_DISPLAY_NONE,
60  
61      /** The default value of the display property for the 'rt' tag is always 'ruby-text'. */
62      @BrowserFeature({FF, FF_ESR})
63      CSS_RT_DISPLAY_RUBY_TEXT_ALWAYS,
64  
65      /** The context menu MouseEvent has a detail of 1. */
66      @BrowserFeature({FF, FF_ESR})
67      EVENT_CONTEXT_MENU_HAS_DETAIL_1,
68  
69      /** Triggers the onfocus event when focusing the body on load. */
70      @BrowserFeature({FF, FF_ESR})
71      EVENT_FOCUS_ON_LOAD,
72  
73      /** Scroll events are of type 'UIEvent'. */
74      @BrowserFeature({FF, FF_ESR})
75      EVENT_SCROLL_UIEVENT,
76  
77      /** Form elements are able to refer to the for by using the form attribute. */
78      @BrowserFeature({CHROME, EDGE})
79      FORM_IGNORE_REL_NOREFERRER,
80  
81      /** Form submit includes the Cache-Control: max-age=0 header. */
82      @BrowserFeature({CHROME, EDGE})
83      FORM_SUBMISSION_HEADER_CACHE_CONTROL_MAX_AGE,
84  
85      /** Should org.htmlunit.javascript.host.html.HTMLBaseFontElement#isEndTagForbidden(). */
86      @BrowserFeature({FF, FF_ESR})
87      HTMLBASEFONT_END_TAG_FORBIDDEN,
88  
89      /** HtmlCollection.namedItem searches by id first. */
90      @BrowserFeature({CHROME, EDGE})
91      HTMLCOLLECTION_NAMED_ITEM_ID_FIRST,
92  
93      /**
94      /** {@code document.getElementsByName} returns an empty list if called with the empty string.
95       */
96      @BrowserFeature({FF, FF_ESR})
97      HTMLDOCUMENT_ELEMENTS_BY_NAME_EMPTY,
98  
99      /** Removing the active element from the dom tree triggers the onblur event. */
100     @BrowserFeature({CHROME, EDGE})
101     HTMLELEMENT_REMOVE_ACTIVE_TRIGGERS_BLUR_EVENT,
102 
103     /** Handle blank source like empty. */
104     @BrowserFeature({CHROME, EDGE})
105     HTMLIMAGE_BLANK_SRC_AS_EMPTY,
106 
107     /** Empty src attribute sets display to false. */
108     @BrowserFeature({FF, FF_ESR})
109     HTMLIMAGE_EMPTY_SRC_DISPLAY_FALSE,
110 
111     /** Is document.cretaeElement('image') an HTMLElement. */
112     @BrowserFeature({FF, FF_ESR})
113     HTMLIMAGE_HTMLELEMENT,
114 
115     /** Is document.cretaeElement('image') an HTMLUnknownElement. */
116     @BrowserFeature({CHROME, EDGE})
117     HTMLIMAGE_HTMLUNKNOWNELEMENT,
118 
119     /** HTMLInputElement image type is not supported. */
120     @BrowserFeature({CHROME, EDGE})
121     HTMLINPUT_TYPE_IMAGE_IGNORES_CUSTOM_VALIDITY,
122 
123     /** HTMLInputElement month type is supported. */
124     @BrowserFeature({CHROME, EDGE})
125     HTMLINPUT_TYPE_MONTH_SUPPORTED,
126 
127     /** HTMLInputElement week type is supported. */
128     @BrowserFeature({CHROME, EDGE})
129     HTMLINPUT_TYPE_WEEK_SUPPORTED,
130 
131     /** For a stylesheet link report an error if the response type is not text/css. */
132     @BrowserFeature({FF, FF_ESR})
133     HTMLLINK_CHECK_RESPONSE_TYPE_FOR_STYLESHEET,
134 
135     /** If the type is present for a link only use if type is text/css. */
136     @BrowserFeature({CHROME, EDGE})
137     HTMLLINK_CHECK_TYPE_FOR_STYLESHEET,
138 
139     /** Should org.htmlunit.javascript.host.html.HTMLTrackElement#isEndTagForbidden(). */
140     @BrowserFeature({FF, FF_ESR})
141     HTMLTRACK_END_TAG_FORBIDDEN,
142 
143     /** HTML parser supports the 'layer' tag. */
144     @BrowserFeature({CHROME, EDGE})
145     HTML_LAYER_TAG,
146 
147     /** Additionally support dates in format "d/M/yyyy". */
148     @BrowserFeature({FF, FF_ESR})
149     HTTP_COOKIE_EXTENDED_DATE_PATTERNS_1,
150 
151     /** Dates format pattern 2. */
152     @BrowserFeature({CHROME, EDGE})
153     HTTP_COOKIE_EXTENDED_DATE_PATTERNS_2,
154 
155     /** domain '.org' is handled as 'org'. */
156     @BrowserFeature({FF, FF_ESR})
157     HTTP_COOKIE_REMOVE_DOT_FROM_ROOT_DOMAINS,
158 
159     /** Browser sends Sec-ch headers. */
160     @BrowserFeature({CHROME, EDGE})
161     HTTP_HEADER_CH_UA,
162 
163     /** Browser sends Priority headers. */
164     @BrowserFeature({FF, FF_ESR})
165     HTTP_HEADER_PRIORITY,
166 
167     /**
168      * The anchor pathname detects url's starting with one letter as file url's
169      * and replaces them with the file protocol. */
170     @BrowserFeature({CHROME, EDGE})
171     JS_ANCHOR_PATHNAME_DETECT_WIN_DRIVES_URL_REPLACE,
172 
173     /** The anchor pathname prefixes file url's with '/'. */
174     @BrowserFeature({CHROME, EDGE})
175     JS_ANCHOR_PATHNAME_PREFIX_WIN_DRIVES_URL,
176 
177     /** The anchor protocol property converts drive letters to uppercase. */
178     @BrowserFeature({CHROME, EDGE})
179     JS_ANCHOR_PROTOCOL_COLON_UPPER_CASE_DRIVE_LETTERS,
180 
181     /** An area element without a href attribute is focusable. */
182     @BrowserFeature({FF, FF_ESR})
183     JS_AREA_WITHOUT_HREF_FOCUSABLE,
184 
185     /** Sorting an array using a user defined comperator accepts inconsistent iterators. */
186     @BrowserFeature({FF, FF_ESR})
187     JS_ARRAY_SORT_ACCEPTS_INCONSISTENT_COMPERATOR,
188 
189     /** AudioProcessingEvent ctor is callable. */
190     @BrowserFeature({CHROME, EDGE})
191     JS_AUDIO_PROCESSING_EVENT_CTOR,
192 
193     /** toDataURL for canvas returns the CHROME version of the PNG. */
194     @BrowserFeature({CHROME, EDGE})
195     JS_CANVAS_DATA_URL_CHROME_PNG,
196 
197     /** ClientHeight for input is 17. */
198     @BrowserFeature({CHROME, EDGE})
199     JS_CLIENTHEIGHT_INPUT_17,
200 
201     /** ClientHeight for input is 18. */
202     @BrowserFeature({FF, FF_ESR})
203     JS_CLIENTHEIGHT_INPUT_18,
204 
205     /** ClientHeight for radio button and checkbox is 14. */
206     @BrowserFeature({FF, FF_ESR})
207     JS_CLIENTHEIGHT_RADIO_CHECKBOX_14,
208 
209     /** ClientHeight for rb is 17. */
210     @BrowserFeature({FF, FF_ESR})
211     JS_CLIENTHEIGHT_RB_17,
212 
213     /** ClientHeight for rt is 9. */
214     @BrowserFeature({FF, FF_ESR})
215     JS_CLIENTHEIGHT_RT_9,
216 
217     /** ClientHeight for ruby is 17. */
218     @BrowserFeature({FF, FF_ESR})
219     JS_CLIENTHEIGHT_RUBY_17,
220 
221     /** ClientWidth for text/password input is 173. */
222     @BrowserFeature({CHROME, EDGE})
223     JS_CLIENTWIDTH_INPUT_TEXT_173,
224 
225     /** ClientWidth for radio button and checkbox is 14. */
226     @BrowserFeature({FF, FF_ESR})
227     JS_CLIENTWIDTH_RADIO_CHECKBOX_14,
228 
229     /** item is enumerated before length property of CSSRuleList. */
230     @BrowserFeature({FF, FF_ESR})
231     JS_CSSRULELIST_ENUM_ITEM_LENGTH,
232 
233     /** Javascript document.evaluate() creates a new result object even if provided as param. */
234     @BrowserFeature({CHROME, EDGE})
235     JS_DOCUMENT_EVALUATE_RECREATES_RESULT,
236 
237     /** The browser has selection {@code rangeCount}. */
238     @BrowserFeature({FF, FF_ESR})
239     JS_DOCUMENT_SELECTION_RANGE_COUNT,
240 
241     /** Javascript {@code Error.stackTraceLimit}. */
242     @BrowserFeature({CHROME, EDGE})
243     JS_ERROR_STACK_TRACE_LIMIT,
244 
245     /** Javascript {@code Error.stackTraceLimit}. */
246     @BrowserFeature({FF, FF_ESR})
247     JS_ERROR_STACK_TRACE_LIMIT_128,
248 
249     /** Javascript InputEvent reads the inputType property from data. */
250     @BrowserFeature({FF, FF_ESR})
251     JS_EVENT_INPUT_CTOR_INPUTTYPE,
252 
253     /** Javascript KeyboardEvent reads the which property from data. */
254     @BrowserFeature({FF, FF_ESR})
255     JS_EVENT_KEYBOARD_CTOR_WHICH,
256 
257     /** form.dispatchEvent(e) submits the form if the event is of type 'submit'. */
258     @BrowserFeature({FF, FF_ESR})
259     JS_FORM_DISPATCHEVENT_SUBMITS,
260 
261     /** Executes the {@code onload} handler, regardless of the element was already attached to the page. */
262     @BrowserFeature({FF, FF_ESR})
263     JS_IFRAME_ALWAYS_EXECUTE_ONLOAD,
264 
265     /**
266      * Getting the width and height of an image tag without a source returns 16x16;
267      * for invalid values returns 0.
268      */
269     @BrowserFeature({CHROME, EDGE})
270     JS_IMAGE_WIDTH_HEIGHT_RETURNS_16x16_0x0,
271 
272     /**
273      * Getting the width and height of an image tag without a source returns 24x24;
274      * for invalid values returns 0x0.
275      */
276     @BrowserFeature({FF, FF_ESR})
277     JS_IMAGE_WIDTH_HEIGHT_RETURNS_24x24_0x0,
278 
279     /** Indicates that the HTML serialization of a processing instruction ends with '>' instead of '?>'. */
280     @BrowserFeature({FF, FF_ESR})
281     JS_INNER_HTML_PROCESSING_INSTRUCTION_NO_QUESTION_MARK,
282 
283     /** Indicates that innerHTML returns an empty string for empty elements. */
284     @BrowserFeature({CHROME, EDGE})
285     JS_INNER_HTML_VOID_ELEMENT_EMPTY,
286 
287     /**
288      * Indicates that the XML serialization writes boolean attributes of XHTML elements
289      * with an empty value as name="name" (e.g. disabled="disabled").
290      */
291     @BrowserFeature({FF, FF_ESR})
292     JS_INNER_HTML_XHTML_BOOLEAN_ATTRIBUTE_VALUE,
293 
294     /** Indicates that the XML serialization escapes line breaks in attribute values as hex references (
). */
295     @BrowserFeature({FF, FF_ESR})
296     JS_INNER_HTML_XHTML_HEX_LINE_BREAK,
297 
298     /** Indicates that the XML serialization writes the namespace declaration of an attribute after the attribute. */
299     @BrowserFeature({FF, FF_ESR})
300     JS_INNER_HTML_XHTML_NS_DECLARATION_AFTER_ATTRIBUTE,
301 
302     /** Indicates that innerHTML of a script or style element in an XHTML document returns the text as is. */
303     @BrowserFeature({FF, FF_ESR})
304     JS_INNER_HTML_XHTML_RAW_SCRIPT_STYLE,
305 
306     /** Indicates that innerText add a nl when reaching svg element. */
307     @BrowserFeature({FF, FF_ESR})
308     JS_INNER_TEXT_SELECT_EMPTY,
309 
310     /** Indicates that innerText add a nl when reaching svg element. */
311     @BrowserFeature({CHROME, EDGE})
312     JS_INNER_TEXT_SVG_NL,
313 
314     /** The value is ignored when the type of the week/month input is changed. */
315     @BrowserFeature({CHROME, EDGE})
316     JS_INPUT_CHANGE_TYPE_DROPS_VALUE_WEEK_MONTH,
317 
318     /** FF accepts all chars. */
319     @BrowserFeature({FF, FF_ESR})
320     JS_INPUT_NUMBER_ACCEPT_ALL,
321 
322     /** FF comma at end is not an integer. */
323     @BrowserFeature({FF, FF_ESR})
324     JS_INPUT_NUMBER_DOT_AT_END_IS_DOUBLE,
325 
326     /** Indicates that Intl.v8BreakIterator is supported. */
327     @BrowserFeature({CHROME, EDGE})
328     JS_INTL_V8_BREAK_ITERATOR,
329 
330     /** Reload sends a referrer header. */
331     @BrowserFeature({CHROME, EDGE})
332     JS_LOCATION_RELOAD_REFERRER,
333 
334     /** Type property of menu returns the current (maybe invalid) value. */
335     @BrowserFeature({FF, FF_ESR})
336     JS_MENU_TYPE_PASS,
337 
338     /** Indicates if the String representation of a native function is without newline. */
339     @BrowserFeature({CHROME, EDGE})
340     JS_NATIVE_FUNCTION_TOSTRING_COMPACT,
341 
342     /** Indicates if the String representation of a native function has a newline for empty parameter list. */
343     @BrowserFeature({FF, FF_ESR})
344     JS_NATIVE_FUNCTION_TOSTRING_NL,
345 
346     /** Navigator.doNotTrack returns unspecified if not set. */
347     @BrowserFeature({FF, FF_ESR})
348     JS_NAVIGATOR_DO_NOT_TRACK_UNSPECIFIED,
349 
350     /** PerformanceObserver.supportedEntryTypes returns only the entry types supported by Firefox. */
351     @BrowserFeature({FF, FF_ESR})
352     JS_PERFORMANCE_OBSERVER_ENTRY_TYPES_FF,
353 
354     /** PerformanceObserver.supportedEntryTypes returns a frozen array. */
355     @BrowserFeature({CHROME, EDGE})
356     JS_PERFORMANCE_OBSERVER_ENTRY_TYPES_FROZEN,
357 
358     /** Indicates that the {@code Object.getOwnPropertyDescriptor.get} contains name. */
359     @BrowserFeature({FF, FF_ESR})
360     JS_PROPERTY_DESCRIPTOR_NAME,
361 
362     /** script tags created from js as child of templates is processed if added to the dom. */
363     @BrowserFeature({CHROME, EDGE})
364     JS_SCRIPT_IN_TEMPLATE_EXECUTED_ON_ATTACH,
365 
366     /** Javascript selectorText property returns selectors in lower case. */
367     @BrowserFeature({CHROME, EDGE})
368     JS_SELECTOR_TEXT_LOWERCASE,
369 
370     /** Indicates that select.options.remove ignores the call if index is too large. */
371     @BrowserFeature({FF, FF_ESR})
372     JS_SELECT_REMOVE_IGNORE_IF_INDEX_OUTSIDE,
373 
374     /** Whether to add to the storage even preserved words. */
375     @BrowserFeature({FF, FF_ESR})
376     JS_STORAGE_PRESERVED_INCLUDED,
377 
378     /** window.getComputedStyle works with pseudo selectors without colon in front. */
379     @BrowserFeature({CHROME, EDGE})
380     JS_WINDOW_COMPUTED_STYLE_PSEUDO_ACCEPT_WITHOUT_COLON,
381 
382     /** Javascript InstallTrigger property set to null. */
383     @BrowserFeature({FF, FF_ESR})
384     JS_WINDOW_INSTALL_TRIGGER_NULL,
385 
386     /**
387      * Difference of window.outer/inner height is 138.
388      */
389     @BrowserFeature(EDGE)
390     JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_138,
391 
392     /**
393      * Difference of window.outer/inner height is 147.
394      */
395     @BrowserFeature(CHROME)
396     JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_147,
397 
398     /**
399      * Difference of window.outer/inner height is 94.
400      */
401     @BrowserFeature({FF, FF_ESR})
402     JS_WINDOW_OUTER_INNER_HEIGHT_DIFF_94,
403 
404     /** Window.getSelection returns null, if the window is not visible. */
405     @BrowserFeature({FF, FF_ESR})
406     JS_WINDOW_SELECTION_NULL_IF_INVISIBLE,
407 
408     /** Take care of the response charset when reading a worker script. */
409     @BrowserFeature({CHROME, EDGE})
410     JS_WORKER_SCRIPT_HONORS_CHARSET_HEADER,
411 
412     /** {@code XSLTProcessor.transformToDocument} supports output indent attribute. */
413     @BrowserFeature({CHROME, EDGE})
414     JS_XSLT_TRANSFORM_INDENT,
415 
416     /** With special keys [in .type(int)], should we trigger onkeypress event or not. */
417     @BrowserFeature({FF, FF_ESR})
418     KEYBOARD_EVENT_SPECIAL_KEYPRESS,
419 
420     /**
421      * Indicates that the Browser handles async and sync network errors the same way.
422      */
423     @BrowserFeature({FF, FF_ESR})
424     XHR_HANDLE_SYNC_NETWORK_ERRORS,
425 
426     /** XMLHttpRequest triggers the load events also if the abort was signaled. */
427     @BrowserFeature({FF, FF_ESR})
428     XHR_LOAD_ALWAYS_AFTER_DONE,
429 
430     /** Indicates if the XMLHttpRequest preflight request includes the 'Sec-Fetch-Mode=cors' header. */
431     @BrowserFeature({CHROME, EDGE})
432     XHR_PREFLIGHT_CORS,
433 
434     /** If state unsent the response text is empty even if the response type is wrong. */
435     @BrowserFeature({FF, FF_ESR})
436     XHR_RESPONSE_TEXT_EMPTY_UNSENT,
437 
438     /** Indicates if the XMLHttpRequest.send() method will throw if aborted. */
439     @BrowserFeature({CHROME, EDGE})
440     XHR_SEND_NETWORK_ERROR_IF_ABORTED,
441 }