| /* |
| * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| * (C) 2000 Dirk Mueller (mueller@kde.org) |
| * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved. |
| * Copyright (C) 2012 Samsung Electronics. All rights reserved. |
| * |
| * 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. |
| * |
| */ |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_INPUT_ELEMENT_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_INPUT_ELEMENT_H_ |
| |
| #include "base/gtest_prod_util.h" |
| #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h" |
| #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" |
| #include "third_party/blink/renderer/bindings/core/v8/script_regexp.h" |
| #include "third_party/blink/renderer/core/core_export.h" |
| #include "third_party/blink/renderer/core/dom/create_element_flags.h" |
| #include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" |
| #include "third_party/blink/renderer/core/html/forms/file_chooser.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 AXObject; |
| class DragData; |
| class ExceptionState; |
| class FileList; |
| class HTMLDataListElement; |
| class HTMLImageLoader; |
| class InputType; |
| class InputTypeView; |
| class KURL; |
| class ListAttributeTargetObserver; |
| class RadioButtonGroupScope; |
| class ScriptValue; |
| struct DateTimeChooserParameters; |
| |
| class CORE_EXPORT HTMLInputElement |
| : public TextControlElement, |
| public ActiveScriptWrappable<HTMLInputElement> { |
| DEFINE_WRAPPERTYPEINFO(); |
| |
| public: |
| HTMLInputElement(Document&, const CreateElementFlags); |
| ~HTMLInputElement() override; |
| void Trace(Visitor*) const override; |
| |
| bool HasPendingActivity() const final; |
| |
| DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange, kWebkitspeechchange) |
| |
| bool ShouldAutocomplete() const final; |
| |
| // For ValidityState |
| bool HasBadInput() const final; |
| bool PatternMismatch() const final; |
| bool RangeUnderflow() const final; |
| bool RangeOverflow() const final; |
| bool StepMismatch() const final; |
| bool TooLong() const final; |
| bool TooShort() const final; |
| bool TypeMismatch() const final; |
| bool ValueMissing() const final; |
| String validationMessage() const final; |
| String ValidationSubMessage() const final; |
| |
| // Returns the minimum value for type=date, number, or range. Don't call this |
| // for other types. |
| double Minimum() const; |
| // Returns the maximum value for type=date, number, or range. Don't call this |
| // for other types. This always returns a value which is >= minimum(). |
| double Maximum() const; |
| // Sets the "allowed value step" defined in the HTML spec to the specified |
| // double pointer. Returns false if there is no "allowed value step." |
| bool GetAllowedValueStep(Decimal*) const; |
| StepRange CreateStepRange(AnyStepHandling) const; |
| |
| Decimal FindClosestTickMarkValue(const Decimal&); |
| |
| // Implementations of HTMLInputElement::stepUp() and stepDown(). |
| void stepUp(int, ExceptionState&); |
| void stepDown(int, ExceptionState&); |
| // stepUp()/stepDown() for user-interaction. |
| bool IsSteppable() const; |
| |
| // Returns true if the type is button, reset, or submit. |
| bool IsTextButton() const; |
| // Returns true if the type is email, number, password, search, tel, text, |
| // or url. |
| bool IsTextField() const; |
| // Do not add type check predicates for concrete input types; e.g. isImage, |
| // isRadio, isFile. If you want to check the input type, you may use |
| // |input->type() == input_type_names::kImage|, etc. |
| |
| // Returns whether this field is or has ever been a password field so that |
| // its value can be protected from memorization by autofill or keyboards. |
| bool HasBeenPasswordField() const; |
| |
| bool checked() const; |
| void setChecked( |
| bool, |
| TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent); |
| void DispatchChangeEventIfNeeded(); |
| void DispatchInputAndChangeEventIfNeeded(); |
| |
| // 'indeterminate' is a state independent of the checked state that causes the |
| // control to draw in a way that hides the actual state. |
| bool indeterminate() const { return is_indeterminate_; } |
| void setIndeterminate(bool); |
| // shouldAppearChecked is used by the layout tree/CSS while checked() is used |
| // by JS to determine checked state |
| bool ShouldAppearChecked() const; |
| bool ShouldAppearIndeterminate() const override; |
| |
| // Returns null if this isn't associated with any radio button group. |
| RadioButtonGroupScope* GetRadioButtonGroupScope() const; |
| |
| unsigned size() const; |
| bool SizeShouldIncludeDecoration(int& preferred_size) const; |
| |
| void setType(const AtomicString&); |
| |
| String value() const override; |
| void setValue( |
| const String&, |
| ExceptionState&, |
| TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent); |
| void setValue( |
| const String&, |
| TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent, |
| TextControlSetValueSelection = |
| TextControlSetValueSelection::kSetSelectionToEnd) override; |
| void SetValueForUser(const String&); |
| // Update the value, and clear hasDirtyValue() flag. |
| void SetNonDirtyValue(const String&); |
| // Checks if the specified string would be a valid value. |
| // We should not call this for types with no string value such as CHECKBOX and |
| // RADIO. |
| bool IsValidValue(const String&) const; |
| bool HasDirtyValue() const; |
| |
| String SanitizeValue(const String&) const; |
| |
| String LocalizeValue(const String&) const; |
| |
| void SetSuggestedValue(const String& value) override; |
| |
| void SetEditingValue(const String&); |
| |
| ScriptValue valueAsDate(ScriptState* script_state) const; |
| void setValueAsDate(ScriptState* script_state, |
| const ScriptValue& value, |
| ExceptionState& exception_state); |
| |
| double valueAsNumber() const; |
| void setValueAsNumber( |
| double, |
| ExceptionState&, |
| TextFieldEventBehavior = TextFieldEventBehavior::kDispatchNoEvent); |
| |
| // For type=range, returns a ratio of the current value in the range between |
| // min and max. i.e. (value - min) / (max - min) |
| // For other types, this function fails with DCHECK(). |
| Decimal RatioValue() const; |
| |
| String ValueOrDefaultLabel() const; |
| |
| // This function dispatches 'input' event for non-textfield types. Callers |
| // need to handle any DOM structure changes by event handlers, or need to |
| // delay the 'input' event with EventQueueScope. |
| void SetValueFromRenderer(const String&); |
| |
| base::Optional<uint32_t> selectionStartForBinding(ExceptionState&) const; |
| base::Optional<uint32_t> selectionEndForBinding(ExceptionState&) const; |
| String selectionDirectionForBinding(ExceptionState&) const; |
| void setSelectionStartForBinding(base::Optional<uint32_t>, ExceptionState&); |
| void setSelectionEndForBinding(base::Optional<uint32_t>, ExceptionState&); |
| void setSelectionDirectionForBinding(const String&, ExceptionState&); |
| void setSelectionRangeForBinding(unsigned start, |
| unsigned end, |
| ExceptionState&); |
| void setSelectionRangeForBinding(unsigned start, |
| unsigned end, |
| const String& direction, |
| ExceptionState&); |
| // This function can be used to allow tests to set the selection |
| // range for Number inputs, which do not support the ordinary |
| // selection API. |
| void SetSelectionRangeForTesting(unsigned start, |
| unsigned end, |
| ExceptionState&); |
| |
| bool LayoutObjectIsNeeded(const ComputedStyle&) const final; |
| LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; |
| void DetachLayoutTree(bool performing_reattach) final; |
| void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus, |
| const FocusOptions*) final; |
| |
| // FIXME: For isActivatedSubmit and setActivatedSubmit, we should use the |
| // NVI-idiom here by making it private virtual in all classes and expose a |
| // public method in HTMLFormControlElement to call |
| // the private virtual method. |
| bool IsActivatedSubmit() const final; |
| void SetActivatedSubmit(bool flag) final; |
| |
| String AltText() const final; |
| |
| const AtomicString& DefaultValue() const; |
| |
| Vector<String> AcceptMIMETypes() const; |
| Vector<String> AcceptFileExtensions() const; |
| const AtomicString& Alt() const; |
| |
| void setSize(unsigned, ExceptionState&); |
| |
| KURL Src() const; |
| bool Multiple() const; |
| |
| FileList* files() const; |
| void setFiles(FileList*); |
| |
| void SetFilesFromPaths(const Vector<String>&); |
| |
| // Returns true if the given DragData has more than one dropped files. |
| bool ReceiveDroppedFiles(const DragData*); |
| |
| String DroppedFileSystemId(); |
| |
| // These functions are used for laying out the input active during a |
| // drag-and-drop operation. |
| bool CanReceiveDroppedFiles() const; |
| void SetCanReceiveDroppedFiles(bool); |
| |
| // Returns 'Choose File(s)' button in a file control. This returns |
| // nullptr for other input types. |
| HTMLInputElement* UploadButton() const; |
| |
| void OnSearch(); |
| |
| void UpdateClearButtonVisibility(); |
| |
| bool WillRespondToMouseClickEvents() override; |
| |
| HTMLElement* list() const; |
| HTMLDataListElement* DataList() const; |
| bool HasValidDataListOptions() const; |
| void ListAttributeTargetChanged(); |
| // Associated <datalist> options which match to the current INPUT value. |
| HeapVector<Member<HTMLOptionElement>> FilteredDataListOptions() const; |
| |
| // Functions for InputType classes. |
| void SetNonAttributeValue(const String&); |
| void SetNonAttributeValueByUserEdit(const String&); |
| void UpdateView(); |
| bool NeedsToUpdateViewValue() const { return needs_to_update_view_value_; } |
| void SetInnerEditorValue(const String&) override; |
| |
| // For test purposes. |
| void SelectColorInColorChooser(const Color&); |
| void EndColorChooserForTesting(); |
| |
| String DefaultToolTip() const override; |
| |
| // Type=file only: Text not in the button such as "No file chosen". The string |
| // is not truncated by ellipsis. |
| // Return a null string for other types. |
| String FileStatusText() const; |
| // Returns true if an ellipsis should be injected at the middle of the text. |
| // This function is called only if text-overflow:ellipsis is specified. |
| bool ShouldApplyMiddleEllipsis() const; |
| |
| unsigned height() const; |
| unsigned width() const; |
| void setHeight(unsigned); |
| void setWidth(unsigned); |
| |
| void blur() final; |
| void DefaultBlur(); |
| |
| const AtomicString& GetName() const final; |
| |
| void EndEditing(); |
| |
| static Vector<String> FilesFromFileInputFormControlState( |
| const FormControlState&); |
| |
| bool MatchesReadOnlyPseudoClass() const final; |
| bool MatchesReadWritePseudoClass() const final; |
| void setRangeText(const String& replacement, ExceptionState&) final; |
| void setRangeText(const String& replacement, |
| unsigned start, |
| unsigned end, |
| const String& selection_mode, |
| ExceptionState&) final; |
| |
| HTMLImageLoader* ImageLoader() const { return image_loader_.Get(); } |
| HTMLImageLoader& EnsureImageLoader(); |
| |
| bool SetupDateTimeChooserParameters(DateTimeChooserParameters&); |
| |
| bool SupportsInputModeAttribute() const; |
| |
| void CapsLockStateMayHaveChanged(); |
| bool ShouldDrawCapsLockIndicator() const; |
| void SetShouldRevealPassword(bool value); |
| bool ShouldRevealPassword() const { return should_reveal_password_; } |
| AXObject* PopupRootAXObject(); |
| void DidNotifySubtreeInsertionsToDocument() override; |
| |
| virtual void EnsureFallbackContent(); |
| virtual void EnsurePrimaryContent(); |
| bool HasFallbackContent() const; |
| |
| bool IsPlaceholderVisible() const override { return is_placeholder_visible_; } |
| void SetPlaceholderVisibility(bool) override; |
| |
| unsigned SizeOfRadioGroup() const; |
| |
| bool SupportsPlaceholder() const final; |
| String GetPlaceholderValue() const final; |
| |
| void ChildrenChanged(const ChildrenChange&) override; |
| |
| LayoutBox* GetLayoutBoxForScrolling() const final; |
| |
| void SetHasBeenPasswordField() { has_been_password_field_ = true; } |
| |
| bool IsDraggedSlider() const; |
| |
| FormElementPiiType GetFormElementPiiType() const override { |
| return form_element_pii_type_; |
| } |
| |
| void SetFormElementPiiType( |
| FormElementPiiType form_element_pii_type) override { |
| form_element_pii_type_ = form_element_pii_type; |
| } |
| |
| protected: |
| void DefaultEventHandler(Event&) override; |
| void CreateShadowSubtree(); |
| |
| private: |
| enum AutoCompleteSetting { kUninitialized, kOn, kOff }; |
| |
| void WillChangeForm() final; |
| void DidChangeForm() final; |
| InsertionNotificationRequest InsertedInto(ContainerNode&) override; |
| void RemovedFrom(ContainerNode&) final; |
| void DidMoveToNewDocument(Document& old_document) final; |
| bool HasActivationBehavior() const override; |
| |
| bool HasCustomFocusLogic() const final; |
| bool IsKeyboardFocusable() const final; |
| bool MayTriggerVirtualKeyboard() const final; |
| bool ShouldHaveFocusAppearance() const final; |
| bool IsEnumeratable() const final; |
| bool IsInteractiveContent() const final; |
| bool IsLabelable() const final; |
| bool MatchesDefaultPseudoClass() const override; |
| bool IsTextControl() const final { return IsTextField(); } |
| int scrollWidth() override; |
| int scrollHeight() override; |
| |
| bool CanTriggerImplicitSubmission() const final { return IsTextField(); } |
| |
| const AtomicString& FormControlType() const final; |
| |
| bool ShouldSaveAndRestoreFormControlState() const final; |
| FormControlState SaveFormControlState() const final; |
| void RestoreFormControlState(const FormControlState&) final; |
| |
| bool CanStartSelection() const final; |
| |
| void AccessKeyAction(SimulatedClickCreationScope creation_scope) final; |
| |
| void ParseAttribute(const AttributeModificationParams&) override; |
| bool IsPresentationAttribute(const QualifiedName&) const final; |
| void CollectStyleForPresentationAttribute(const QualifiedName&, |
| const AtomicString&, |
| MutableCSSPropertyValueSet*) final; |
| void FinishParsingChildren() final; |
| void ParserDidSetAttributes() final; |
| |
| void CloneNonAttributePropertiesFrom(const Element&, CloneChildrenFlag) final; |
| |
| bool TypeShouldForceLegacyLayout() const final; |
| void AttachLayoutTree(AttachContext&) final; |
| |
| void AppendToFormData(FormData&) final; |
| String ResultForDialogSubmit() final; |
| |
| bool CanBeSuccessfulSubmitButton() const final; |
| |
| void ResetImpl() final; |
| |
| EventDispatchHandlingState* PreDispatchEventHandler(Event&) final; |
| void PostDispatchEventHandler(Event&, EventDispatchHandlingState*) final; |
| |
| bool IsURLAttribute(const Attribute&) const final; |
| bool HasLegalLinkAttribute(const QualifiedName&) const final; |
| const QualifiedName& SubResourceAttributeName() const final; |
| bool IsInRange() const final; |
| bool IsOutOfRange() const final; |
| |
| bool TooLong(const String&, NeedsToCheckDirtyFlag) const; |
| bool TooShort(const String&, NeedsToCheckDirtyFlag) const; |
| |
| void UpdatePlaceholderText() final; |
| bool IsEmptyValue() const final { return InnerEditorValue().IsEmpty(); } |
| void HandleBlurEvent() final; |
| void DispatchFocusInEvent(const AtomicString& event_type, |
| Element* old_focused_element, |
| mojom::blink::FocusType, |
| InputDeviceCapabilities* source_capabilities) final; |
| |
| bool IsOptionalFormControl() const final { return !IsRequiredFormControl(); } |
| bool IsRequiredFormControl() const final; |
| bool RecalcWillValidate() const final; |
| void RequiredAttributeChanged() final; |
| void DisabledAttributeChanged() final; |
| |
| void InitializeTypeInParsing(); |
| void UpdateType(); |
| |
| void SubtreeHasChanged() final; |
| |
| void SetListAttributeTargetObserver(ListAttributeTargetObserver*); |
| void ResetListAttributeTargetObserver(); |
| |
| void AddToRadioButtonGroup(); |
| void RemoveFromRadioButtonGroup(); |
| scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( |
| const StyleRecalcContext&) override; |
| void DidRecalcStyle(const StyleRecalcChange) override; |
| |
| void MaybeReportPiiMetrics(); |
| |
| AtomicString name_; |
| // The value string in |value| value mode. |
| String non_attribute_value_; |
| unsigned size_; |
| // https://html.spec.whatwg.org/C/#concept-input-value-dirty-flag |
| unsigned has_dirty_value_ : 1; |
| // https://html.spec.whatwg.org/C/#concept-fe-checked |
| unsigned is_checked_ : 1; |
| // https://html.spec.whatwg.org/C/#concept-input-checked-dirty-flag |
| unsigned dirty_checkedness_ : 1; |
| unsigned is_indeterminate_ : 1; |
| unsigned is_activated_submit_ : 1; |
| unsigned autocomplete_ : 2; // AutoCompleteSetting |
| unsigned has_non_empty_list_ : 1; |
| unsigned state_restored_ : 1; |
| unsigned parsing_in_progress_ : 1; |
| unsigned can_receive_dropped_files_ : 1; |
| unsigned should_reveal_password_ : 1; |
| unsigned needs_to_update_view_value_ : 1; |
| unsigned is_placeholder_visible_ : 1; |
| unsigned has_been_password_field_ : 1; |
| Member<InputType> input_type_; |
| Member<InputTypeView> input_type_view_; |
| // The ImageLoader must be owned by this element because the loader code |
| // assumes that it lives as long as its owning element lives. If we move the |
| // loader into the ImageInput object we may delete the loader while this |
| // element lives on. |
| Member<HTMLImageLoader> image_loader_; |
| Member<ListAttributeTargetObserver> list_attribute_target_observer_; |
| |
| FormElementPiiType form_element_pii_type_ = FormElementPiiType::kUnknown; |
| |
| FRIEND_TEST_ALL_PREFIXES(HTMLInputElementTest, RadioKeyDownDCHECKFailure); |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_INPUT_ELEMENT_H_ |