DOM event handling should pass Event around by reference.
[WebKit-https.git] / Source / WebCore / html / HTMLTextFormControlElement.h
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2000 Dirk Mueller (mueller@kde.org)
5  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
6  * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24
25 #ifndef HTMLTextFormControlElement_h
26 #define HTMLTextFormControlElement_h
27
28 #include "HTMLFormControlElementWithState.h"
29
30 namespace WebCore {
31
32 class Position;
33 class RenderTextControl;
34 class TextControlInnerTextElement;
35 class VisiblePosition;
36
37 enum class AutoFillButtonType : uint8_t { None, Credentials, Contacts };
38 enum TextFieldSelectionDirection { SelectionHasNoDirection, SelectionHasForwardDirection, SelectionHasBackwardDirection };
39 enum TextFieldEventBehavior { DispatchNoEvent, DispatchChangeEvent, DispatchInputAndChangeEvent };
40
41 class HTMLTextFormControlElement : public HTMLFormControlElementWithState {
42 public:
43     // Common flag for HTMLInputElement::tooLong() and HTMLTextAreaElement::tooLong().
44     enum NeedsToCheckDirtyFlag {CheckDirtyFlag, IgnoreDirtyFlag};
45
46     virtual ~HTMLTextFormControlElement();
47
48     void didEditInnerTextValue();
49     void forwardEvent(Event&);
50
51     WEBCORE_EXPORT void setMaxLengthForBindings(int, ExceptionCode&);
52
53     InsertionNotificationRequest insertedInto(ContainerNode&) override;
54
55     // The derived class should return true if placeholder processing is needed.
56     bool isPlaceholderVisible() const { return m_isPlaceholderVisible; }
57     virtual bool supportsPlaceholder() const = 0;
58     String strippedPlaceholder() const;
59     virtual HTMLElement* placeholderElement() const = 0;
60     void updatePlaceholderVisibility();
61
62     int indexForVisiblePosition(const VisiblePosition&) const;
63     WEBCORE_EXPORT VisiblePosition visiblePositionForIndex(int index) const;
64     WEBCORE_EXPORT int selectionStart() const;
65     WEBCORE_EXPORT int selectionEnd() const;
66     WEBCORE_EXPORT const AtomicString& selectionDirection() const;
67     WEBCORE_EXPORT void setSelectionStart(int);
68     WEBCORE_EXPORT void setSelectionEnd(int);
69     WEBCORE_EXPORT void setSelectionDirection(const String&);
70     WEBCORE_EXPORT void select(const AXTextStateChangeIntent& = AXTextStateChangeIntent());
71     WEBCORE_EXPORT virtual void setRangeText(const String& replacement, ExceptionCode&);
72     WEBCORE_EXPORT virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionCode&);
73     void setSelectionRange(int start, int end, const String& direction, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
74     WEBCORE_EXPORT void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
75     PassRefPtr<Range> selection() const;
76     String selectedText() const;
77
78     void dispatchFormControlChangeEvent() final;
79
80     virtual String value() const = 0;
81
82     virtual TextControlInnerTextElement* innerTextElement() const = 0;
83     virtual RenderStyle createInnerTextStyle(const RenderStyle&) const = 0;
84
85     void selectionChanged(bool shouldFireSelectEvent);
86     WEBCORE_EXPORT bool lastChangeWasUserEdit() const;
87     void setInnerTextValue(const String&);
88     String innerTextValue() const;
89
90     String directionForFormData() const;
91
92     void setTextAsOfLastFormControlChangeEvent(const String& text) { m_textAsOfLastFormControlChangeEvent = text; }
93 #if PLATFORM(IOS)
94     WEBCORE_EXPORT void hidePlaceholder();
95     WEBCORE_EXPORT void showPlaceholderIfNecessary();
96 #endif
97
98 protected:
99     HTMLTextFormControlElement(const QualifiedName&, Document&, HTMLFormElement*);
100     bool isPlaceholderEmpty() const;
101     virtual void updatePlaceholderText() = 0;
102
103     void parseAttribute(const QualifiedName&, const AtomicString&) override;
104
105     void disabledStateChanged() override;
106     void readOnlyAttributeChanged() override;
107     void updateInnerTextElementEditability();
108
109     void cacheSelection(int start, int end, TextFieldSelectionDirection direction)
110     {
111         m_cachedSelectionStart = start;
112         m_cachedSelectionEnd = end;
113         m_cachedSelectionDirection = direction;
114     }
115
116     void restoreCachedSelection(const AXTextStateChangeIntent& = AXTextStateChangeIntent());
117     bool hasCachedSelection() const { return m_cachedSelectionStart >= 0; }
118
119     virtual void subtreeHasChanged() = 0;
120
121     void setLastChangeWasNotUserEdit() { m_lastChangeWasUserEdit = false; }
122
123     String valueWithHardLineBreaks() const;
124
125     void adjustInnerTextStyle(const RenderStyle& parentStyle, RenderStyle& textBlockStyle) const;
126
127 private:
128     TextFieldSelectionDirection cachedSelectionDirection() const { return static_cast<TextFieldSelectionDirection>(m_cachedSelectionDirection); }
129
130     int computeSelectionStart() const;
131     int computeSelectionEnd() const;
132     TextFieldSelectionDirection computeSelectionDirection() const;
133
134     void dispatchFocusEvent(RefPtr<Element>&& oldFocusedElement, FocusDirection) final;
135     void dispatchBlurEvent(RefPtr<Element>&& newFocusedElement) final;
136     bool childShouldCreateRenderer(const Node&) const override;
137
138     unsigned indexForPosition(const Position&) const;
139
140     // Returns true if user-editable value is empty. Used to check placeholder visibility.
141     virtual bool isEmptyValue() const = 0;
142     // Called in dispatchFocusEvent(), after placeholder process, before calling parent's dispatchFocusEvent().
143     virtual void handleFocusEvent(Node* /* oldFocusedNode */, FocusDirection) { }
144     // Called in dispatchBlurEvent(), after placeholder process, before calling parent's dispatchBlurEvent().
145     virtual void handleBlurEvent() { }
146
147     bool placeholderShouldBeVisible() const;
148
149     String m_textAsOfLastFormControlChangeEvent;
150
151     int m_cachedSelectionStart;
152     int m_cachedSelectionEnd;
153
154     unsigned char m_cachedSelectionDirection : 2;
155     unsigned char m_lastChangeWasUserEdit : 1;
156     unsigned char m_isPlaceholderVisible : 1;
157 };
158
159 HTMLTextFormControlElement* enclosingTextFormControl(const Position&);
160
161 } // namespace WebCore
162
163 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::HTMLTextFormControlElement)
164     static bool isType(const WebCore::Element& element) { return element.isTextFormControl(); }
165     static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
166 SPECIALIZE_TYPE_TRAITS_END()
167
168 #endif