1 /* 2 * Copyright (c) 2002-2025 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.html; 16 17 import java.io.IOException; 18 import java.util.Map; 19 20 import org.htmlunit.ElementNotFoundException; 21 import org.htmlunit.Page; 22 import org.htmlunit.SgmlPage; 23 import org.htmlunit.javascript.host.event.Event; 24 25 /** 26 * Wrapper for the HTML element "label". 27 * 28 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 29 * @author David K. Taylor 30 * @author <a href="mailto:cse@dynabean.de">Christian Sell</a> 31 * @author Marc Guillemot 32 * @author Ahmed Ashour 33 * @author Ronald Brill 34 * @author Frank Danek 35 */ 36 public class HtmlLabel extends HtmlElement { 37 38 /** The HTML tag represented by this element. */ 39 public static final String TAG_NAME = "label"; 40 41 /** 42 * Creates an instance of HtmlLabel 43 * 44 * @param qualifiedName the qualified name of the element type to instantiate 45 * @param page the HtmlPage that contains this element 46 * @param attributes the initial attributes 47 */ 48 HtmlLabel(final String qualifiedName, final SgmlPage page, 49 final Map<String, DomAttr> attributes) { 50 super(qualifiedName, page, attributes); 51 } 52 53 /** 54 * Returns the value of the attribute {@code for}. Refer to the 55 * <a href="http://www.w3.org/TR/html401/">HTML 4.01</a> 56 * documentation for details on the use of this attribute. 57 * 58 * @return the value of the attribute {@code for} 59 * or an empty string if that attribute isn't defined. 60 */ 61 public final String getForAttribute() { 62 return getAttributeDirect("for"); 63 } 64 65 /** 66 * Returns the value of the attribute {@code accesskey}. Refer to the 67 * <a href="http://www.w3.org/TR/html401/">HTML 4.01</a> 68 * documentation for details on the use of this attribute. 69 * 70 * @return the value of the attribute {@code accesskey} 71 * or an empty string if that attribute isn't defined. 72 */ 73 public final String getAccessKeyAttribute() { 74 return getAttributeDirect("accesskey"); 75 } 76 77 /** 78 * Returns the value of the attribute {@code onfocus}. Refer to the 79 * <a href="http://www.w3.org/TR/html401/">HTML 4.01</a> 80 * documentation for details on the use of this attribute. 81 * 82 * @return the value of the attribute {@code onfocus} 83 * or an empty string if that attribute isn't defined. 84 */ 85 public final String getOnFocusAttribute() { 86 return getAttributeDirect("onfocus"); 87 } 88 89 /** 90 * Returns the value of the attribute {@code onblur}. Refer to the 91 * <a href="http://www.w3.org/TR/html401/">HTML 4.01</a> 92 * documentation for details on the use of this attribute. 93 * 94 * @return the value of the attribute {@code onblur} 95 * or an empty string if that attribute isn't defined. 96 */ 97 public final String getOnBlurAttribute() { 98 return getAttributeDirect("onblur"); 99 } 100 101 /** 102 * Sets the focus to this element. 103 */ 104 @Override 105 public void focus() { 106 final HtmlElement element = getLabeledElement(); 107 if (element != null) { 108 element.focus(); 109 } 110 } 111 112 /** 113 * Gets the element labeled by this label. That is the labelable element in the page 114 * which id is equal to the value of the for attribute of this label or, if no for 115 * attribute is defined, the first nested labelable element. 116 * @return the element, {@code null} if not found 117 */ 118 public HtmlElement getLabeledElement() { 119 final String elementId = getForAttribute(); 120 if (ATTRIBUTE_NOT_DEFINED == elementId) { 121 for (final DomNode element : getChildren()) { 122 if (element instanceof LabelableElement) { 123 return (HtmlElement) element; 124 } 125 } 126 } 127 else { 128 try { 129 final HtmlElement element = ((HtmlPage) getPage()).getHtmlElementById(elementId); 130 if (element instanceof LabelableElement) { 131 return element; 132 } 133 } 134 catch (final ElementNotFoundException e) { 135 return null; 136 } 137 } 138 return null; 139 } 140 141 /** 142 * Clicks the label and propagates to the referenced element. 143 * {@inheritDoc} 144 */ 145 @Override 146 public <P extends Page> P click(final Event event, 147 final boolean shiftKey, final boolean ctrlKey, final boolean altKey, 148 final boolean ignoreVisibility) throws IOException { 149 // first the click on the label 150 final P page = super.click(event, shiftKey, ctrlKey, altKey, ignoreVisibility); 151 152 // then the click on the referenced element 153 final HtmlElement element = getLabeledElement(); 154 if (element == null || element.isDisabledElementAndDisabled()) { 155 return page; 156 } 157 158 // not sure which page we should return 159 return element.click(false, false, false, false, true, true, true); 160 } 161 162 /** 163 * {@inheritDoc} 164 */ 165 @Override 166 public DisplayStyle getDefaultStyleDisplay() { 167 return DisplayStyle.INLINE; 168 } 169 }