blob: 36f5b325d36004fe278454d452d7d390f27944b4 [file] [log] [blame]
/*
* 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 HTMLInputElement_h
#define HTMLInputElement_h
#include "base/gtest_prod_util.h"
#include "bindings/core/v8/ActiveScriptWrappable.h"
#include "core/CoreExport.h"
#include "core/html/forms/FileChooser.h"
#include "core/html/forms/StepRange.h"
#include "core/html/forms/TextControlElement.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;
struct DateTimeChooserParameters;
class CORE_EXPORT HTMLInputElement
: public TextControlElement,
public ActiveScriptWrappable<HTMLInputElement> {
DEFINE_WRAPPERTYPEINFO();
USING_GARBAGE_COLLECTED_MIXIN(HTMLInputElement);
public:
static HTMLInputElement* Create(Document&, bool created_by_parser);
~HTMLInputElement() override;
void Trace(blink::Visitor*) override;
bool HasPendingActivity() const final;
DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange);
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() == InputTypeNames::image|, etc.
bool checked() const;
void setChecked(bool, TextFieldEventBehavior = kDispatchNoEvent);
void DispatchChangeEventIfNeeded();
// '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;
int size() const;
bool SizeShouldIncludeDecoration(int& preferred_size) const;
void setType(const AtomicString&);
String value() const override;
void setValue(const String&,
ExceptionState&,
TextFieldEventBehavior = kDispatchNoEvent);
void setValue(const String&,
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&);
double valueAsDate(bool& is_null) const;
void setValueAsDate(double, bool is_null, ExceptionState&);
double valueAsNumber() const;
void setValueAsNumber(double,
ExceptionState&,
TextFieldEventBehavior = kDispatchNoEvent);
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&);
unsigned selectionStartForBinding(bool&, ExceptionState&) const;
unsigned selectionEndForBinding(bool&, ExceptionState&) const;
String selectionDirectionForBinding(ExceptionState&) const;
void setSelectionStartForBinding(unsigned, bool is_null, ExceptionState&);
void setSelectionEndForBinding(unsigned, bool is_null, ExceptionState&);
void setSelectionDirectionForBinding(const String&, ExceptionState&);
void setSelectionRangeForBinding(unsigned start,
unsigned end,
ExceptionState&);
void setSelectionRangeForBinding(unsigned start,
unsigned end,
const String& direction,
ExceptionState&);
bool LayoutObjectIsNeeded(const ComputedStyle&) final;
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
void DetachLayoutTree(const AttachContext& = AttachContext()) 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);
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);
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;
HTMLInputElement* CheckedRadioButtonForGroup();
bool IsInRequiredRadioButtonGroup();
// 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 EndColorChooser();
String DefaultToolTip() const override;
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<FileChooserFileInfo> 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 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;
String GetPlaceholderValue() const final;
protected:
HTMLInputElement(Document&, bool created_by_parser);
void DefaultEventHandler(Event*) override;
private:
enum AutoCompleteSetting { kUninitialized, kOn, kOff };
void DidAddUserAgentShadowRoot(ShadowRoot&) final;
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 ShouldShowFocusRingOnMouseFocus() const final;
bool IsEnumeratable() const final;
bool IsInteractiveContent() const final;
bool SupportLabels() const final;
bool MatchesDefaultPseudoClass() const override;
bool IsTextControl() const final { return IsTextField(); }
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(bool send_mouse_events) 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 CopyNonAttributePropertiesFromElement(const Element&) final;
void AttachLayoutTree(AttachContext&) final;
void AppendToFormData(FormData&) final;
String ResultForDialogSubmit() final;
bool CanBeSuccessfulSubmitButton() const final;
void ResetImpl() final;
bool SupportsAutofocus() const 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;
bool SupportsPlaceholder() const final;
void UpdatePlaceholderText() final;
bool IsEmptyValue() const final { return InnerEditorValue().IsEmpty(); }
void HandleFocusEvent(Element* old_focused_element, WebFocusType) final;
void HandleBlurEvent() final;
void DispatchFocusInEvent(const AtomicString& event_type,
Element* old_focused_element,
WebFocusType,
InputDeviceCapabilities* source_capabilities) final;
bool SupportsAutocapitalize() const final;
const AtomicString& DefaultAutocapitalize() const 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 ParseMaxLengthAttribute(const AtomicString&);
void ParseMinLengthAttribute(const AtomicString&);
// Returns null if this isn't associated with any radio button group.
RadioButtonGroupScope* GetRadioButtonGroupScope() const;
void AddToRadioButtonGroup();
void RemoveFromRadioButtonGroup();
scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override;
AtomicString name_;
// The value string in |value| value mode.
String non_attribute_value_;
int size_;
// https://html.spec.whatwg.org/multipage/forms.html#concept-input-value-dirty-flag
unsigned has_dirty_value_ : 1;
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-checked
unsigned is_checked_ : 1;
// https://html.spec.whatwg.org/multipage/forms.html#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;
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_;
FRIEND_TEST_ALL_PREFIXES(HTMLInputElementTest, RadioKeyDownDCHECKFailure);
};
} // namespace blink
#endif // HTMLInputElement_h