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