1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "TextInputController.h"
33
34 #include "TestShell.h"
35 #include "WebBindings.h"
36 #include "WebCompositionUnderline.h"
37 #include "WebFrame.h"
38 #include "WebRange.h"
39 #include "WebString.h"
40 #include "WebVector.h"
41 #include "WebView.h"
42 #include <wtf/StringExtras.h>
43 #include <string>
44
45 using namespace WebKit;
46
47 TestShell* TextInputController::testShell = 0;
48
TextInputController(TestShell * shell)49 TextInputController::TextInputController(TestShell* shell)
50 {
51 // Set static testShell variable. Be careful not to assign testShell to new
52 // windows which are temporary.
53 if (!testShell)
54 testShell = shell;
55
56 bindMethod("attributedSubstringFromRange", &TextInputController::attributedSubstringFromRange);
57 bindMethod("characterIndexForPoint", &TextInputController::characterIndexForPoint);
58 bindMethod("conversationIdentifier", &TextInputController::conversationIdentifier);
59 bindMethod("doCommand", &TextInputController::doCommand);
60 bindMethod("firstRectForCharacterRange", &TextInputController::firstRectForCharacterRange);
61 bindMethod("hasMarkedText", &TextInputController::hasMarkedText);
62 bindMethod("insertText", &TextInputController::insertText);
63 bindMethod("makeAttributedString", &TextInputController::makeAttributedString);
64 bindMethod("markedRange", &TextInputController::markedRange);
65 bindMethod("selectedRange", &TextInputController::selectedRange);
66 bindMethod("setMarkedText", &TextInputController::setMarkedText);
67 bindMethod("substringFromRange", &TextInputController::substringFromRange);
68 bindMethod("unmarkText", &TextInputController::unmarkText);
69 bindMethod("validAttributesForMarkedText", &TextInputController::validAttributesForMarkedText);
70 bindMethod("setComposition", &TextInputController::setComposition);
71 }
72
getMainFrame()73 WebFrame* TextInputController::getMainFrame()
74 {
75 return testShell->webView()->mainFrame();
76 }
77
insertText(const CppArgumentList & arguments,CppVariant * result)78 void TextInputController::insertText(const CppArgumentList& arguments, CppVariant* result)
79 {
80 result->setNull();
81
82 if (arguments.size() < 1 || !arguments[0].isString())
83 return;
84
85 testShell->webView()->confirmComposition(WebString::fromUTF8(arguments[0].toString()));
86 }
87
doCommand(const CppArgumentList & arguments,CppVariant * result)88 void TextInputController::doCommand(const CppArgumentList& arguments, CppVariant* result)
89 {
90 result->setNull();
91
92 WebFrame* mainFrame = getMainFrame();
93 if (!mainFrame)
94 return;
95
96 if (arguments.size() >= 1 && arguments[0].isString())
97 mainFrame->executeCommand(WebString::fromUTF8(arguments[0].toString()));
98 }
99
setMarkedText(const CppArgumentList & arguments,CppVariant * result)100 void TextInputController::setMarkedText(const CppArgumentList& arguments, CppVariant* result)
101 {
102 result->setNull();
103
104 if (arguments.size() >= 3 && arguments[0].isString()
105 && arguments[1].isNumber() && arguments[2].isNumber()) {
106 WebVector<WebCompositionUnderline> underlines;
107 testShell->webView()->setComposition(WebString::fromUTF8(arguments[0].toString()),
108 underlines,
109 arguments[1].toInt32(),
110 arguments[1].toInt32() + arguments[2].toInt32());
111 }
112 }
113
unmarkText(const CppArgumentList &,CppVariant * result)114 void TextInputController::unmarkText(const CppArgumentList&, CppVariant* result)
115 {
116 result->setNull();
117
118 testShell->webView()->confirmComposition();
119 }
120
hasMarkedText(const CppArgumentList &,CppVariant * result)121 void TextInputController::hasMarkedText(const CppArgumentList&, CppVariant* result)
122 {
123 result->setNull();
124
125 WebFrame* mainFrame = getMainFrame();
126 if (!mainFrame)
127 return;
128
129 result->set(mainFrame->hasMarkedText());
130 }
131
conversationIdentifier(const CppArgumentList &,CppVariant * result)132 void TextInputController::conversationIdentifier(const CppArgumentList&, CppVariant* result)
133 {
134 // FIXME: Implement this.
135 result->setNull();
136 }
137
substringFromRange(const CppArgumentList &,CppVariant * result)138 void TextInputController::substringFromRange(const CppArgumentList&, CppVariant* result)
139 {
140 // FIXME: Implement this.
141 result->setNull();
142 }
143
attributedSubstringFromRange(const CppArgumentList &,CppVariant * result)144 void TextInputController::attributedSubstringFromRange(const CppArgumentList&, CppVariant* result)
145 {
146 // FIXME: Implement this.
147 result->setNull();
148 }
149
markedRange(const CppArgumentList &,CppVariant * result)150 void TextInputController::markedRange(const CppArgumentList&, CppVariant* result)
151 {
152 result->setNull();
153
154 WebFrame* mainFrame = getMainFrame();
155 if (!mainFrame)
156 return;
157
158 WebRange range = mainFrame->markedRange();
159 Vector<int> intArray(2);
160 intArray[0] = range.startOffset();
161 intArray[1] = range.endOffset();
162 result->set(WebBindings::makeIntArray(intArray));
163 }
164
selectedRange(const CppArgumentList &,CppVariant * result)165 void TextInputController::selectedRange(const CppArgumentList&, CppVariant* result)
166 {
167 result->setNull();
168
169 WebFrame* mainFrame = getMainFrame();
170 if (!mainFrame)
171 return;
172
173 WebRange range = mainFrame->selectionRange();
174 Vector<int> intArray(2);
175 intArray[0] = range.startOffset();
176 intArray[1] = range.endOffset();
177 result->set(WebBindings::makeIntArray(intArray));
178 }
179
firstRectForCharacterRange(const CppArgumentList & arguments,CppVariant * result)180 void TextInputController::firstRectForCharacterRange(const CppArgumentList& arguments, CppVariant* result)
181 {
182 result->setNull();
183
184 WebFrame* mainFrame = getMainFrame();
185 if (!mainFrame)
186 return;
187
188 if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
189 return;
190
191 WebRect rect;
192 if (!mainFrame->firstRectForCharacterRange(arguments[0].toInt32(), arguments[1].toInt32(), rect))
193 return;
194
195 Vector<int> intArray(4);
196 intArray[0] = rect.x;
197 intArray[1] = rect.y;
198 intArray[2] = rect.width;
199 intArray[3] = rect.height;
200 result->set(WebBindings::makeIntArray(intArray));
201 }
202
characterIndexForPoint(const CppArgumentList &,CppVariant * result)203 void TextInputController::characterIndexForPoint(const CppArgumentList&, CppVariant* result)
204 {
205 // FIXME: Implement this.
206 result->setNull();
207 }
208
validAttributesForMarkedText(const CppArgumentList &,CppVariant * result)209 void TextInputController::validAttributesForMarkedText(const CppArgumentList&, CppVariant* result)
210 {
211 result->setNull();
212
213 WebFrame* mainFrame = getMainFrame();
214 if (!mainFrame)
215 return;
216
217 result->set("NSUnderline,NSUnderlineColor,NSMarkedClauseSegment,"
218 "NSTextInputReplacementRangeAttributeName");
219 }
220
makeAttributedString(const CppArgumentList &,CppVariant * result)221 void TextInputController::makeAttributedString(const CppArgumentList&, CppVariant* result)
222 {
223 // FIXME: Implement this.
224 result->setNull();
225 }
226
setComposition(const CppArgumentList & arguments,CppVariant * result)227 void TextInputController::setComposition(const CppArgumentList& arguments, CppVariant* result)
228 {
229 result->setNull();
230
231 WebView* view = getMainFrame() ? getMainFrame()->view() : 0;
232 if (!view)
233 return;
234
235 if (arguments.size() < 1)
236 return;
237
238 // Sends a keydown event with key code = 0xE5 to emulate input method behavior.
239 WebKeyboardEvent keyDown;
240 keyDown.type = WebInputEvent::RawKeyDown;
241 keyDown.modifiers = 0;
242 keyDown.windowsKeyCode = 0xE5; // VKEY_PROCESSKEY
243 keyDown.setKeyIdentifierFromWindowsKeyCode();
244 view->handleInputEvent(keyDown);
245
246 WebVector<WebCompositionUnderline> underlines;
247 WebString text(WebString::fromUTF8(arguments[0].toString()));
248 view->setComposition(text, underlines, 0, text.length());
249 }
250