/*
 * Copyright (C) 2006 Apple Computer, Inc.
 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

module html {

    interface HTMLInputElement : HTMLElement {
                 attribute [ConvertNullToNullString] DOMString defaultValue;
                 attribute boolean         defaultChecked;
        readonly attribute HTMLFormElement form;
                 attribute boolean         formNoValidate;
        readonly attribute ValidityState   validity;
                 attribute [ConvertNullToNullString] DOMString accept;
                 attribute [ConvertNullToNullString] DOMString accessKey;
                 attribute [ConvertNullToNullString] DOMString align;
                 attribute [ConvertNullToNullString] DOMString alt;
                 attribute boolean         checked;
                 attribute boolean         disabled;
                 attribute boolean         autofocus;
#if defined(ENABLE_DATALIST) && ENABLE_DATALIST
        readonly attribute HTMLElement     list;
#endif
                 attribute [ConvertNullToNullString, Reflect] DOMString max;
                 attribute long            maxLength
                     setter raises(DOMException);
                 attribute [ConvertNullToNullString, Reflect] DOMString min;
                 attribute boolean         multiple;
                 attribute [ConvertNullToNullString] DOMString name;
                 attribute [ConvertNullToNullString, Reflect] DOMString pattern;
                 attribute DOMString       placeholder;
                 attribute boolean         readOnly;
                 attribute boolean         required;
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
                 attribute [ConvertToString] DOMString size; // DOM level 2 changed this to a long, but our existing API is a string
#else
                 // FIXME: the spec says this should be a long, not an unsigned long
                 attribute unsigned long   size; // Changed string -> long as part of DOM level 2
#endif
                 attribute [ConvertNullToNullString] DOMString src;
                 attribute [ConvertNullToNullString, Reflect] DOMString step;
                 attribute [ConvertNullToNullString, JSCCustomGetter] DOMString type; // readonly dropped as part of DOM level 2
                 attribute [ConvertNullToNullString] DOMString useMap;
                 attribute [ConvertNullToNullString] DOMString value;
                 attribute Date            valueAsDate setter raises(DOMException);
                 attribute double          valueAsNumber setter raises(DOMException);
#if defined(ENABLE_DATALIST) && ENABLE_DATALIST
        readonly attribute HTMLOptionElement selectedOption;
#endif

        void               stepUp(in [Optional] long n)
            raises(DOMException);
        void               stepDown(in [Optional] long n)
            raises(DOMException);

        readonly attribute boolean         willValidate;
        readonly attribute DOMString       validationMessage;
        boolean            checkValidity();
        void               setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
        void               select();
        void               click();

#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
        void               setValueForUser(in [ConvertNullToNullString] DOMString value);
#endif

        // WinIE extension:
                 attribute boolean         indeterminate;

        // WinIE & FireFox extension:

                 attribute [Custom] long selectionStart;
                 attribute [Custom] long selectionEnd;
        [Custom] void setSelectionRange(in long start, in long end);

#if defined(LANGUAGE_OBJECTIVE_C)
        // Objective-C extension:
        readonly attribute DOMString       altDisplayString;
        readonly attribute URL             absoluteImageURL;
#endif

        readonly attribute FileList files;
    };

}
