[BlackBerry] Optimize spellchecking by coalescing messages
[WebKit-https.git] / Source / WebKit / blackberry / WebKitSupport / InputHandler.h
1 /*
2  * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #ifndef InputHandler_h
20 #define InputHandler_h
21
22 #include "FloatPoint.h"
23 #include "TextChecking.h"
24
25 #include <BlackBerryPlatformInputEvents.h>
26 #include <BlackBerryPlatformMisc.h>
27 #include <BlackBerryPlatformSettings.h>
28
29 #include <imf/events.h>
30 #include <imf/input_data.h>
31 #include <map>
32 #include <pthread.h>
33 #include <wtf/RefPtr.h>
34
35 namespace WTF {
36 class String;
37 }
38
39 namespace WebCore {
40 class AttributeTextStyle;
41 class Element;
42 class Frame;
43 class HTMLInputElement;
44 class HTMLSelectElement;
45 class IntRect;
46 class Node;
47 class Range;
48 class SpellChecker;
49 class SpellCheckRequest;
50 class TextCheckingRequest;
51 class VisiblePosition;
52 class VisibleSelection;
53 }
54
55 namespace BlackBerry {
56
57 namespace Platform {
58 class IntPoint;
59 class KeyboardEvent;
60 }
61
62 namespace WebKit {
63
64 class SpellingHandler;
65 class WebPagePrivate;
66
67 class InputHandler {
68 public:
69     InputHandler(WebPagePrivate*);
70     ~InputHandler();
71
72     enum FocusElementType { TextEdit, TextPopup /* Date/Time & Color */, SelectPopup, Plugin };
73     enum CaretScrollType { CenterAlways = BlackBerry::Platform::Settings::ScrollAdjustmentCenterAlways,
74                            CenterIfNeeded = BlackBerry::Platform::Settings::ScrollAdjustmentCenterIfNeeded,
75                            EdgeIfNeeded = BlackBerry::Platform::Settings::ScrollAdjustmentEdgeIfNeeded };
76
77     bool isInputModeEnabled() const;
78     void setInputModeEnabled(bool active = true);
79
80     void focusedNodeChanged();
81     void nodeTextChanged(const WebCore::Node*);
82     void selectionChanged();
83     void frameUnloaded(const WebCore::Frame*);
84
85     bool handleKeyboardInput(const BlackBerry::Platform::KeyboardEvent&, bool changeIsPartOfComposition = false);
86
87     bool deleteSelection();
88     void insertText(const WTF::String&);
89     void clearField();
90
91     void cut();
92     void copy();
93     void paste();
94     void selectAll();
95
96     void cancelSelection();
97
98     void setInputValue(const WTF::String&);
99
100     void setDelayKeyboardVisibilityChange(bool value);
101     void processPendingKeyboardVisibilityChange();
102
103     void notifyClientOfKeyboardVisibilityChange(bool visible, bool triggeredByFocusChange = false);
104
105     bool isInputMode() const { return isActiveTextEdit(); }
106     bool isMultilineInputMode() const { return isActiveTextEdit() && elementType(m_currentFocusElement.get()) == BlackBerry::Platform::InputTypeTextArea; }
107     PassRefPtr<WebCore::Element> currentFocusElement() const { return m_currentFocusElement; }
108
109     void ensureFocusElementVisible(bool centerFieldInDisplay = true);
110
111     // PopupMenu methods.
112     bool willOpenPopupForNode(WebCore::Node*);
113     bool didNodeOpenPopup(WebCore::Node*);
114     bool openLineInputPopup(WebCore::HTMLInputElement*);
115     bool openSelectPopup(WebCore::HTMLSelectElement*);
116     void setPopupListIndex(int);
117     void setPopupListIndexes(int size, const bool* selecteds);
118
119     bool processingChange() const { return m_processingChange; }
120     void setProcessingChange(bool);
121
122     WTF::String elementText();
123
124     WebCore::IntRect boundingBoxForInputField();
125
126     bool isCaretAtEndOfText();
127
128     // IMF driven calls.
129     bool setBatchEditingActive(bool);
130     bool setSelection(int start, int end, bool changeIsPartOfComposition = false);
131     int caretPosition() const;
132     bool deleteTextRelativeToCursor(int leftOffset, int rightOffset);
133
134     spannable_string_t* selectedText(int32_t flags);
135     spannable_string_t* textBeforeCursor(int32_t length, int32_t flags);
136     spannable_string_t* textAfterCursor(int32_t length, int32_t flags);
137     extracted_text_t* extractedTextRequest(extracted_text_request_t*, int32_t flags);
138
139     int32_t setComposingRegion(int32_t start, int32_t end);
140     int32_t finishComposition();
141     int32_t setComposingText(spannable_string_t*, int32_t relativeCursorPosition);
142     int32_t commitText(spannable_string_t*, int32_t relativeCursorPosition);
143
144     void requestCheckingOfString(PassRefPtr<WebCore::TextCheckingRequest>);
145     void spellCheckingRequestProcessed(int32_t transactionId, spannable_string_t*);
146     void spellCheckingRequestCancelled(int32_t transactionId);
147
148     bool shouldRequestSpellCheckingOptionsForPoint(const Platform::IntPoint& documentContentPosition, const WebCore::Element*, imf_sp_text_t&);
149     void requestSpellingCheckingOptions(imf_sp_text_t&, WebCore::IntSize& screenOffset, const bool shouldMoveDialog = false);
150     void clearDidSpellCheckState() { m_didSpellCheckWord = false; }
151     void redrawSpellCheckDialogIfRequired(const bool shouldMoveDialog = true);
152
153     void callRequestCheckingFor(PassRefPtr<WebCore::SpellCheckRequest>);
154
155 private:
156     enum PendingKeyboardStateChange { NoChange, Visible, NotVisible };
157
158     void setElementFocused(WebCore::Element*);
159     void setPluginFocused(WebCore::Element*);
160     void setElementUnfocused(bool refocusOccuring = false);
161
162     void ensureFocusTextElementVisible(CaretScrollType = CenterAlways);
163     void ensureFocusPluginElementVisible();
164
165     void clearCurrentFocusElement();
166
167     bool selectionAtStartOfElement();
168     bool selectionAtEndOfElement();
169
170     WebCore::IntRect rectForCaret(int index);
171
172     bool isActiveTextEdit() const { return m_currentFocusElement && m_currentFocusElementType == TextEdit; }
173     bool isActiveTextPopup() const { return m_currentFocusElement && m_currentFocusElementType == TextPopup; }
174     bool isActiveSelectPopup() const { return m_currentFocusElement && m_currentFocusElementType == SelectPopup; }
175     bool isActivePlugin() const { return m_currentFocusElement && m_currentFocusElementType == Plugin; }
176
177     bool openDatePopup(WebCore::HTMLInputElement*, BlackBerry::Platform::BlackBerryInputType);
178     bool openColorPopup(WebCore::HTMLInputElement*);
179
180     bool executeTextEditCommand(const WTF::String&);
181
182     BlackBerry::Platform::BlackBerryInputType elementType(WebCore::Element*) const;
183
184     int selectionStart() const;
185     int selectionEnd() const;
186     int selectionPosition(bool start) const;
187     bool selectionActive() const { return selectionStart() != selectionEnd(); }
188
189     bool compositionActive() const { return compositionLength(); }
190     unsigned compositionLength() const { return m_composingTextEnd - m_composingTextStart; }
191
192     spannable_string_t* spannableTextInRange(int start, int end, int32_t flags);
193
194     void addAttributedTextMarker(int start, int end, const WebCore::AttributeTextStyle&);
195     void removeAttributedTextMarker();
196
197     bool deleteText(int start, int end);
198     bool setTextAttributes(int insertionPoint, spannable_string_t*);
199     bool setText(spannable_string_t*);
200     bool setSpannableTextAndRelativeCursor(spannable_string_t*, int relativeCursorPosition, bool markTextAsComposing);
201     bool removeComposedText();
202     bool setRelativeCursorPosition(int insertionPoint, int relativeCursorPosition);
203     bool setCursorPosition(int location);
204
205     span_t* firstSpanInString(spannable_string_t*, SpannableStringAttribute);
206     bool isTrailingSingleCharacter(span_t*, unsigned, unsigned);
207
208     void learnText();
209     void sendLearnTextDetails(const WTF::String&);
210     WebCore::SpellChecker* getSpellChecker();
211     bool shouldSpellCheckElement(const WebCore::Element*) const;
212     bool didSpellCheckWord() const { return m_didSpellCheckWord; }
213
214     bool shouldNotifyWebView(const Platform::KeyboardEvent&);
215
216     WebPagePrivate* m_webPage;
217
218     RefPtr<WebCore::Element> m_currentFocusElement;
219     bool m_inputModeEnabled;
220
221     bool m_processingChange;
222     bool m_shouldEnsureFocusTextElementVisibleOnSelectionChanged;
223
224     FocusElementType m_currentFocusElementType;
225     int64_t m_currentFocusElementTextEditMask;
226
227     int m_composingTextStart;
228     int m_composingTextEnd;
229
230     PendingKeyboardStateChange m_pendingKeyboardVisibilityChange;
231     bool m_delayKeyboardVisibilityChange;
232
233     RefPtr<WebCore::TextCheckingRequest> m_request;
234     int32_t m_processingTransactionId;
235
236     bool m_shouldNotifyWebView;
237     unsigned short m_expectedKeyUpChar;
238
239     imf_sp_text_t m_spellCheckingOptionsRequest;
240     WebCore::IntSize m_screenOffset;
241     bool m_didSpellCheckWord;
242     SpellingHandler* m_spellingHandler;
243
244     DISABLE_COPY(InputHandler);
245 };
246
247 }
248 }
249
250 #endif // InputHandler_h