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