[Qt] Add more support for textInputController
authorrobert@webkit.org <robert@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Apr 2010 14:43:28 +0000 (14:43 +0000)
committerrobert@webkit.org <robert@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 24 Apr 2010 14:43:28 +0000 (14:43 +0000)
2010-04-20  Robert Hogan  <robert@webkit.org>

        Reviewed by Simon Hausmann.

        [Qt] Add more support for textInputController

        Add support for selectedRange(), setMarkedText(), insertText(),
        and firstRectForCharacterRange().

        Unskip tests:

        fast/forms/input-maxlength-ime-preedit.html
        fast/forms/input-maxlength-ime-completed.html
        fast/text/international/thai-cursor-position.html
        fast/events/ime-composition-events-001.html
        editing/selection/5825350-1.html
        editing/selection/5825350-2.html
        editing/selection/mixed-editability-10.html

        https://bugs.webkit.org/show_bug.cgi?id=35702

        * platform/qt/Skipped:

2010-04-20  Robert Hogan  <robert@webkit.org>

        Reviewed by Simon Hausmann.

        [Qt] Add more support for textInputController

        Add support for selectedRange(), setMarkedText(), insertText(),
        and firstRectForCharacterRange().

        Unskip tests:

        fast/forms/input-maxlength-ime-preedit.html
        fast/forms/input-maxlength-ime-completed.html
        fast/text/international/thai-cursor-position.html
        fast/events/ime-composition-events-001.html
        editing/selection/5825350-1.html
        editing/selection/5825350-2.html
        editing/selection/mixed-editability-10.html

        https://bugs.webkit.org/show_bug.cgi?id=35702

        * DumpRenderTree/qt/TextInputControllerQt.cpp:
        (TextInputController::setMarkedText):
        (TextInputController::insertText):
        (TextInputController::selectedRange):
        (TextInputController::firstRectForCharacterRange):
        * DumpRenderTree/qt/TextInputControllerQt.h:

2010-04-20  Robert Hogan  <robert@webkit.org>

        Reviewed by Simon Hausmann.

        [Qt] Add more support for textInputController

        Add support for selectedRange(), setMarkedText(), insertText(),
        and firstRectForCharacterRange().

        https://bugs.webkit.org/show_bug.cgi?id=35702

        * Api/qwebpage.cpp:
        (QWebPagePrivate::inputMethodEvent):
        * WebCoreSupport/DumpRenderTreeSupportQt.cpp:
        (DumpRenderTreeSupportQt::selectedRange):
        (DumpRenderTreeSupportQt::firstRectForCharacterRange):
        * WebCoreSupport/DumpRenderTreeSupportQt.h:
        * tests/qwebpage/tst_qwebpage.cpp:
        (tst_QWebPage::inputMethods):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@58218 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/qt/Skipped
LayoutTests/platform/qt/editing/selection/5825350-1-expected.txt [new file with mode: 0644]
LayoutTests/platform/qt/editing/selection/5825350-2-expected.txt [new file with mode: 0644]
LayoutTests/platform/qt/editing/selection/mixed-editability-10-expected.txt [new file with mode: 0644]
WebKit/qt/Api/qwebpage.cpp
WebKit/qt/ChangeLog
WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.cpp
WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h
WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/qt/TextInputControllerQt.cpp
WebKitTools/DumpRenderTree/qt/TextInputControllerQt.h

index 4759314..17e1191 100644 (file)
@@ -1,3 +1,29 @@
+2010-04-20  Robert Hogan  <robert@webkit.org>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Add more support for textInputController
+
+        Add support for selectedRange(), setMarkedText(), insertText(),
+        and firstRectForCharacterRange().
+
+        Unskip tests:
+
+        fast/forms/input-maxlength-ime-preedit.html
+        fast/forms/input-maxlength-ime-completed.html
+        fast/text/international/thai-cursor-position.html
+        fast/events/ime-composition-events-001.html
+        editing/selection/5825350-1.html
+        editing/selection/5825350-2.html
+        editing/selection/mixed-editability-10.html
+
+        https://bugs.webkit.org/show_bug.cgi?id=35702
+
+        * platform/qt/Skipped:
+        * platform/qt/editing/selection/5825350-1-expected.txt: Added.
+        * platform/qt/editing/selection/5825350-2-expected.txt: Added.
+        * platform/qt/editing/selection/mixed-editability-10-expected.txt: Added.
+
 2010-04-24  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         Not reviewed.
index 5e69ecd..e61e3f2 100644 (file)
@@ -268,17 +268,6 @@ http/tests/security/local-video-source-from-remote.html
 #            Missing features in our DumpRenderTree implementation              #
 # ============================================================================= #
 
