001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.bean.html5;
018
019import static org.apache.juneau.commons.utils.CollectionUtils.*;
020import static org.apache.juneau.commons.utils.ObjectUtils.*;
021import static org.apache.juneau.commons.utils.Shorts.*;
022import static org.apache.juneau.commons.utils.StringUtils.*;
023import static org.apache.juneau.marshall.html.HtmlFormat.*;
024import static org.apache.juneau.marshall.xml.XmlFormat.*;
025
026import java.net.*;
027
028import org.apache.juneau.commons.bean.*;
029import org.apache.juneau.commons.conversion.*;
030import org.apache.juneau.marshall.*;
031import org.apache.juneau.marshall.html.*;
032import org.apache.juneau.marshall.xml.*;
033
034/**
035 * Superclass for all HTML elements.
036 *
037 * <p>
038 * These are beans that when serialized using {@link HtmlSerializer} generate valid HTML5 elements.
039 *
040 * <h5 class='section'>See Also:</h5><ul>
041 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanHtml5">juneau-bean-html5</a>
042
043 * </ul>
044 *
045 * @param <SELF> The self type for fluent setters.
046 */
047@org.apache.juneau.marshall.html.Html(format = XML)
048@SuppressWarnings({
049   "java:S119" // 'SELF' (CRTP self-type) is intentional and clearer than a single-letter name.
050})
051public abstract class HtmlElement<SELF extends HtmlElement<SELF>> {
052
053   private java.util.Map<String,Object> attrs;
054
055   @SuppressWarnings({
056      "unchecked" // (SELF) this is the CRTP self-cast; SELF is bounded by HtmlElement<SELF>
057   })
058   protected final SELF self() {
059      return (SELF) this;
060   }
061
062   /**
063    * <a class="doclink" href="https://www.w3.org/TR/html5/dom.html#classes">class</a> attribute.
064    *
065    * <p>
066    * Specifies one or more CSS class names for the element, separated by spaces.
067    * These classes can be used for styling and JavaScript selection.
068    *
069    * @param value Space-separated CSS class names (e.g., <js>"btn btn-primary"</js>). Can be <jk>null</jk> to unset the attribute.
070    * @return This object.
071    */
072   @SuppressWarnings({
073      "java:S100" // Method name uses underscore prefix to match HTML attribute name
074   })
075   public SELF class_(String value) {
076      attr("class", value);
077      return self();
078   }
079
080   /**
081    * <a class="doclink" href="https://www.w3.org/TR/html5/editing.html#the-accesskey-attribute">accesskey</a>
082    * attribute.
083    *
084    * <p>
085    * Defines a keyboard shortcut to activate or focus an element.
086    * The value should be a single character that, when pressed with a modifier key (usually Alt),
087    * activates the element.
088    *
089    * @param value The keyboard shortcut character (e.g., <js>"a"</js>, <js>"1"</js>). Can be <jk>null</jk> to unset the attribute.
090    * @return This object.
091    */
092   public SELF accesskey(String value) {
093      attr("accesskey", value);
094      return self();
095   }
096
097   /**
098    * Adds an arbitrary attribute to this element.
099    *
100    * @param key The attribute name.
101    * @param val The attribute value. Can be <jk>null</jk> to remove the attribute.
102    * @return This object.
103    */
104   public SELF attr(String key, Object val) {
105      if (attrs == null)
106         attrs = map();
107      if (val == null)
108         attrs.remove(key);
109      else {
110         if (eqa(key, "url", "href") || key.endsWith("action"))
111            val = toUri(val);
112         attrs.put(key, val);
113      }
114      return self();
115   }
116
117   /**
118    * Adds an arbitrary URI attribute to this element.
119    *
120    * <p>
121    * Same as {@link #attr(String, Object)}, except if the value is a string that appears to be a URI
122    * (e.g. <js>"servlet:/xxx"</js>).
123    *
124    * <p>
125    * The value can be of any of the following types: {@link URI}, {@link URL}, {@link String}.
126    * Strings must be valid URIs.
127    *
128    * <p>
129    * URIs defined by {@link UriResolver} can be used for values.
130    *
131    * @param key The attribute name.
132    * @param val The attribute value. Can be <jk>null</jk>, in which case the attribute is added with a <jk>null</jk> value (unlike {@link #attr(String, Object)}, the key is not removed).
133    * @return This object.
134    */
135   public SELF attrUri(String key, Object val) {
136      if (attrs == null)
137         attrs = map();
138      attrs.put(key, toUri(val));
139      return self();
140   }
141
142   /**
143    * <a class="doclink" href="https://www.w3.org/TR/html5/editing.html#attr-contenteditable">contenteditable</a>
144    * attribute.
145    *
146    * <p>
147    * Indicates whether the element's content is editable by the user.
148    *
149    * <p>
150    * Possible values:
151    * <ul>
152    *    <li><js>"true"</js> or empty string - Element content is editable</li>
153    *    <li><js>"false"</js> - Element content is not editable</li>
154    *    <li><js>"plaintext-only"</js> - Element content is editable, but rich text formatting is disabled</li>
155    * </ul>
156    *
157    * @param value The editability state of the element. Can be <jk>null</jk> to unset the attribute.
158    * @return This object.
159    */
160   public SELF contenteditable(Object value) {
161      attr("contenteditable", value);
162      return self();
163   }
164
165   /**
166    * <a class="doclink" href="https://www.w3.org/TR/html5/dom.html#the-dir-attribute">dir</a> attribute.
167    *
168    * <p>
169    * Specifies the text direction of the element's content.
170    *
171    * <p>
172    * Possible values:
173    * <ul>
174    *    <li><js>"ltr"</js> - Left-to-right text direction</li>
175    *    <li><js>"rtl"</js> - Right-to-left text direction</li>
176    *    <li><js>"auto"</js> - Browser determines direction based on content</li>
177    * </ul>
178    *
179    * @param value The text direction for the element. Can be <jk>null</jk> to unset the attribute.
180    * @return This object.
181    */
182   public SELF dir(String value) {
183      attr("dir", value);
184      return self();
185   }
186
187   /**
188    * Returns the attribute with the specified name converted to the specified class type.
189    *
190    * @param <T> The class type to convert this class to.
191    * @param type
192    *    The class type to convert this class to.
193    *    See {@link BasicConverter} for a list of supported conversion types.
194    * @param key The attribute name.
195    * @return The attribute value, or <jk>null</jk> if the named attribute does not exist.
196    * @throws InvalidConversionException If the attribute value cannot be converted to the specified type.
197    */
198   public <T> T getAttr(Class<T> type, String key) {
199      return attrs == null ? null : BasicConverter.INSTANCE.to(attrs.get(key), type);
200   }
201
202   /**
203    * Returns the attribute with the specified name.
204    *
205    * @param key The attribute name.
206    * @return The attribute value, or <jk>null</jk> if the named attribute does not exist.
207    */
208   public String getAttr(String key) {
209      return getAttr(String.class, key);
210   }
211
212   /**
213    * The attributes of this element.
214    *
215    * @return The attributes of this element, or <jk>null</jk> if no attributes are set.
216    */
217   @Xml(format = ATTRS)
218   @BeanProp("a")
219   public java.util.Map<String,Object> getAttrs() { return attrs; }
220
221   /**
222    * <a class="doclink" href="https://www.w3.org/TR/html5/editing.html#the-hidden-attribute">hidden</a> attribute.
223    *
224    * <p>
225    * This attribute uses deminimized values:
226    * <ul>
227    *    <li><jk>false</jk> - Attribute is not added</li>
228    *    <li><jk>true</jk> - Attribute is added as <js>"hidden"</js></li>
229    *    <li>Other values - Passed through as-is</li>
230    * </ul>
231    *
232    * @param value
233    *    The new value for this attribute.
234    *    Typically a {@link Boolean} or {@link String}.
235    *    Can be <jk>null</jk> to unset the attribute.
236    * @return This object.
237    */
238   public SELF hidden(Object value) {
239      attr("hidden", deminimize(value, "hidden"));
240      return self();
241   }
242
243   /**
244    * <a class="doclink" href="https://www.w3.org/TR/html5/dom.html#the-id-attribute">id</a> attribute.
245    *
246    * <p>
247    * Specifies a unique identifier for the element. The ID must be unique within the document
248    * and can be used for CSS styling, JavaScript selection, and anchor links.
249    *
250    * @param value A unique identifier for the element (e.g., <js>"header"</js>, <js>"main-content"</js>). Can be <jk>null</jk> to unset the attribute.
251    * @return This object.
252    */
253   public SELF id(String value) {
254      attr("id", value);
255      return self();
256   }
257
258   /**
259    * <a class="doclink" href="https://www.w3.org/TR/html5/dom.html#attr-lang">lang</a> attribute.
260    *
261    * <p>
262    * Specifies the primary language of the element's content using a language tag.
263    * This helps with accessibility, search engines, and browser features like spell checking.
264    *
265    * @param value A language tag (e.g., <js>"en"</js>, <js>"en-US"</js>, <js>"es"</js>, <js>"fr-CA"</js>). Can be <jk>null</jk> to unset the attribute.
266    * @return This object.
267    */
268   public SELF lang(String value) {
269      attr("lang", value);
270      return self();
271   }
272
273   /**
274    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onabort">onabort</a> attribute.
275    *
276    * <p>
277    * Event handler for when an operation is aborted (e.g., image loading is cancelled).
278    *
279    * @param value JavaScript code to execute when the abort event occurs. Can be <jk>null</jk> to unset the attribute.
280    * @return This object.
281    */
282   public SELF onabort(String value) {
283      attr("onabort", value);
284      return self();
285   }
286
287   /**
288    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onblur">onblur</a> attribute.
289    *
290    * <p>
291    * Event handler for when the element loses focus.
292    *
293    * <h5 class='section'>Note:</h5>
294    * <p>
295    * If your HTML serializer is configured to use single quotes for attribute values, you should use double quotes
296    * in your JavaScript code, and vice versa. Otherwise, the quotes will be converted to HTML entities.
297    * For example:
298    * <ul>
299    *    <li>If using single quotes for attributes: <c>onblur(<js>"validate(\"email\")"</js>)</c>
300    *    <li>If using double quotes for attributes: <c>onblur(<js>"validate('email')"</js>)</c>
301    * </ul>
302    *
303    * @param value JavaScript code to execute when the element loses focus. Can be <jk>null</jk> to unset the attribute.
304    * @return This object.
305    */
306   public SELF onblur(String value) {
307      attr("onblur", value);
308      return self();
309   }
310
311   /**
312    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-oncancel">oncancel</a> attribute.
313    *
314    * <p>
315    * Event handler for when a dialog is cancelled.
316    *
317    * @param value JavaScript code to execute when the cancel event occurs. Can be <jk>null</jk> to unset the attribute.
318    * @return This object.
319    */
320   public SELF oncancel(String value) {
321      attr("oncancel", value);
322      return self();
323   }
324
325   /**
326    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-oncanplay">oncanplay</a> attribute.
327    *
328    * <p>
329    * Event handler for when the media can start playing (enough data has been buffered).
330    *
331    * @param value JavaScript code to execute when the canplay event occurs. Can be <jk>null</jk> to unset the attribute.
332    * @return This object.
333    */
334   public SELF oncanplay(String value) {
335      attr("oncanplay", value);
336      return self();
337   }
338
339   /**
340    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-oncanplaythrough">oncanplaythrough</a>
341    * attribute.
342    *
343    * <p>
344    * Event handler for when the media can play through to the end without buffering.
345    *
346    * @param value JavaScript code to execute when the canplaythrough event occurs. Can be <jk>null</jk> to unset the attribute.
347    * @return This object.
348    */
349   public SELF oncanplaythrough(String value) {
350      attr("oncanplaythrough", value);
351      return self();
352   }
353
354   /**
355    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onchange">onchange</a> attribute.
356    *
357    * <p>
358    * Event handler for when the value of a form element changes and loses focus.
359    *
360    * <h5 class='section'>Note:</h5>
361    * <p>
362    * If your HTML serializer is configured to use single quotes for attribute values, you should use double quotes
363    * in your JavaScript code, and vice versa. Otherwise, the quotes will be converted to HTML entities.
364    * For example:
365    * <ul>
366    *    <li>If using single quotes for attributes: <c>onchange(<js>"validate(\"field\")"</js>)</c>
367    *    <li>If using double quotes for attributes: <c>onchange(<js>"validate('field')"</js>)</c>
368    * </ul>
369    *
370    * @param value JavaScript code to execute when the change event occurs. Can be <jk>null</jk> to unset the attribute.
371    * @return This object.
372    */
373   public SELF onchange(String value) {
374      attr("onchange", value);
375      return self();
376   }
377
378   /**
379    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onclick">onclick</a> attribute.
380    *
381    * <p>
382    * Event handler for when the element is clicked.
383    *
384    * <h5 class='section'>Note:</h5>
385    * <p>
386    * If your HTML serializer is configured to use single quotes for attribute values, you should use double quotes
387    * in your JavaScript code, and vice versa. Otherwise, the quotes will be converted to HTML entities.
388    * For example:
389    * <ul>
390    *    <li>If using single quotes for attributes: <c>onclick(<js>"alert(\"Hello\")"</js>)</c>
391    *    <li>If using double quotes for attributes: <c>onclick(<js>"alert('Hello')"</js>)</c>
392    * </ul>
393    *
394    * @param value JavaScript code to execute when the click event occurs. Can be <jk>null</jk> to unset the attribute.
395    * @return This object.
396    */
397   public SELF onclick(String value) {
398      attr("onclick", value);
399      return self();
400   }
401
402   /**
403    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-oncuechange">oncuechange</a>
404    * attribute.
405    *
406    * <p>
407    * Event handler for when a text track cue changes.
408    *
409    * @param value JavaScript code to execute when the cuechange event occurs. Can be <jk>null</jk> to unset the attribute.
410    * @return This object.
411    */
412   public SELF oncuechange(String value) {
413      attr("oncuechange", value);
414      return self();
415   }
416
417   /**
418    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-ondblclick">ondblclick</a> attribute.
419    *
420    * <p>
421    * Event handler for when the element is double-clicked.
422    *
423    * @param value JavaScript code to execute when the dblclick event occurs. Can be <jk>null</jk> to unset the attribute.
424    * @return This object.
425    */
426   public SELF ondblclick(String value) {
427      attr("ondblclick", value);
428      return self();
429   }
430
431   /**
432    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-ondurationchange">ondurationchange</a>
433    * attribute.
434    *
435    * <p>
436    * Event handler for when the duration of the media changes.
437    *
438    * @param value JavaScript code to execute when the durationchange event occurs. Can be <jk>null</jk> to unset the attribute.
439    * @return This object.
440    */
441   public SELF ondurationchange(String value) {
442      attr("ondurationchange", value);
443      return self();
444   }
445
446   /**
447    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onemptied">onemptied</a> attribute.
448    *
449    * <p>
450    * Event handler for when the media element becomes empty (e.g., network error).
451    *
452    * @param value JavaScript code to execute when the emptied event occurs. Can be <jk>null</jk> to unset the attribute.
453    * @return This object.
454    */
455   public SELF onemptied(String value) {
456      attr("onemptied", value);
457      return self();
458   }
459
460   /**
461    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onended">onended</a> attribute.
462    *
463    * <p>
464    * Event handler for when the media playback reaches the end.
465    *
466    * @param value JavaScript code to execute when the ended event occurs. Can be <jk>null</jk> to unset the attribute.
467    * @return This object.
468    */
469   public SELF onended(String value) {
470      attr("onended", value);
471      return self();
472   }
473
474   /**
475    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onerror">onerror</a> attribute.
476    *
477    * <p>
478    * Event handler for when an error occurs (e.g., failed resource loading).
479    *
480    * @param value JavaScript code to execute when the error event occurs. Can be <jk>null</jk> to unset the attribute.
481    * @return This object.
482    */
483   public SELF onerror(String value) {
484      attr("onerror", value);
485      return self();
486   }
487
488   /**
489    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onfocus">onfocus</a> attribute.
490    *
491    * <p>
492    * Event handler for when the element receives focus.
493    *
494    * <h5 class='section'>Note:</h5>
495    * <p>
496    * If your HTML serializer is configured to use single quotes for attribute values, you should use double quotes
497    * in your JavaScript code, and vice versa. Otherwise, the quotes will be converted to HTML entities.
498    * For example:
499    * <ul>
500    *    <li>If using single quotes for attributes: <c>onfocus(<js>"highlight(\"field\")"</js>)</c>
501    *    <li>If using double quotes for attributes: <c>onfocus(<js>"highlight('field')"</js>)</c>
502    * </ul>
503    *
504    * @param value JavaScript code to execute when the focus event occurs. Can be <jk>null</jk> to unset the attribute.
505    * @return This object.
506    */
507   public SELF onfocus(String value) {
508      attr("onfocus", value);
509      return self();
510   }
511
512   /**
513    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-oninput">oninput</a> attribute.
514    *
515    * <p>
516    * Event handler for when the value of an input element changes (fires on every keystroke).
517    *
518    * @param value JavaScript code to execute when the input event occurs. Can be <jk>null</jk> to unset the attribute.
519    * @return This object.
520    */
521   public SELF oninput(String value) {
522      attr("oninput", value);
523      return self();
524   }
525
526   /**
527    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-oninvalid">oninvalid</a> attribute.
528    *
529    * <p>
530    * Event handler for when form validation fails.
531    *
532    * @param value JavaScript code to execute when the invalid event occurs. Can be <jk>null</jk> to unset the attribute.
533    * @return This object.
534    */
535   public SELF oninvalid(String value) {
536      attr("oninvalid", value);
537      return self();
538   }
539
540   /**
541    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onkeydown">onkeydown</a> attribute.
542    *
543    * <p>
544    * Event handler for when a key is pressed down.
545    *
546    * @param value JavaScript code to execute when the keydown event occurs. Can be <jk>null</jk> to unset the attribute.
547    * @return This object.
548    */
549   public SELF onkeydown(String value) {
550      attr("onkeydown", value);
551      return self();
552   }
553
554   /**
555    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onkeypress">onkeypress</a> attribute.
556    *
557    * <p>
558    * Event handler for when a key is pressed (deprecated, use onkeydown instead).
559    *
560    * @param value JavaScript code to execute when the keypress event occurs. Can be <jk>null</jk> to unset the attribute.
561    * @return This object.
562    */
563   public SELF onkeypress(String value) {
564      attr("onkeypress", value);
565      return self();
566   }
567
568   /**
569    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onkeyup">onkeyup</a> attribute.
570    *
571    * <p>
572    * Event handler for when a key is released.
573    *
574    * @param value JavaScript code to execute when the keyup event occurs. Can be <jk>null</jk> to unset the attribute.
575    * @return This object.
576    */
577   public SELF onkeyup(String value) {
578      attr("onkeyup", value);
579      return self();
580   }
581
582   /**
583    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onload">onload</a> attribute.
584    *
585    * <p>
586    * Event handler for when the element and its resources have finished loading.
587    *
588    * <h5 class='section'>Note:</h5>
589    * <p>
590    * If your HTML serializer is configured to use single quotes for attribute values, you should use double quotes
591    * in your JavaScript code, and vice versa. Otherwise, the quotes will be converted to HTML entities.
592    * For example:
593    * <ul>
594    *    <li>If using single quotes for attributes: <c>onload(<js>"init(\"config\")"</js>)</c>
595    *    <li>If using double quotes for attributes: <c>onload(<js>"init('config')"</js>)</c>
596    * </ul>
597    *
598    * @param value JavaScript code to execute when the load event occurs. Can be <jk>null</jk> to unset the attribute.
599    * @return This object.
600    */
601   public SELF onload(String value) {
602      attr("onload", value);
603      return self();
604   }
605
606   /**
607    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onloadeddata">onloadeddata</a>
608    * attribute.
609    *
610    * <p>
611    * Event handler for when the first frame of media has finished loading.
612    *
613    * @param value JavaScript code to execute when the loadeddata event occurs. Can be <jk>null</jk> to unset the attribute.
614    * @return This object.
615    */
616   public SELF onloadeddata(String value) {
617      attr("onloadeddata", value);
618      return self();
619   }
620
621   /**
622    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onloadedmetadata">onloadedmetadata</a>
623    * attribute.
624    *
625    * <p>
626    * Event handler for when metadata (duration, dimensions, etc.) has been loaded.
627    *
628    * @param value JavaScript code to execute when the loadedmetadata event occurs. Can be <jk>null</jk> to unset the attribute.
629    * @return This object.
630    */
631   public SELF onloadedmetadata(String value) {
632      attr("onloadedmetadata", value);
633      return self();
634   }
635
636   /**
637    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onloadstart">onloadstart</a>
638    * attribute.
639    *
640    * <p>
641    * Event handler for when the browser starts loading the media.
642    *
643    * @param value JavaScript code to execute when the loadstart event occurs. Can be <jk>null</jk> to unset the attribute.
644    * @return This object.
645    */
646   public SELF onloadstart(String value) {
647      attr("onloadstart", value);
648      return self();
649   }
650
651   /**
652    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmousedown">onmousedown</a>
653    * attribute.
654    *
655    * <p>
656    * Event handler for when a mouse button is pressed down on the element.
657    *
658    * @param value JavaScript code to execute when the mousedown event occurs. Can be <jk>null</jk> to unset the attribute.
659    * @return This object.
660    */
661   public SELF onmousedown(String value) {
662      attr("onmousedown", value);
663      return self();
664   }
665
666   /**
667    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmouseenter">onmouseenter</a> attribute.
668    *
669    * <p>
670    * Event handler for when the mouse pointer enters the element (does not bubble).
671    *
672    * @param value JavaScript code to execute when the mouseenter event occurs. Can be <jk>null</jk> to unset the attribute.
673    * @return This object.
674    */
675   public SELF onmouseenter(String value) {
676      attr("onmouseenter", value);
677      return self();
678   }
679
680   /**
681    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmouseleave">onmouseleave</a>
682    * attribute.
683    *
684    * <p>
685    * Event handler for when the mouse pointer leaves the element (does not bubble).
686    *
687    * @param value JavaScript code to execute when the mouseleave event occurs. Can be <jk>null</jk> to unset the attribute.
688    * @return This object.
689    */
690   public SELF onmouseleave(String value) {
691      attr("onmouseleave", value);
692      return self();
693   }
694
695   /**
696    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmousemove">onmousemove</a>
697    * attribute.
698    *
699    * <p>
700    * Event handler for when the mouse pointer moves over the element.
701    *
702    * @param value JavaScript code to execute when the mousemove event occurs. Can be <jk>null</jk> to unset the attribute.
703    * @return This object.
704    */
705   public SELF onmousemove(String value) {
706      attr("onmousemove", value);
707      return self();
708   }
709
710   /**
711    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmouseout">onmouseout</a> attribute.
712    *
713    * <p>
714    * Event handler for when the mouse pointer moves out of the element (bubbles).
715    *
716    * @param value JavaScript code to execute when the mouseout event occurs. Can be <jk>null</jk> to unset the attribute.
717    * @return This object.
718    */
719   public SELF onmouseout(String value) {
720      attr("onmouseout", value);
721      return self();
722   }
723
724   /**
725    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmouseover">onmouseover</a>
726    * attribute.
727    *
728    * <p>
729    * Event handler for when the mouse pointer moves over the element (bubbles).
730    *
731    * <h5 class='section'>Note:</h5>
732    * <p>
733    * If your HTML serializer is configured to use single quotes for attribute values, you should use double quotes
734    * in your JavaScript code, and vice versa. Otherwise, the quotes will be converted to HTML entities.
735    * For example:
736    * <ul>
737    *    <li>If using single quotes for attributes: <c>onmouseover(<js>"showTooltip(\"info\")"</js>)</c>
738    *    <li>If using double quotes for attributes: <c>onmouseover(<js>"showTooltip('info')"</js>)</c>
739    * </ul>
740    *
741    * @param value JavaScript code to execute when the mouseover event occurs. Can be <jk>null</jk> to unset the attribute.
742    * @return This object.
743    */
744   public SELF onmouseover(String value) {
745      attr("onmouseover", value);
746      return self();
747   }
748
749   /**
750    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmouseup">onmouseup</a> attribute.
751    *
752    * <p>
753    * Event handler for when a mouse button is released over the element.
754    *
755    * @param value JavaScript code to execute when the mouseup event occurs. Can be <jk>null</jk> to unset the attribute.
756    * @return This object.
757    */
758   public SELF onmouseup(String value) {
759      attr("onmouseup", value);
760      return self();
761   }
762
763   /**
764    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onmousewheel">onmousewheel</a>
765    * attribute.
766    *
767    * <p>
768    * Event handler for when the mouse wheel is rotated over the element (deprecated, use onwheel).
769    *
770    * @param value JavaScript code to execute when the mousewheel event occurs. Can be <jk>null</jk> to unset the attribute.
771    * @return This object.
772    */
773   public SELF onmousewheel(String value) {
774      attr("onmousewheel", value);
775      return self();
776   }
777
778   /**
779    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onpause">onpause</a> attribute.
780    *
781    * <p>
782    * Event handler for when media playback is paused.
783    *
784    * @param value JavaScript code to execute when the pause event occurs. Can be <jk>null</jk> to unset the attribute.
785    * @return This object.
786    */
787   public SELF onpause(String value) {
788      attr("onpause", value);
789      return self();
790   }
791
792   /**
793    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onplay">onplay</a> attribute.
794    *
795    * <p>
796    * Event handler for when media playback starts.
797    *
798    * @param value JavaScript code to execute when the play event occurs. Can be <jk>null</jk> to unset the attribute.
799    * @return This object.
800    */
801   public SELF onplay(String value) {
802      attr("onplay", value);
803      return self();
804   }
805
806   /**
807    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onplaying">onplaying</a> attribute.
808    *
809    * <p>
810    * Event handler for when media playback starts after being paused or delayed.
811    *
812    * @param value JavaScript code to execute when the playing event occurs. Can be <jk>null</jk> to unset the attribute.
813    * @return This object.
814    */
815   public SELF onplaying(String value) {
816      attr("onplaying", value);
817      return self();
818   }
819
820   /**
821    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onprogress">onprogress</a> attribute.
822    *
823    * <p>
824    * Event handler for when the browser is downloading media data.
825    *
826    * @param value JavaScript code to execute when the progress event occurs. Can be <jk>null</jk> to unset the attribute.
827    * @return This object.
828    */
829   public SELF onprogress(String value) {
830      attr("onprogress", value);
831      return self();
832   }
833
834   /**
835    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onratechange">onratechange</a>
836    * attribute.
837    *
838    * <p>
839    * Event handler for when the playback rate of media changes.
840    *
841    * @param value JavaScript code to execute when the ratechange event occurs. Can be <jk>null</jk> to unset the attribute.
842    * @return This object.
843    */
844   public SELF onratechange(String value) {
845      attr("onratechange", value);
846      return self();
847   }
848
849   /**
850    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onreset">onreset</a> attribute.
851    *
852    * <p>
853    * Event handler for when a form is reset.
854    *
855    * @param value JavaScript code to execute when the reset event occurs. Can be <jk>null</jk> to unset the attribute.
856    * @return This object.
857    */
858   public SELF onreset(String value) {
859      attr("onreset", value);
860      return self();
861   }
862
863   /**
864    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onresize">onresize</a> attribute.
865    *
866    * <p>
867    * Event handler for when the element is resized.
868    *
869    * @param value JavaScript code to execute when the resize event occurs. Can be <jk>null</jk> to unset the attribute.
870    * @return This object.
871    */
872   public SELF onresize(String value) {
873      attr("onresize", value);
874      return self();
875   }
876
877   /**
878    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onscroll">onscroll</a> attribute.
879    *
880    * <p>
881    * Event handler for when the element's scrollbar is scrolled.
882    *
883    * @param value JavaScript code to execute when the scroll event occurs. Can be <jk>null</jk> to unset the attribute.
884    * @return This object.
885    */
886   public SELF onscroll(String value) {
887      attr("onscroll", value);
888      return self();
889   }
890
891   /**
892    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onseeked">onseeked</a> attribute.
893    *
894    * <p>
895    * Event handler for when a seek operation completes.
896    *
897    * @param value JavaScript code to execute when the seeked event occurs. Can be <jk>null</jk> to unset the attribute.
898    * @return This object.
899    */
900   public SELF onseeked(String value) {
901      attr("onseeked", value);
902      return self();
903   }
904
905   /**
906    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onseeking">onseeking</a> attribute.
907    *
908    * <p>
909    * Event handler for when a seek operation begins.
910    *
911    * @param value JavaScript code to execute when the seeking event occurs. Can be <jk>null</jk> to unset the attribute.
912    * @return This object.
913    */
914   public SELF onseeking(String value) {
915      attr("onseeking", value);
916      return self();
917   }
918
919   /**
920    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onselect">onselect</a> attribute.
921    *
922    * <p>
923    * Event handler for when text is selected in the element.
924    *
925    * @param value JavaScript code to execute when the select event occurs. Can be <jk>null</jk> to unset the attribute.
926    * @return This object.
927    */
928   public SELF onselect(String value) {
929      attr("onselect", value);
930      return self();
931   }
932
933   /**
934    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onshow">onshow</a> attribute.
935    *
936    * <p>
937    * Event handler for when a context menu is shown.
938    *
939    * @param value JavaScript code to execute when the show event occurs. Can be <jk>null</jk> to unset the attribute.
940    * @return This object.
941    */
942   public SELF onshow(String value) {
943      attr("onshow", value);
944      return self();
945   }
946
947   /**
948    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onstalled">onstalled</a> attribute.
949    *
950    * <p>
951    * Event handler for when media loading is stalled.
952    *
953    * @param value JavaScript code to execute when the stalled event occurs. Can be <jk>null</jk> to unset the attribute.
954    * @return This object.
955    */
956   public SELF onstalled(String value) {
957      attr("onstalled", value);
958      return self();
959   }
960
961   /**
962    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onsubmit">onsubmit</a> attribute.
963    *
964    * <p>
965    * Event handler for when a form is submitted.
966    *
967    * <h5 class='section'>Note:</h5>
968    * <p>
969    * If your HTML serializer is configured to use single quotes for attribute values, you should use double quotes
970    * in your JavaScript code, and vice versa. Otherwise, the quotes will be converted to HTML entities.
971    * For example:
972    * <ul>
973    *    <li>If using single quotes for attributes: <c>onsubmit(<js>"return validate(\"form\")"</js>)</c>
974    *    <li>If using double quotes for attributes: <c>onsubmit(<js>"return validate('form')"</js>)</c>
975    * </ul>
976    *
977    * @param value JavaScript code to execute when the submit event occurs. Can be <jk>null</jk> to unset the attribute.
978    * @return This object.
979    */
980   public SELF onsubmit(String value) {
981      attr("onsubmit", value);
982      return self();
983   }
984
985   /**
986    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onsuspend">onsuspend</a> attribute.
987    *
988    * <p>
989    * Event handler for when media loading is suspended.
990    *
991    * @param value JavaScript code to execute when the suspend event occurs. Can be <jk>null</jk> to unset the attribute.
992    * @return This object.
993    */
994   public SELF onsuspend(String value) {
995      attr("onsuspend", value);
996      return self();
997   }
998
999   /**
1000    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-ontimeupdate">ontimeupdate</a>
1001    * attribute.
1002    *
1003    * <p>
1004    * Event handler for when the current playback position changes.
1005    *
1006    * @param value JavaScript code to execute when the timeupdate event occurs. Can be <jk>null</jk> to unset the attribute.
1007    * @return This object.
1008    */
1009   public SELF ontimeupdate(String value) {
1010      attr("ontimeupdate", value);
1011      return self();
1012   }
1013
1014   /**
1015    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-ontoggle">ontoggle</a> attribute.
1016    *
1017    * <p>
1018    * Event handler for when a details element is opened or closed.
1019    *
1020    * @param value JavaScript code to execute when the toggle event occurs. Can be <jk>null</jk> to unset the attribute.
1021    * @return This object.
1022    */
1023   public SELF ontoggle(String value) {
1024      attr("ontoggle", value);
1025      return self();
1026   }
1027
1028   /**
1029    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onvolumechange">onvolumechange</a>
1030    * attribute.
1031    *
1032    * <p>
1033    * Event handler for when the volume of media changes.
1034    *
1035    * @param value JavaScript code to execute when the volumechange event occurs. Can be <jk>null</jk> to unset the attribute.
1036    * @return This object.
1037    */
1038   public SELF onvolumechange(String value) {
1039      attr("onvolumechange", value);
1040      return self();
1041   }
1042
1043   /**
1044    * <a class="doclink" href="https://www.w3.org/TR/html5/webappapis.html#handler-onwaiting">onwaiting</a> attribute.
1045    *
1046    * <p>
1047    * Event handler for when media playback stops to buffer more data.
1048    *
1049    * @param value JavaScript code to execute when the waiting event occurs. Can be <jk>null</jk> to unset the attribute.
1050    * @return This object.
1051    */
1052   public SELF onwaiting(String value) {
1053      attr("onwaiting", value);
1054      return self();
1055   }
1056
1057   /**
1058    * Sets the attributes for this element.
1059    *
1060    * @param value The new attributes for this element. Can be <jk>null</jk> to clear all attributes.
1061    * @return This object.
1062    */
1063   @BeanProp("a")
1064   public SELF setAttrs(java.util.Map<String,Object> value) {
1065      if (nn(value)) {
1066         value.entrySet().forEach(x -> {
1067            var key = x.getKey();
1068            if (eqa(key, "url", "href") || key.endsWith("action"))
1069               x.setValue(toUri(x.getValue()));
1070         });
1071      }
1072      attrs = value;
1073      return self();
1074   }
1075
1076   /**
1077    * <a class="doclink" href="https://www.w3.org/TR/html5/editing.html#attr-spellcheck">spellcheck</a> attribute.
1078    *
1079    * <p>
1080    * Indicates whether the element should have its spelling and grammar checked.
1081    *
1082    * <p>
1083    * Possible values:
1084    * <ul>
1085    *    <li><js>"true"</js> - Enable spell checking for this element</li>
1086    *    <li><js>"false"</js> - Disable spell checking for this element</li>
1087    * </ul>
1088    *
1089    * @param value Whether spell checking should be enabled. Can be <jk>null</jk> to unset the attribute.
1090    * @return This object.
1091    */
1092   public SELF spellcheck(Object value) {
1093      attr("spellcheck", value);
1094      return self();
1095   }
1096
1097   /**
1098    * <a class="doclink" href="https://www.w3.org/TR/html5/dom.html#the-style-attribute">style</a> attribute.
1099    *
1100    * <p>
1101    * Specifies inline CSS styles for the element. The value should be valid CSS
1102    * property-value pairs separated by semicolons.
1103    *
1104    * @param value Inline CSS styles (e.g., <js>"color: red; font-size: 14px;"</js>). Can be <jk>null</jk> to unset the attribute.
1105    * @return This object.
1106    */
1107   public SELF style(String value) {
1108      attr("style", value);
1109      return self();
1110   }
1111
1112   /**
1113    * <a class="doclink" href="https://www.w3.org/TR/html5/editing.html#attr-tabindex">tabindex</a> attribute.
1114    *
1115    * <p>
1116    * Specifies the tab order of the element when navigating with the keyboard.
1117    *
1118    * <p>
1119    * Possible values:
1120    * <ul>
1121    *    <li>Positive integer - Element is focusable and participates in tab order</li>
1122    *    <li><js>"0"</js> - Element is focusable but not in tab order</li>
1123    *    <li>Negative integer - Element is not focusable</li>
1124    * </ul>
1125    *
1126    * @param value The tab order value for keyboard navigation. Can be <jk>null</jk> to unset the attribute.
1127    * @return This object.
1128    */
1129   public SELF tabindex(Object value) {
1130      attr("tabindex", value);
1131      return self();
1132   }
1133
1134   /**
1135    * <a class="doclink" href="https://www.w3.org/TR/html5/dom.html#attr-title">title</a> attribute.
1136    *
1137    * <p>
1138    * Specifies additional information about the element, typically displayed as a tooltip
1139    * when the user hovers over the element.
1140    *
1141    * @param value Tooltip text to display on hover (e.g., <js>"Click to submit form"</js>). Can be <jk>null</jk> to unset the attribute.
1142    * @return This object.
1143    */
1144   public SELF title(String value) {
1145      attr("title", value);
1146      return self();
1147   }
1148
1149   @Override /* Overridden from Object */
1150   public String toString() {
1151      return HtmlSerializer.DEFAULT_SIMPLE_SQ.toString(this);
1152   }
1153
1154   /**
1155    * <a class="doclink" href="https://www.w3.org/TR/html5/dom.html#attr-translate">translate</a> attribute.
1156    *
1157    * <p>
1158    * Specifies whether the element's content should be translated when the page is localized.
1159    *
1160    * <p>
1161    * Possible values:
1162    * <ul>
1163    *    <li><js>"yes"</js> - Content should be translated (default)</li>
1164    *    <li><js>"no"</js> - Content should not be translated</li>
1165    * </ul>
1166    *
1167    * @param value Whether the element content should be translated. Can be <jk>null</jk> to unset the attribute.
1168    * @return This object.
1169    */
1170   public SELF translate(Object value) {
1171      attr("translate", value);
1172      return self();
1173   }
1174
1175   /**
1176    * If the specified attribute is a boolean, it gets converted to the attribute name if <jk>true</jk> or <jk>null</jk> if <jk>false</jk>.
1177    *
1178    * @param value The attribute value. Can be <jk>null</jk> (returned as-is, since <jk>null</jk> is not a <c>Boolean</c>).
1179    * @param attr The attribute name.
1180    * @return The deminimized value, or the same value if the value wasn't a boolean, or <jk>null</jk> if the value was a boolean <jk>false</jk>.
1181   */
1182   protected Object deminimize(Object value, String attr) {
1183      if (value instanceof Boolean value2) {
1184         if (isTrue(value2))
1185            return attr;
1186         return null;
1187      }
1188      return value;
1189   }
1190}