All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gargoylesoftware.htmlunit.html.HtmlInput Maven / Gradle / Ivy

Go to download

XLT (Xceptance LoadTest) is an extensive load and performance test tool developed and maintained by Xceptance.

There is a newer version: 8.1.0
Show newest version
/*
 * Copyright (c) 2002-2020 Gargoyle Software Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gargoylesoftware.htmlunit.html;

import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_INPUT_DISPLAY_INLINE_BLOCK;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.CSS_INPUT_DISPLAY_RADIO_CHECKBOX_INLINE_BLOCK;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.EVENT_MOUSE_ON_DISABLED;
import static com.gargoylesoftware.htmlunit.BrowserVersionFeatures.HTMLINPUT_DOES_NOT_CLICK_SURROUNDING_ANCHOR;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;

import com.gargoylesoftware.htmlunit.HttpHeader;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.SgmlPage;
import com.gargoylesoftware.htmlunit.WebAssert;
import com.gargoylesoftware.htmlunit.javascript.AbstractJavaScriptEngine;
import com.gargoylesoftware.htmlunit.javascript.host.event.Event;
import com.gargoylesoftware.htmlunit.javascript.host.event.MouseEvent;
import com.gargoylesoftware.htmlunit.util.NameValuePair;

/**
 * Wrapper for the HTML element "input".
 *
 * @author Mike Bowler
 * @author David K. Taylor
 * @author Christian Sell
 * @author David D. Kilzer
 * @author Marc Guillemot
 * @author Daniel Gredler
 * @author Ahmed Ashour
 * @author Ronald Brill
 * @author Frank Danek
 */