-# Missing textInputController.selectedRange()
-editing/selection/5825350-1.html
-editing/selection/5825350-2.html
-editing/selection/mixed-editability-10.html
-
-# Missing textInputController.setMarkedText()
-fast/forms/input-maxlength-ime-preedit.html
-fast/forms/input-maxlength-ime-completed.html
-fast/text/international/thai-cursor-position.html
-fast/events/ime-composition-events-001.html
-
 # Missing textInputController.firstRectForCharacterRange()
 editing/inserting/caret-position.html
 
diff --git a/LayoutTests/platform/qt/editing/selection/5825350-1-expected.txt b/LayoutTests/platform/qt/editing/selection/5825350-1-expected.txt
new file mode 100644 (file)
index 0000000..3ce53f4
--- /dev/null
@@ -0,0 +1,3 @@
+This tests for a bug where moving the caret left towards a non-editable pocket of an editable region would make the caret disappear. The caret should be just before the 'B' in "Bob".
+
+Caret: (8, 48)
diff --git a/LayoutTests/platform/qt/editing/selection/5825350-2-expected.txt b/LayoutTests/platform/qt/editing/selection/5825350-2-expected.txt
new file mode 100644 (file)
index 0000000..d4c6e33
--- /dev/null
@@ -0,0 +1,3 @@
+This tests for a bug where moving the caret right towards a non-editable pocket of an editable region would make the caret disappear. The caret should be just after the 'y' in "Sally".
+
+Caret: (85, 48)
diff --git a/LayoutTests/platform/qt/editing/selection/mixed-editability-10-expected.txt b/LayoutTests/platform/qt/editing/selection/mixed-editability-10-expected.txt
new file mode 100644 (file)
index 0000000..a736634
--- /dev/null
@@ -0,0 +1,25 @@
+#1 DIV element with a non-editable element only align center:
+
+Hello
+#2 DIV element with a non-editable element only align left:
+
+Hello
+#3 DIV element with a non-editable element only align right:
+
+Hello
+#4 DIV element with two non-editable elementwith padding:
+
+Hello World
+#5 DIV element empty
+
+#6 non editable DIV element with an editable empty span element
+
+Hello: 
+Anchor ([object HTMLDivElement], 0 caret[39,44] refpos=39) is correct.
+Anchor ([object HTMLDivElement], 3 caret[77,44] refpos=77) is correct.
+Anchor ([object HTMLDivElement], 1 caret[46,116] refpos=46) is correct.
+Anchor ([object HTMLDivElement], 0 caret[8,116] refpos=8) is correct.
+Anchor ([object HTMLDivElement], 0 caret[70,188] refpos=70) is correct.
+Anchor ([object HTMLDivElement], 3 caret[50,260] refpos=50) is correct.
+Anchor ([object HTMLDivElement], 0 caret[58,332] refpos=58) is correct.
+Anchor ([object HTMLElement], 0 caret[0,0] refpos=0) is correct.
index 47988d6..168ec58 100644 (file)
@@ -1139,6 +1139,9 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
 {
     WebCore::Frame *frame = page->focusController()->focusedOrMainFrame();
     WebCore::Editor *editor = frame->editor();
+#if QT_VERSION >= 0x040600
+    QInputMethodEvent::Attribute selection(QInputMethodEvent::Selection, 0, 0, QVariant());
+#endif
 
     if (!editor->canEdit()) {
         ev->ignore();
@@ -1155,6 +1158,7 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
         renderTextControl = toRenderTextControl(renderer);
 
     Vector<CompositionUnderline> underlines;
+    bool hasSelection = false;
 
     for (int i = 0; i < ev->attributes().size(); ++i) {
         const QInputMethodEvent::Attribute& a = ev->attributes().at(i);
@@ -1178,10 +1182,8 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
         }
 #if QT_VERSION >= 0x040600
         case QInputMethodEvent::Selection: {
-            if (renderTextControl) {
-                renderTextControl->setSelectionStart(qMin(a.start, (a.start + a.length)));
-                renderTextControl->setSelectionEnd(qMax(a.start, (a.start + a.length)));
-            }
+            selection = a;
+            hasSelection = true;
             break;
         }
 #endif
@@ -1190,10 +1192,25 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
 
     if (!ev->commitString().isEmpty())
         editor->confirmComposition(ev->commitString());
-    else if (!ev->preeditString().isEmpty()) {
+    else {
+        // 1. empty preedit with a selection attribute, and start/end of 0 cancels composition
+        // 2. empty preedit with a selection attribute, and start/end of non-0 updates selection of current preedit text
+        // 3. populated preedit with a selection attribute, and start/end of 0 or non-0 updates selection of supplied preedit text
+        // 4. otherwise event is updating supplied pre-edit text
         QString preedit = ev->preeditString();
-        editor->setComposition(preedit, underlines, preedit.length(), 0);
+#if QT_VERSION >= 0x040600
+        if (hasSelection) {
+            QString text = (renderTextControl) ? QString(renderTextControl->text()) : QString();
+            if (preedit.isEmpty() && selection.start + selection.length > 0)
+                preedit = text;
+            editor->setComposition(preedit, underlines,
+                                   (selection.length < 0) ? selection.start + selection.length : selection.start,
+                                   (selection.length < 0) ? selection.start : selection.start + selection.length);
+        } else
+#endif
+            editor->setComposition(preedit, underlines, preedit.length(), 0);
     }
+
     ev->accept();
 }
 
index 649a64d..88b6dcb 100644 (file)
@@ -1,3 +1,23 @@
+2010-04-20  Robert Hogan  <robert@webkit.org>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Add more support for textInputController
+
+        Add support for selectedRange(), setMarkedText(), insertText(),
+        and firstRectForCharacterRange().
+
+        https://bugs.webkit.org/show_bug.cgi?id=35702
+
+        * Api/qwebpage.cpp:
+        (QWebPagePrivate::inputMethodEvent):
+        * WebCoreSupport/DumpRenderTreeSupportQt.cpp:
+        (DumpRenderTreeSupportQt::selectedRange):
+        (DumpRenderTreeSupportQt::firstRectForCharacterRange):
+        * WebCoreSupport/DumpRenderTreeSupportQt.h:
+        * tests/qwebpage/tst_qwebpage.cpp:
+        (tst_QWebPage::inputMethods):
+
 2010-04-22  John Pavan  <john.pavan@nokia.com>
 
         Reviewed by Laszlo Gombos.
index 3f2e221..4cc000a 100644 (file)
@@ -44,6 +44,7 @@
 #if ENABLE(SVG)
 #include "SVGSMILElement.h"
 #endif
+#include "TextIterator.h"
 #include "WorkerThread.h"
 
 #include "qwebframe.h"
@@ -370,3 +371,47 @@ QString DumpRenderTreeSupportQt::markerTextForListItem(const QWebElement& listIt
 {
     return WebCore::markerTextForListItem(listItem.m_element);
 }
+
+QVariantList DumpRenderTreeSupportQt::selectedRange(QWebPage* page)
+{
+    WebCore::Frame* frame = page->handle()->page->focusController()->focusedOrMainFrame();
+    QVariantList selectedRange;
+    RefPtr<Range> range = frame->selection()->toNormalizedRange().get();
+
+    Element* selectionRoot = frame->selection()->rootEditableElement();
+    Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
+
+    RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
+    ASSERT(testRange->startContainer() == scope);
+    int startPosition = TextIterator::rangeLength(testRange.get());
+
+    ExceptionCode ec;
+    testRange->setEnd(range->endContainer(), range->endOffset(), ec);
+    ASSERT(testRange->startContainer() == scope);
+    int endPosition = TextIterator::rangeLength(testRange.get());
+
+    selectedRange << startPosition << (endPosition - startPosition);
+
+    return selectedRange;
+
+}
+
+QVariantList DumpRenderTreeSupportQt::firstRectForCharacterRange(QWebPage* page, int location, int length)
+{
+    WebCore::Frame* frame = page->handle()->page->focusController()->focusedOrMainFrame();
+    QVariantList rect;
+
+    if ((location + length < location) && (location + length != 0))
+        length = 0;
+
+    Element* selectionRoot = frame->selection()->rootEditableElement();
+    Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
+    RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(scope, location, length);
+
+    if (!range)
+        return QVariantList();
+
+    QRect resultRect = frame->firstRectForRange(range.get());
+    rect << resultRect.x() << resultRect.y() << resultRect.width() << resultRect.height();
+    return rect;
+}
index b92b86a..c0187df 100644 (file)
@@ -24,6 +24,7 @@
 #define DumpRenderTreeSupportQt_h
 
 #include "qwebkitglobal.h"
+#include <QVariant>
 
 #include "qwebelement.h"
 
@@ -42,6 +43,8 @@ public:
     static bool isCommandEnabled(QWebPage* page, const QString& name);
     static void setSmartInsertDeleteEnabled(QWebPage* page, bool enabled);
     static void setSelectTrailingWhitespaceEnabled(QWebPage* page, bool enabled);
+    static QVariantList selectedRange(QWebPage* page);
+    static QVariantList firstRectForCharacterRange(QWebPage* page, int location, int length);
 
     static bool pauseAnimation(QWebFrame*, const QString& name, double time, const QString& elementId);
     static bool pauseTransitionOfProperty(QWebFrame*, const QString& name, double time, const QString& elementId);
index e36c587..58eb0c0 100644 (file)
@@ -1406,11 +1406,16 @@ void tst_QWebPage::inputMethods()
     QString selectionValue = variant.value<QString>();
     QCOMPARE(selectionValue, QString("eb"));
 
-    //Set selection with negative length
-    inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 6, -5, QVariant());
+    //Cancel current composition first
+    inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
     QInputMethodEvent eventSelection2("",inputAttributes);
     page->event(&eventSelection2);
 
+    //Set selection with negative length
+    inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 6, -5, QVariant());
+    QInputMethodEvent eventSelection3("",inputAttributes);
+    page->event(&eventSelection3);
+
     //ImAnchorPosition
     variant = page->inputMethodQuery(Qt::ImAnchorPosition);
     anchorPosition =  variant.toInt();
index 87f0021..8679f32 100644 (file)
@@ -1,3 +1,31 @@
+2010-04-20  Robert Hogan  <robert@webkit.org>
+
+        Reviewed by Simon Hausmann.
+
+        [Qt] Add more support for textInputController
+
+        Add support for selectedRange(), setMarkedText(), insertText(),
+        and firstRectForCharacterRange().
+
+        Unskip tests:
+
+        fast/forms/input-maxlength-ime-preedit.html
+        fast/forms/input-maxlength-ime-completed.html
+        fast/text/international/thai-cursor-position.html
+        fast/events/ime-composition-events-001.html
+        editing/selection/5825350-1.html
+        editing/selection/5825350-2.html
+        editing/selection/mixed-editability-10.html
+
+        https://bugs.webkit.org/show_bug.cgi?id=35702
+
+        * DumpRenderTree/qt/TextInputControllerQt.cpp:
+        (TextInputController::setMarkedText):
+        (TextInputController::insertText):
+        (TextInputController::selectedRange):
+        (TextInputController::firstRectForCharacterRange):
+        * DumpRenderTree/qt/TextInputControllerQt.h:
+
 2010-04-23  Eric Seidel  <eric@webkit.org>
 
         Reviewed by Adam Barth.
index 7b8f120..e0c9b61 100644 (file)
  */
 #include "config.h"
 #include "TextInputControllerQt.h"
+#include "../../../WebKit/qt/WebCoreSupport/DumpRenderTreeSupportQt.h"
 
 #include <QApplication>
+#include <QInputMethodEvent>
 #include <QKeyEvent>
 
 TextInputController::TextInputController(QWebPage* parent)
@@ -127,3 +129,32 @@ void TextInputController::doCommand(const QString& command)
     QKeyEvent event2(QEvent::KeyRelease, keycode, modifiers);
     QApplication::sendEvent(parent(), &event2);
 }
