Home | History | Annotate | Download | only in runner
      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 "TextInputController.h"
     32 
     33 #include "TestCommon.h"
     34 #include "public/platform/WebString.h"
     35 #include "public/platform/WebVector.h"
     36 #include "public/web/WebBindings.h"
     37 #include "public/web/WebCompositionUnderline.h"
     38 #include "public/web/WebFrame.h"
     39 #include "public/web/WebInputEvent.h"
     40 #include "public/web/WebRange.h"
     41 #include "public/web/WebView.h"
     42 #include <string>
     43 
     44 using namespace blink;
     45 using namespace std;
     46 
     47 namespace WebTestRunner {
     48 
     49 TextInputController::TextInputController()
     50 {
     51     bindMethod("doCommand", &TextInputController::doCommand);
     52     bindMethod("firstRectForCharacterRange", &TextInputController::firstRectForCharacterRange);
     53     bindMethod("hasMarkedText", &TextInputController::hasMarkedText);
     54     bindMethod("insertText", &TextInputController::insertText);
     55     bindMethod("markedRange", &TextInputController::markedRange);
     56     bindMethod("selectedRange", &TextInputController::selectedRange);
     57     bindMethod("setMarkedText", &TextInputController::setMarkedText);
     58     bindMethod("unmarkText", &TextInputController::unmarkText);
     59     bindMethod("setComposition", &TextInputController::setComposition);
     60 }
     61 
     62 void TextInputController::insertText(const CppArgumentList& arguments, CppVariant* result)
     63 {
     64     result->setNull();
     65 
     66     if (arguments.size() < 1 || !arguments[0].isString())
     67         return;
     68 
     69     m_webView->confirmComposition(WebString::fromUTF8(arguments[0].toString()));
     70 }
     71 
     72 void TextInputController::doCommand(const CppArgumentList& arguments, CppVariant* result)
     73 {
     74     result->setNull();
     75 
     76     WebFrame* mainFrame = m_webView->mainFrame();
     77     if (!mainFrame)
     78         return;
     79 
     80     if (arguments.size() >= 1 && arguments[0].isString())
     81         mainFrame->executeCommand(WebString::fromUTF8(arguments[0].toString()));
     82 }
     83 
     84 void TextInputController::setMarkedText(const CppArgumentList& arguments, CppVariant* result)
     85 {
     86     result->setNull();
     87 
     88     if (arguments.size() < 3 || !arguments[0].isString()
     89         || !arguments[1].isNumber() || !arguments[2].isNumber())
     90         return;
     91 
     92     WebString text(WebString::fromUTF8(arguments[0].toString()));
     93     int start = arguments[1].toInt32();
     94     int length = arguments[2].toInt32();
     95 
     96     // Split underline into up to 3 elements (before, selection, and after).
     97     vector<WebCompositionUnderline> underlines;
     98     WebCompositionUnderline underline;
     99     if (!start) {
    100         underline.endOffset = length;
    101     } else {
    102         underline.endOffset = start;
    103         underlines.push_back(underline);
    104         underline.startOffset = start;
    105         underline.endOffset = start + length;
    106     }
    107     underline.thick = true;
    108     underlines.push_back(underline);
    109     if (start + length < static_cast<int>(text.length())) {
    110         underline.startOffset = underline.endOffset;
    111         underline.endOffset = text.length();
    112         underline.thick = false;
    113         underlines.push_back(underline);
    114     }
    115 
    116     m_webView->setComposition(text, underlines, start, start + length);
    117 }
    118 
    119 void TextInputController::unmarkText(const CppArgumentList&, CppVariant* result)
    120 {
    121     result->setNull();
    122 
    123     m_webView->confirmComposition();
    124 }
    125 
    126 void TextInputController::hasMarkedText(const CppArgumentList&, CppVariant* result)
    127 {
    128     result->setNull();
    129 
    130     WebFrame* mainFrame = m_webView->mainFrame();
    131     if (!mainFrame)
    132         return;
    133 
    134     result->set(mainFrame->hasMarkedText());
    135 }
    136 
    137 void TextInputController::markedRange(const CppArgumentList&, CppVariant* result)
    138 {
    139     result->setNull();
    140 
    141     WebFrame* mainFrame = m_webView->mainFrame();
    142     if (!mainFrame)
    143         return;
    144 
    145     WebRange range = mainFrame->markedRange();
    146     vector<int> intArray(2);
    147     intArray[0] = range.startOffset();
    148     intArray[1] = range.endOffset();
    149 
    150     NPObject* resultArray = WebBindings::makeIntArray(intArray);
    151     result->set(resultArray);
    152     WebBindings::releaseObject(resultArray);
    153 }
    154 
    155 void TextInputController::selectedRange(const CppArgumentList&, CppVariant* result)
    156 {
    157     result->setNull();
    158 
    159     WebFrame* mainFrame = m_webView->mainFrame();
    160     if (!mainFrame)
    161         return;
    162 
    163     WebRange range = mainFrame->selectionRange();
    164     vector<int> intArray(2);
    165     intArray[0] = range.startOffset();
    166     intArray[1] = range.endOffset();
    167 
    168     NPObject* resultArray = WebBindings::makeIntArray(intArray);
    169     result->set(resultArray);
    170     WebBindings::releaseObject(resultArray);
    171 }
    172 
    173 void TextInputController::firstRectForCharacterRange(const CppArgumentList& arguments, CppVariant* result)
    174 {
    175     result->setNull();
    176 
    177     WebFrame* frame = m_webView->focusedFrame();
    178     if (!frame)
    179         return;
    180 
    181     if (arguments.size() < 2 || !arguments[0].isNumber() || !arguments[1].isNumber())
    182         return;
    183 
    184     WebRect rect;
    185     if (!frame->firstRectForCharacterRange(arguments[0].toInt32(), arguments[1].toInt32(), rect))
    186         return;
    187 
    188     vector<int> intArray(4);
    189     intArray[0] = rect.x;
    190     intArray[1] = rect.y;
    191     intArray[2] = rect.width;
    192     intArray[3] = rect.height;
    193 
    194     NPObject* resultArray = WebBindings::makeIntArray(intArray);
    195     result->set(resultArray);
    196     WebBindings::releaseObject(resultArray);
    197 }
    198 
    199 void TextInputController::setComposition(const CppArgumentList& arguments, CppVariant* result)
    200 {
    201     result->setNull();
    202 
    203     if (arguments.size() < 1)
    204         return;
    205 
    206     // Sends a keydown event with key code = 0xE5 to emulate input method behavior.
    207     WebKeyboardEvent keyDown;
    208     keyDown.type = WebInputEvent::RawKeyDown;
    209     keyDown.modifiers = 0;
    210     keyDown.windowsKeyCode = 0xE5; // VKEY_PROCESSKEY
    211     keyDown.setKeyIdentifierFromWindowsKeyCode();
    212     m_webView->handleInputEvent(keyDown);
    213 
    214     WebVector<WebCompositionUnderline> underlines;
    215     WebString text(WebString::fromUTF8(arguments[0].toString()));
    216     m_webView->setComposition(text, underlines, 0, text.length());
    217 }
    218 
    219 }
    220