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 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 "core/html/HTMLFormControlElementWithState.h"
29
30namespace blink {
31
32class ExceptionState;
33class Position;
34class Range;
35class RenderTextControl;
36class VisiblePosition;
37
38enum TextFieldSelectionDirection { SelectionHasNoDirection, SelectionHasForwardDirection, SelectionHasBackwardDirection };
39enum TextFieldEventBehavior { DispatchNoEvent, DispatchChangeEvent, DispatchInputAndChangeEvent };
40
41class HTMLTextFormControlElement : public HTMLFormControlElementWithState {
42public:
43    // Common flag for HTMLInputElement::tooLong() and HTMLTextAreaElement::tooLong().
44    enum NeedsToCheckDirtyFlag {CheckDirtyFlag, IgnoreDirtyFlag};
45    // Option of setSelectionRange.
46    enum SelectionOption {
47        ChangeSelection,
48        ChangeSelectionAndFocus,
49        ChangeSelectionIfFocused,
50        NotChangeSelection
51    };
52
53    virtual ~HTMLTextFormControlElement();
54
55    void forwardEvent(Event*);
56
57
58    virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
59
60    // The derived class should return true if placeholder processing is needed.
61    virtual bool supportsPlaceholder() const = 0;
62    String strippedPlaceholder() const;
63    bool placeholderShouldBeVisible() const;
64    HTMLElement* placeholderElement() const;
65    void updatePlaceholderVisibility(bool);
66
67    VisiblePosition visiblePositionForIndex(int) const;
68    int indexForVisiblePosition(const VisiblePosition&) const;
69    int selectionStart() const;
70    int selectionEnd() const;
71    const AtomicString& selectionDirection() const;
72    void setSelectionStart(int);
73    void setSelectionEnd(int);
74    void setSelectionDirection(const String&);
75    void select();
76    virtual void setRangeText(const String& replacement, ExceptionState&);
77    virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState&);
78    void setSelectionRange(int start, int end, const String& direction);
79    void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection, SelectionOption = ChangeSelection);
80    PassRefPtrWillBeRawPtr<Range> selection() const;
81
82    virtual void dispatchFormControlChangeEvent() OVERRIDE FINAL;
83
84    virtual String value() const = 0;
85
86    HTMLElement* innerEditorElement() const;
87
88    void selectionChanged(bool userTriggered);
89    bool lastChangeWasUserEdit() const;
90    virtual void setInnerEditorValue(const String&);
91    String innerEditorValue() const;
92
93    String directionForFormData() const;
94
95    void setTextAsOfLastFormControlChangeEvent(const String& text) { m_textAsOfLastFormControlChangeEvent = text; }
96
97    // These functions don't cause synchronous layout and SpellChecker uses
98    // them to improve performance.
99    // Passed |Position| must point inside of a text form control.
100    static Position startOfWord(const Position&);
101    static Position endOfWord(const Position&);
102    static Position startOfSentence(const Position&);
103    static Position endOfSentence(const Position&);
104
105protected:
106    HTMLTextFormControlElement(const QualifiedName&, Document&, HTMLFormElement*);
107    bool isPlaceholderEmpty() const;
108    virtual void updatePlaceholderText() = 0;
109
110    virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
111
112    void cacheSelection(int start, int end, TextFieldSelectionDirection direction)
113    {
114        ASSERT(start >= 0);
115        m_cachedSelectionStart = start;
116        m_cachedSelectionEnd = end;
117        m_cachedSelectionDirection = direction;
118    }
119
120    void restoreCachedSelection();
121
122    virtual void defaultEventHandler(Event*) OVERRIDE;
123    virtual void subtreeHasChanged() = 0;
124
125    void setLastChangeWasNotUserEdit() { m_lastChangeWasUserEdit = false; }
126
127    String valueWithHardLineBreaks() const;
128
129    virtual bool shouldDispatchFormControlChangeEvent(String&, String&);
130
131private:
132    int computeSelectionStart() const;
133    int computeSelectionEnd() const;
134    TextFieldSelectionDirection computeSelectionDirection() const;
135
136    virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE FINAL;
137    virtual void dispatchBlurEvent(Element* newFocusedElement) OVERRIDE FINAL;
138
139    // Returns true if user-editable value is empty. Used to check placeholder visibility.
140    virtual bool isEmptyValue() const = 0;
141    // Returns true if suggested value is empty. Used to check placeholder visibility.
142    virtual bool isEmptySuggestedValue() const { return true; }
143    // Called in dispatchFocusEvent(), after placeholder process, before calling parent's dispatchFocusEvent().
144    virtual void handleFocusEvent(Element* /* oldFocusedNode */, FocusType) { }
145    // Called in dispatchBlurEvent(), after placeholder process, before calling parent's dispatchBlurEvent().
146    virtual void handleBlurEvent() { }
147
148    String m_textAsOfLastFormControlChangeEvent;
149    bool m_lastChangeWasUserEdit;
150
151    int m_cachedSelectionStart;
152    int m_cachedSelectionEnd;
153    TextFieldSelectionDirection m_cachedSelectionDirection;
154};
155
156inline bool isHTMLTextFormControlElement(const Element& element)
157{
158    return element.isTextFormControl();
159}
160
161DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTextFormControlElement);
162
163HTMLTextFormControlElement* enclosingTextFormControl(const Position&);
164HTMLTextFormControlElement* enclosingTextFormControl(Node*);
165
166} // namespace
167
168#endif
169