+
+void TextInputController::setMarkedText(const QString& string, int start, int end)
+{
+    QList<QInputMethodEvent::Attribute> attributes;
+#if QT_VERSION >= 0x040600
+    QInputMethodEvent::Attribute selection(QInputMethodEvent::Selection, start, end, QVariant());
+    attributes << selection;
+#endif
+    QInputMethodEvent event(string, attributes);
+    QApplication::sendEvent(parent(), &event);
+}
+
+void TextInputController::insertText(const QString& string)
+{
+    QList<QInputMethodEvent::Attribute> attributes;
+    QInputMethodEvent event(string, attributes);
+    event.setCommitString(string);
+    QApplication::sendEvent(parent(), &event);
+}
+
+QVariantList TextInputController::selectedRange()
+{
+    return DumpRenderTreeSupportQt::selectedRange(qobject_cast<QWebPage*>(parent()));
+}
+
+QVariantList TextInputController::firstRectForCharacterRange(int location, int length)
+{
+    return DumpRenderTreeSupportQt::firstRectForCharacterRange(qobject_cast<QWebPage*>(parent()), location, length);
+}
index 7c7433e..0210984 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <QList>
 #include <QObject>
+#include <QVariant>
 #include <QString>
 #include "qwebpage.h"
 
@@ -41,14 +42,14 @@ public:
 
 public slots:
     void doCommand(const QString& command);
-//     void setMarkedText(const QString& str, int from, int length);
+    void setMarkedText(const QString& string, int start, int end);
 //     bool hasMarkedText();
 //     void unmarkText();
 //     QList<int> markedRange();
-//     QList<int> selectedRange();
+    QVariantList selectedRange();
 //     void validAttributesForMarkedText();
-//     void inserText(const QString&);
-//     void firstRectForCharacterRange();
+    void insertText(const QString& string);
+    QVariantList firstRectForCharacterRange(int location, int length);
 //     void characterIndexForPoint(int, int);
 //     void substringFromRange(int, int);
 //     void conversationIdentifier();