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 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 73 WebFrame* TextInputController::getMainFrame() 74 { 75 return testShell->webView()->mainFrame(); 76 } 77 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 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 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 114 void TextInputController::unmarkText(const CppArgumentList&, CppVariant* result) 115 { 116 result->setNull(); 117 118 testShell->webView()->confirmComposition(); 119 } 120 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 132 void TextInputController::conversationIdentifier(const CppArgumentList&, CppVariant* result) 133 { 134 // FIXME: Implement this. 135 result->setNull(); 136 } 137 138 void TextInputController::substringFromRange(const CppArgumentList&, CppVariant* result) 139 { 140 // FIXME: Implement this. 141 result->setNull(); 142 } 143 144 void TextInputController::attributedSubstringFromRange(const CppArgumentList&, CppVariant* result) 145 { 146 // FIXME: Implement this. 147 result->setNull(); 148 } 149 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 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 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 203 void TextInputController::characterIndexForPoint(const CppArgumentList&, CppVariant* result) 204 { 205 // FIXME: Implement this. 206 result->setNull(); 207 } 208 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 221 void TextInputController::makeAttributedString(const CppArgumentList&, CppVariant* result) 222 { 223 // FIXME: Implement this. 224 result->setNull(); 225 } 226 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