一、HTML <input> 标签
定义和用法
<input>
标签定义输入字段,用户可以在其中输入数据。
<input>
元素是最重要的表单元素。
<input>
元素可以以多种方式显示,具体取决于 type 属性。
以下是不同的输入类型:
<input type="button">
<input type="checkbox">
<input type="color">
<input type="date">
<input type="datetime-local">
<input type="email">
<input type="file">
<input type="hidden">
<input type="image">
<input type="month">
<input type="number">
<input type="password">
<input type="radio">
<input type="range">
<input type="reset">
<input type="search">
<input type="submit">
<input type="tel">
<input type="text">
(默认值)<input type="time">
<input type="url">
<input type="week">
参阅 type 属性,以查看每种输入类型的实例!
实例
包含三个输入字段的 HTML 表单;两个文本字段和一个提交按钮:
<form action="/action_page.php"> <label for="fname">名字:</label> <input type="text" id="fname" name="fname"><br><br> <label for="lname">姓氏:</label> <input type="text" id="lname" name="lname"><br><br> <input type="submit" value="提交"> </form>
二、<input> 在
html_tag_names.json5中接口定义:
(third_party\blink\renderer\core\html\html_tag_names.json5)
{
name: "input",
constructorNeedsCreateElementFlags: true,
interfaceHeaderDir: "third_party/blink/renderer/core/html/forms",
},
三、<input> 在blink中定义
third_party\blink\renderer\core\html\forms\input_type.h
third_party\blink\renderer\core\html\forms\input_type.cc
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_INPUT_TYPE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_INPUT_TYPE_H_
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/blink/public/mojom/forms/form_control_type.mojom-blink.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/frame/web_feature_forward.h"
#include "third_party/blink/renderer/core/html/forms/color_chooser_client.h"
#include "third_party/blink/renderer/core/html/forms/step_range.h"
#include "third_party/blink/renderer/core/html/forms/text_control_element.h"
namespace blink {
class ChromeClient;
class DragData;
class ExceptionState;
class FileList;
class FormData;
class InputTypeView;
// An InputType object represents the type-specific part of an HTMLInputElement.
// Do not expose instances of InputType and classes derived from it to classes
// other than HTMLInputElement.
class CORE_EXPORT InputType : public GarbageCollected<InputType> {
public:
// The type attribute of HTMLInputElement is an enumerated attribute:
// https://html.spec.whatwg.org/multipage/input.html#attr-input-type
// These values are a subset of the `FormControlType` enum. They have the same
// binary representation so that FormControlType() reduces to a type cast.
enum class Type : std::underlying_type_t<mojom::blink::FormControlType> {
kButton = base::to_underlying(mojom::blink::FormControlType::kInputButton),
kColor = base::to_underlying(mojom::blink::FormControlType::kInputColor),
kFile = base::to_underlying(mojom::blink::FormControlType::kInputFile),
kHidden = base::to_underlying(mojom::blink::FormControlType::kInputHidden),
kImage = base::to_underlying(mojom::blink::FormControlType::kInputImage),
kNumber = base::to_underlying(mojom::blink::FormControlType::kInputNumber),
kRange = base::to_underlying(mojom::blink::FormControlType::kInputRange),
kReset = base::to_underlying(mojom::blink::FormControlType::kInputReset),
kSubmit = base::to_underlying(mojom::blink::FormControlType::kInputSubmit),
// BaseCheckable
kRadio = base::to_underlying(mojom::blink::FormControlType::kInputRadio),
kCheckbox =
base::to_underlying(mojom::blink::FormControlType::kInputCheckbox),
// BaseTemporal
kDate = base::to_underlying(mojom::blink::FormControlType::kInputDate),
kDateTimeLocal =
base::to_underlying(mojom::blink::FormControlType::kInputDatetimeLocal),
kMonth = base::to_underlying(mojom::blink::FormControlType::kInputMonth),
kTime = base::to_underlying(mojom::blink::FormControlType::kInputTime),
kWeek = base::to_underlying(mojom::blink::FormControlType::kInputWeek),
// BaseText
kEmail = base::to_underlying(mojom::blink::FormControlType::kInputEmail),
kPassword =
base::to_underlying(mojom::blink::FormControlType::kInputPassword),
kSearch = base::to_underlying(mojom::blink::FormControlType::kInputSearch),
kTelephone =
base::to_underlying(mojom::blink::FormControlType::kInputTelephone),
kURL = base::to_underlying(mojom::blink::FormControlType::kInputUrl),
kText = base::to_underlying(mojom::blink::FormControlType::kInputText),
};
static const AtomicString& TypeToString(Type);
static InputType* Create(HTMLInputElement&, const AtomicString&);
static const AtomicString& NormalizeTypeName(const AtomicString&);
InputType(const InputType&) = delete;
InputType& operator=(const InputType&) = delete;
virtual ~InputType();
virtual void Trace(Visitor*) const;
virtual InputTypeView* CreateView() = 0;
Type type() const { return type_; }
const AtomicString& FormControlTypeAsString() const;
mojom::blink::FormControlType FormControlType() const {
return static_cast<mojom::blink::FormControlType>(
base::to_underlying(type_));
}
// Type query functions
// Any time we are using one of these functions it's best to refactor
// to add a virtual function to allow the input type object to do the
// work instead, or at least make a query function that asks a higher
// level question. These functions make the HTMLInputElement class
// inflexible because it's harder to add new input types if there is
// scattered code with special cases for various types.
virtual bool IsInteractiveContent() const;
virtual bool IsTextButton() const;
virtual bool IsTextField() const;
virtual bool IsAutoDirectionalityFormAssociated() const;
bool IsButtonInputType() const { return type_ == Type::kButton; }
bool IsColorInputType() const { return type_ == Type::kColor; }
bool IsFileInputType() const { return type_ == Type::kFile; }
bool IsHiddenInputType() const { return type_ == Type::kHidden; }
bool IsImageInputType() const { return type_ == Type::kImage; }
bool IsNumberInputType() const { return type_ == Type::kNumber; }
bool IsRangeInputType() const { return type_ == Type::kRange; }
bool IsResetInputType() const { return type_ == Type::kReset; }
bool IsSubmitInputType() const { return type_ == Type::kSubmit; }
bool IsRadioInputType() const { return type_ == Type::kRadio; }
bool IsCheckboxInputType() const { return type_ == Type::kCheckbox; }
bool IsBaseCheckableInputType() const {
return type_ == Type::kRadio || type_ == Type::kCheckbox;
}
bool IsDateInputType() const { return type_ == Type::kDate; }
bool IsDateTimeLocalInputType() const {
return type_ == Type::kDateTimeLocal;
}
bool IsMonthInputType() const { return type_ == Type::kMonth; }
bool IsTimeInputType() const { return type_ == Type::kTime; }
bool IsWeekInputType() const { return type_ == Type::kWeek; }
bool IsBaseTemporalInputType() const {
return type_ == Type::kDate || type_ == Type::kDateTimeLocal ||
type_ == Type::kMonth || type_ == Type::kTime ||
type_ == Type::kWeek;
}
bool IsEmailInputType() const { return type_ == Type::kEmail; }
bool IsPasswordInputType() const { return type_ == Type::kPassword; }
bool IsSearchInputType() const { return type_ == Type::kSearch; }
bool IsTelephoneInputType() const { return type_ == Type::kTelephone; }
bool IsTextInputType() const { return type_ == Type::kText; }
bool IsURLInputType() const { return type_ == Type::kURL; }
bool IsBaseTextInputType() const {
return type_ == Type::kEmail || type_ == Type::kPassword ||
type_ == Type::kSearch || type_ == Type::kTelephone ||
type_ == Type::kURL || type_ == Type::kText;
}
bool IsTextFieldInputType() const {
return IsBaseTextInputType() || IsNumberInputType();
}
bool IsValidValue(const String&) const;
// Form value functions
virtual bool ShouldSaveAndRestoreFormControlState() const;
virtual bool IsFormDataAppendable() const;
virtual void AppendToFormData(FormData&) const;
virtual String ResultForDialogSubmit() const;
// DOM property functions
// Returns a string value in ValueMode::kFilename.
virtual String ValueInFilenameValueMode() const;
// Default string to be used for showing button and form submission if |value|
// is missing.
virtual String DefaultLabel() const;
// https://html.spec.whatwg.org/C/#dom-input-value
enum class ValueMode { kValue, kDefault, kDefaultOn, kFilename };
virtual ValueMode GetValueMode() const = 0;
virtual double ValueAsDate() const;
virtual void SetValueAsDate(const absl::optional<base::Time>&,
ExceptionState&) const;
virtual double ValueAsDouble() const;
virtual void SetValueAsDouble(double,
TextFieldEventBehavior,
ExceptionState&) const;
virtual void SetValueAsDecimal(const Decimal&,
TextFieldEventBehavior,
ExceptionState&) const;
// Functions related to 'checked'
virtual void ReadingChecked() const;
// The function is called just before updating checkedness.
virtual void WillUpdateCheckedness(bool new_checked);
// Validation functions
// Returns a validation message as .first, and title attribute value as
// .second if patternMismatch.
std::pair<String, String> ValidationMessage(const InputTypeView&) const;
virtual bool SupportsValidation() const;
bool TypeMismatchFor(const String&) const;
// Type check for the current input value. We do nothing for some types
// though typeMismatchFor() does something for them because of value
// sanitization.
virtual bool TypeMismatch() const;
virtual bool SupportsRequired() const;
bool ValueMissing(const String&) const;
bool PatternMismatch(const String&) const;
virtual bool TooLong(const String&,
TextControlElement::NeedsToCheckDirtyFlag) const;
virtual bool TooShort(const String&,
TextControlElement::NeedsToCheckDirtyFlag) const;
bool RangeUnderflow(const String&) const;
bool RangeOverflow(const String&) const;
bool IsInRange(const String&) const;
bool IsOutOfRange(const String&) const;
void InRangeChanged() const;
virtual Decimal DefaultValueForStepUp() const;
double Minimum() const;
double Maximum() const;
bool StepMismatch(const String&) const;
bool GetAllowedValueStep(Decimal*) const;
virtual StepRange CreateStepRange(AnyStepHandling) const;
void StepUp(double, ExceptionState&);
void StepUpFromLayoutObject(int);
virtual String BadInputText() const;
virtual String ValueNotEqualText(const Decimal& value) const;
virtual String RangeOverflowText(const Decimal& maximum) const;
virtual String RangeUnderflowText(const Decimal& minimum) const;
virtual String ReversedRangeOutOfRangeText(const Decimal& minimum,
const Decimal& maximum) const;
virtual String RangeInvalidText(const Decimal& minimum,
const Decimal& maximum) const;
virtual String TypeMismatchText() const;
virtual String ValueMissingText() const;
bool CanSetStringValue() const;
virtual String LocalizeValue(const String&) const;
virtual String VisibleValue() const;
// Returing the null string means "use the default value."
// This function must be called only by HTMLInputElement::sanitizeValue().
virtual String SanitizeValue(const String&) const;
virtual String SanitizeUserInputValue(const String&) const;
virtual void WarnIfValueIsInvalid(const String&) const;
void WarnIfValueIsInvalidAndElementIsVisible(const String&) const;
virtual bool IsKeyboardFocusable(
Element::UpdateBehavior update_behavior =
Element::UpdateBehavior::kStyleAndLayout) const;
virtual bool MayTriggerVirtualKeyboard() const;
virtual bool CanBeSuccessfulSubmitButton();
virtual bool MatchesDefaultPseudoClass();
// Miscellaneous functions
virtual bool LayoutObjectIsNeeded();
virtual void CountUsage();
virtual void SanitizeValueInResponseToMinOrMaxAttributeChange();
virtual bool ShouldRespectAlignAttribute();
virtual FileList* Files();
// Should return true if the file list was were changed.
virtual bool SetFiles(FileList*);
virtual void SetFilesAndDispatchEvents(FileList*);
virtual void SetFilesFromPaths(const Vector<String>&);
// Should return true if the given DragData has more than one dropped files.
virtual bool ReceiveDroppedFiles(const DragData*);
virtual String DroppedFileSystemId();
// Should return true if the corresponding layoutObject for a type can display
// a suggested value.
virtual bool CanSetSuggestedValue();
virtual bool ShouldSendChangeEventAfterCheckedChanged();
virtual bool CanSetValue(const String&);
virtual void SetValue(const String&,
bool value_changed,
TextFieldEventBehavior,
TextControlSetValueSelection);
virtual bool ShouldRespectListAttribute();
virtual bool IsEnumeratable();
virtual bool IsCheckable();
bool IsSteppable() const;
virtual HTMLFormControlElement::PopoverTriggerSupport
SupportsPopoverTriggering() const;
virtual bool ShouldRespectHeightAndWidthAttributes();
virtual int MaxLength() const;
virtual int MinLength() const;
virtual bool SupportsPlaceholder() const;
virtual bool SupportsReadOnly() const;
virtual String DefaultToolTip(const InputTypeView&) const;
virtual Decimal FindClosestTickMarkValue(const Decimal&);
virtual bool HasLegalLinkAttribute(const QualifiedName&) const;
virtual void CopyNonAttributeProperties(const HTMLInputElement&);
virtual void OnAttachWithLayoutObject();
// Parses the specified string for the type, and return
// the Decimal value for the parsing result if the parsing
// succeeds; Returns defaultValue otherwise. This function can
// return NaN or Infinity only if defaultValue is NaN or Infinity.
virtual Decimal ParseToNumber(const String&,
const Decimal& default_value) const;
// Create a string representation of the specified Decimal value for the
// input type. If NaN or Infinity is specified, this returns an empty
// string. This should not be called for types without valueAsNumber.
virtual String Serialize(const Decimal&) const;
virtual bool ShouldAppearIndeterminate() const;
virtual bool SupportsInputModeAttribute() const;
virtual bool SupportsSelectionAPI() const;
// Gets width and height of the input element if the type of the
// element is image. It returns 0 if the element is not image type.
virtual unsigned Height() const;
virtual unsigned Width() const;
virtual void DispatchSearchEvent();
// For test purpose
virtual ColorChooserClient* GetColorChooserClient();
protected:
InputType(Type type, HTMLInputElement& element)
: type_(type), element_(element) {}
HTMLInputElement& GetElement() const { return *element_; }
ChromeClient* GetChromeClient() const;
Locale& GetLocale() const;
Decimal ParseToNumberOrNaN(const String&) const;
void CountUsageIfVisible(WebFeature) const;
// Derive the step base, following the HTML algorithm steps.
Decimal FindStepBase(const Decimal&) const;
StepRange CreateStepRange(AnyStepHandling,
const Decimal& step_base_default,
const Decimal& minimum_default,
const Decimal& maximum_default,
const StepRange::StepDescription&) const;
StepRange CreateReversibleStepRange(AnyStepHandling,
const Decimal& step_base_default,
const Decimal& minimum_default,
const Decimal& maximum_default,
const StepRange::StepDescription&) const;
void AddWarningToConsole(const char* message_format,
const String& value) const;
private:
// Helper for stepUp()/stepDown(). Adds step value * count to the current
// value.
void ApplyStep(const Decimal&,
double count,
AnyStepHandling,
TextFieldEventBehavior,
ExceptionState&);
StepRange CreateStepRange(AnyStepHandling,
const Decimal& step_base_default,
const Decimal& minimum_default,
const Decimal& maximum_default,
const StepRange::StepDescription&,
bool supports_reversed_range) const;
const Type type_;
Member<HTMLInputElement> element_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_INPUT_TYPE_H_
四、其中前端type="button" 对应 mojom::blink::FormControlType::kInputButton等定义
在third_party\blink\public\mojom\forms\form_control_type.mojom
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module blink.mojom;
// An enum representation of the values of the `type` attribute of form control
// elements. This list is exhaustive.
enum FormControlType {
// https://html.spec.whatwg.org/multipage/form-elements.html#attr-button-type
kButtonButton,
kButtonSubmit,
kButtonReset,
kButtonSelectList,
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-fieldset-type
kFieldset,
// https://html.spec.whatwg.org/multipage/input.html#attr-input-type
kInputButton,
kInputCheckbox,
kInputColor,
kInputDate,
kInputDatetimeLocal,
kInputEmail,
kInputFile,
kInputHidden,
kInputImage,
kInputMonth,
kInputNumber,
kInputPassword,
kInputRadio,
kInputRange,
kInputReset,
kInputSearch,
kInputSubmit,
kInputTelephone,
kInputText,
kInputTime,
kInputUrl,
kInputWeek,
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-output-type
kOutput,
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-select-type
kSelectOne,
kSelectMultiple,
kSelectList,
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-type
kTextArea,
};
对应实现:
out\Debug\gen\third_party\blink\public\mojom\forms\form_control_type.mojom-shared.h
out\Debug\gen\third_party\blink\public\mojom\forms\form_control_type.mojom-shared.cc
// third_party/blink/public/mojom/forms/form_control_type.mojom-shared.h is auto generated by mojom_bindings_generator.py, do not edit
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_PUBLIC_MOJOM_FORMS_FORM_CONTROL_TYPE_MOJOM_SHARED_H_
#define THIRD_PARTY_BLINK_PUBLIC_MOJOM_FORMS_FORM_CONTROL_TYPE_MOJOM_SHARED_H_
#include <stdint.h>
#include <functional>
#include <iosfwd>
#include <type_traits>
#include <utility>
#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
#include "third_party/blink/public/mojom/forms/form_control_type.mojom-shared-internal.h"
#include "base/component_export.h"
namespace blink::mojom {
} // blink::mojom
namespace mojo {
namespace internal {
} // namespace internal
} // namespace mojo
namespace blink::mojom {
enum class FormControlType : int32_t {
kButtonButton = 0,
kButtonSubmit = 1,
kButtonReset = 2,
kButtonSelectList = 3,
kFieldset = 4,
kInputButton = 5,
kInputCheckbox = 6,
kInputColor = 7,
kInputDate = 8,
kInputDatetimeLocal = 9,
kInputEmail = 10,
kInputFile = 11,
kInputHidden = 12,
kInputImage = 13,
kInputMonth = 14,
kInputNumber = 15,
kInputPassword = 16,
kInputRadio = 17,
kInputRange = 18,
kInputReset = 19,
kInputSearch = 20,
kInputSubmit = 21,
kInputTelephone = 22,
kInputText = 23,
kInputTime = 24,
kInputUrl = 25,
kInputWeek = 26,
kOutput = 27,
kSelectOne = 28,
kSelectMultiple = 29,
kSelectList = 30,
kTextArea = 31,
kMinValue = 0,
kMaxValue = 31,
};
COMPONENT_EXPORT(MOJOM_SHARED_BLINK_COMMON_EXPORT) std::ostream& operator<<(std::ostream& os, FormControlType value);
inline bool IsKnownEnumValue(FormControlType value) {
return internal::FormControlType_Data::IsKnownValue(
static_cast<int32_t>(value));
}
} // blink::mojom
namespace std {
template <>
struct hash<::blink::mojom::FormControlType>
: public mojo::internal::EnumHashImpl<::blink::mojom::FormControlType> {};
} // namespace std
namespace mojo {
namespace internal {
template <typename MaybeConstUserType>
struct Serializer<::blink::mojom::FormControlType, MaybeConstUserType> {
using UserType = typename std::remove_const<MaybeConstUserType>::type;
using Traits = EnumTraits<::blink::mojom::FormControlType, UserType>;
static void Serialize(UserType input, int32_t* output) {
*output = static_cast<int32_t>(Traits::ToMojom(input));
}
static bool Deserialize(int32_t input, UserType* output) {
return Traits::FromMojom(::mojo::internal::ToKnownEnumValueHelper(
static_cast<::blink::mojom::FormControlType>(input)), output);
}
};
} // namespace internal
} // namespace mojo
namespace blink::mojom {
} // blink::mojom
// Declare TraceFormatTraits for enums, which should be defined in ::perfetto
// namespace.
namespace perfetto {
template <>
struct COMPONENT_EXPORT(MOJOM_SHARED_BLINK_COMMON_EXPORT) TraceFormatTraits<::blink::mojom::FormControlType> {
static void WriteIntoTrace(perfetto::TracedValue context, ::blink::mojom::FormControlType value);
};
} // namespace perfetto
#endif // THIRD_PARTY_BLINK_PUBLIC_MOJOM_FORMS_FORM_CONTROL_TYPE_MOJOM_SHARED_H_