public abstract class HtmlInput extends HtmlElement implements DisabledElement, SubmittableElement,
    FormFieldWithNameHistory {
    /** The HTML tag represented by this element. */
    public static final String TAG_NAME = "input";

    private String defaultValue_;
    private String originalName_;
    private Collection newNames_ = Collections.emptySet();
    private boolean createdByJavascript_;
    private Object valueAtFocus_;

    /**
     * Creates an instance.
     *
     * @param page the page that contains this element
     * @param attributes the initial attributes
     */
    public HtmlInput(final SgmlPage page, final Map attributes) {
        this(TAG_NAME, page, attributes);
    }

    /**
     * Creates an instance.
     *
     * @param qualifiedName the qualified name of the element type to instantiate
     * @param page the page that contains this element
     * @param attributes the initial attributes
     */
    public HtmlInput(final String qualifiedName, final SgmlPage page,
            final Map attributes) {
        super(qualifiedName, page, attributes);
        defaultValue_ = getValueAttribute();
        originalName_ = getNameAttribute();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setAttribute(final String attributeName, final String attributeValue) {
        if ("value".equals(attributeName)) {
            setValueAttribute(attributeValue);
        }
        else {
            super.setAttribute(attributeName, attributeValue);
        }
    }

    /**
     * Sets the content of the {@code value} attribute.
     *
     * @param newValue the new value
     */
    public void setValueAttribute(final String newValue) {
        WebAssert.notNull("newValue", newValue);
        super.setAttribute("value", newValue);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public NameValuePair[] getSubmitNameValuePairs() {
        return new NameValuePair[]{new NameValuePair(getNameAttribute(), getValueAttribute())};
    }

    /**
     * Returns the value of the attribute {@code type}. Refer to the
     * HTML 4.01
     * documentation for details on the use of this attribute.
     *
     * @return the value of the attribute {@code type} or an empty string if that attribute isn't defined
     */
    public final String getTypeAttribute() {
        final String type = getAttributeDirect("type");
        if (ATTRIBUTE_NOT_DEFINED == type) {
            return "text";
        }
        return type;
    }

    /**
     * Returns the value of the attribute {@code name}. Refer to the
     * HTML 4.01
     * documentation for details on the use of this attribute.
     *
     * @return the value of the attribute {@code name} or an empty string if that attribute isn't defined
     */
    public final String getNameAttribute() {
        return getAttributeDirect("name");
    }

    /**
     * 

Return the value of the attribute "value". Refer to the * HTML 4.01 * documentation for details on the use of this attribute.

* * @return the value of the attribute {@code value} or an empty string if that attribute isn't defined */ public final String getValueAttribute() { return getAttributeDirect("value"); } /** * Returns the value of the attribute {@code checked}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code checked} or an empty string if that attribute isn't defined */ public final String getCheckedAttribute() { return getAttributeDirect("checked"); } /** * {@inheritDoc} */ @Override public final String getDisabledAttribute() { return getAttributeDirect("disabled"); } /** * {@inheritDoc} */ @Override public final boolean isDisabled() { return hasAttribute("disabled"); } /** * Returns the value of the attribute {@code readonly}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code readonly} * or an empty string if that attribute isn't defined. */ public final String getReadOnlyAttribute() { return getAttributeDirect("readonly"); } /** * Returns the value of the attribute {@code size}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code size} * or an empty string if that attribute isn't defined. */ public final String getSizeAttribute() { return getAttributeDirect("size"); } /** * Returns the value of the attribute {@code maxlength}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code maxlength} * or an empty string if that attribute isn't defined. */ public final String getMaxLengthAttribute() { return getAttribute("maxLength"); } /** * Gets the max length if defined, Integer.MAX_VALUE if none. * @return the max length */ protected int getMaxLength() { final String maxLength = getMaxLengthAttribute(); if (maxLength.isEmpty()) { return Integer.MAX_VALUE; } try { return Integer.parseInt(maxLength.trim()); } catch (final NumberFormatException e) { return Integer.MAX_VALUE; } } /** * Returns the value of the attribute {@code src}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code src} * or an empty string if that attribute isn't defined. */ public final String getSrcAttribute() { return getSrcAttributeNormalized(); } /** * Returns the value of the attribute {@code alt}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code alt} * or an empty string if that attribute isn't defined. */ public final String getAltAttribute() { return getAttributeDirect("alt"); } /** * Returns the value of the attribute {@code usemap}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code usemap} * or an empty string if that attribute isn't defined. */ public final String getUseMapAttribute() { return getAttributeDirect("usemap"); } /** * Returns the value of the attribute {@code tabindex}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code tabindex} * or an empty string if that attribute isn't defined. */ public final String getTabIndexAttribute() { return getAttributeDirect("tabindex"); } /** * Returns the value of the attribute {@code accesskey}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code accesskey} * or an empty string if that attribute isn't defined. */ public final String getAccessKeyAttribute() { return getAttributeDirect("accesskey"); } /** * Returns the value of the attribute {@code onfocus}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code onfocus} * or an empty string if that attribute isn't defined. */ public final String getOnFocusAttribute() { return getAttributeDirect("onfocus"); } /** * Returns the value of the attribute {@code onblur}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code onblur} * or an empty string if that attribute isn't defined. */ public final String getOnBlurAttribute() { return getAttributeDirect("onblur"); } /** * Returns the value of the attribute {@code onselect}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code onselect} * or an empty string if that attribute isn't defined. */ public final String getOnSelectAttribute() { return getAttributeDirect("onselect"); } /** * Returns the value of the attribute {@code onchange}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code onchange} * or an empty string if that attribute isn't defined. */ public final String getOnChangeAttribute() { return getAttributeDirect("onchange"); } /** * Returns the value of the attribute {@code accept}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code accept} * or an empty string if that attribute isn't defined. */ public final String getAcceptAttribute() { return getAttribute(HttpHeader.ACCEPT_LC); } /** * Returns the value of the attribute {@code align}. Refer to the * HTML 4.01 * documentation for details on the use of this attribute. * * @return the value of the attribute {@code align} * or an empty string if that attribute isn't defined. */ public final String getAlignAttribute() { return getAttributeDirect("align"); } /** * {@inheritDoc} * @see SubmittableElement#reset() */ @Override public void reset() { setValueAttribute(defaultValue_); } /** * {@inheritDoc} * * @see SubmittableElement#setDefaultValue(String) */ @Override public void setDefaultValue(final String defaultValue) { setDefaultValue(defaultValue, true); } /** * Sets the default value, optionally also modifying the current value. * @param defaultValue the new default value * @param modifyValue Whether or not to set the current value to the default value */ protected void setDefaultValue(final String defaultValue, final boolean modifyValue) { final String oldAttributeValue = defaultValue_; final HtmlAttributeChangeEvent event; if (defaultValue_ == ATTRIBUTE_NOT_DEFINED) { event = new HtmlAttributeChangeEvent(this, "value", defaultValue); } else { event = new HtmlAttributeChangeEvent(this, "value", oldAttributeValue); } defaultValue_ = defaultValue; if (modifyValue) { if (this instanceof HtmlFileInput) { super.setAttribute("value", defaultValue); } else { setValueAttribute(defaultValue); } } notifyAttributeChangeListeners(event, this, oldAttributeValue, true); } /** * {@inheritDoc} * @see SubmittableElement#getDefaultValue() */ @Override public String getDefaultValue() { return defaultValue_; } /** * {@inheritDoc} The default implementation returns {@code false}; only checkboxes and * radio buttons really care what the default checked value is. * @see SubmittableElement#isDefaultChecked() * @see HtmlRadioButtonInput#isDefaultChecked() * @see HtmlCheckBoxInput#isDefaultChecked() */ @Override public boolean isDefaultChecked() { return false; } /** * Sets the {@code checked} attribute, returning the page that occupies this input's window after setting * the attribute. Note that the returned page may or may not be the original page, depending on * the presence of JavaScript event handlers, etc. * * @param isChecked {@code true} if this element is to be selected * @return the page that occupies this input's window after setting the attribute */ public Page setChecked(final boolean isChecked) { // By default this returns the current page. Derived classes will override. return getPage(); } /** * Sets the {@code readOnly} attribute. * * @param isReadOnly {@code true} if this element is read only */ public void setReadOnly(final boolean isReadOnly) { if (isReadOnly) { setAttribute("readOnly", "readOnly"); } else { removeAttribute("readOnly"); } } /** * Returns {@code true} if this element is currently selected. * @return {@code true} if this element is currently selected */ public boolean isChecked() { return hasAttribute("checked"); } /** * Returns {@code true} if this element is read only. * @return {@code true} if this element is read only */ public boolean isReadOnly() { return hasAttribute("readOnly"); } /** * {@inheritDoc} */ @Override protected boolean propagateClickStateUpdateToParent() { return !hasFeature(HTMLINPUT_DOES_NOT_CLICK_SURROUNDING_ANCHOR); } /** * {@inheritDoc} */ @Override public boolean handles(final Event event) { if (event instanceof MouseEvent && hasFeature(EVENT_MOUSE_ON_DISABLED)) { return true; } return super.handles(event); } /** * Executes the onchange script code for this element if this is appropriate. * This means that the element must have an onchange script, script must be enabled * and the change in the element must not have been triggered by a script. * * @param htmlElement the element that contains the onchange attribute * @return the page that occupies this window after this method completes (may or * may not be the same as the original page) */ static Page executeOnChangeHandlerIfAppropriate(final HtmlElement htmlElement) { final SgmlPage page = htmlElement.getPage(); final AbstractJavaScriptEngine engine = htmlElement.getPage().getWebClient().getJavaScriptEngine(); if (engine.isScriptRunning()) { return page; } final ScriptResult scriptResult = htmlElement.fireEvent(Event.TYPE_CHANGE); if (page.getWebClient().containsWebWindow(page.getEnclosingWindow())) { // may be itself or a newly loaded one return page.getEnclosingWindow().getEnclosedPage(); } if (scriptResult != null) { // current window doesn't exist anymore return page.getWebClient().getCurrentWindow().getEnclosedPage(); } return page; } /** * {@inheritDoc} */ @Override protected void setAttributeNS(final String namespaceURI, final String qualifiedName, final String attributeValue, final boolean notifyAttributeChangeListeners, final boolean notifyMutationObservers) { if ("name".equals(qualifiedName)) { if (newNames_.isEmpty()) { newNames_ = new HashSet<>(); } newNames_.add(attributeValue); } super.setAttributeNS(namespaceURI, qualifiedName, attributeValue, notifyAttributeChangeListeners, notifyMutationObservers); } /** * {@inheritDoc} */ @Override public String getOriginalName() { return originalName_; } /** * {@inheritDoc} */ @Override public Collection getNewNames() { return newNames_; } /** * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
* * Marks this frame as created by javascript. This is needed to handle * some special IE behavior. */ public void markAsCreatedByJavascript() { createdByJavascript_ = true; } /** * INTERNAL API - SUBJECT TO CHANGE AT ANY TIME - USE AT YOUR OWN RISK.
* * Returns true if this frame was created by javascript. This is needed to handle * some special IE behavior. * @return true or false */ public boolean wasCreatedByJavascript() { return createdByJavascript_; } /** * {@inheritDoc} */ @Override public final void focus() { super.focus(); // store current value to trigger onchange when needed at focus lost valueAtFocus_ = getInternalValue(); } /** * {@inheritDoc} */ @Override public final void removeFocus() { super.removeFocus(); if (valueAtFocus_ != null && !valueAtFocus_.equals(getInternalValue())) { handleFocusLostValueChanged(); } valueAtFocus_ = null; } void handleFocusLostValueChanged() { executeOnChangeHandlerIfAppropriate(this); } Object getInternalValue() { return getValueAttribute(); } /** * {@inheritDoc} */ @Override public DisplayStyle getDefaultStyleDisplay() { if (hasFeature(CSS_INPUT_DISPLAY_INLINE_BLOCK)) { return DisplayStyle.INLINE_BLOCK; } if (hasFeature(CSS_INPUT_DISPLAY_RADIO_CHECKBOX_INLINE_BLOCK)) { final String type = getTypeAttribute(); if ("radio".equals(type) || "checkbox".equals(type)) { return DisplayStyle.INLINE_BLOCK; } } return DisplayStyle.INLINE; } /** * Returns the value of the {@code size} attribute. * * @return the value of the {@code size} attribute */ public String getSize() { return getAttributeDirect("size"); } /** * Sets the {@code size} attribute. * * @param size the {@code size} attribute */ public void setSize(final String size) { setAttribute("size", size); } /** * Sets the {@code maxLength} attribute. * * @param maxLength the {@code maxLength} attribute */ public void setMaxLength(final int maxLength) { setAttribute("maxLength", String.valueOf(maxLength)); } /** * Sets the {@code minLength} attribute. * * @param minLength the {@code minLength} attribute */ public void setMinLength(final int minLength) { setAttribute("minLength", String.valueOf(minLength)); } /** * Returns the value of the {@code accept} attribute. * * @return the value of the {@code accept} attribute */ public String getAccept() { return getAttribute(HttpHeader.ACCEPT_LC); } /** * Sets the {@code accept} attribute. * * @param accept the {@code accept} attribute */ public void setAccept(final String accept) { setAttribute(HttpHeader.ACCEPT_LC, accept); } /** * Returns the value of the {@code autocomplete} attribute. * * @return the value of the {@code autocomplete} attribute */ public String getAutocomplete() { return getAttributeDirect("autocomplete"); } /** * Sets the {@code autocomplete} attribute. * * @param autocomplete the {@code autocomplete} attribute */ public void setAutocomplete(final String autocomplete) { setAttribute("autocomplete", autocomplete); } /** * Returns the value of the {@code placeholder} attribute. * * @return the value of the {@code placeholder} attribute */ public String getPlaceholder() { return getAttributeDirect("placeholder"); } /** * Sets the {@code placeholder} attribute. * * @param placeholder the {@code placeholder} attribute */ public void setPlaceholder(final String placeholder) { setAttribute("placeholder", placeholder); } /** * {@inheritDoc} */ @Override protected boolean isRequiredSupported() { return true; } /** * {@inheritDoc} */ @Override public DomNode cloneNode(final boolean deep) { final HtmlInput newnode = (HtmlInput) super.cloneNode(deep); newnode.newNames_ = new HashSet<>(newNames_); return newnode; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy