Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: third_party/WebKit/Source/core/editing/InputMethodControllerTest.cpp

Issue 2493703002: Make "compositionend" event fired after setting caret position (Closed)
Patch Set: Refactor Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/editing/InputMethodController.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/editing/InputMethodController.h" 5 #include "core/editing/InputMethodController.h"
6 6
7 #include "core/dom/Document.h" 7 #include "core/dom/Document.h"
8 #include "core/dom/Element.h" 8 #include "core/dom/Element.h"
9 #include "core/dom/Range.h" 9 #include "core/dom/Range.h"
10 #include "core/editing/Editor.h" 10 #include "core/editing/Editor.h"
(...skipping 10 matching lines...) Expand all
21 namespace blink { 21 namespace blink {
22 22
23 class InputMethodControllerTest : public ::testing::Test { 23 class InputMethodControllerTest : public ::testing::Test {
24 protected: 24 protected:
25 InputMethodController& controller() { 25 InputMethodController& controller() {
26 return frame().inputMethodController(); 26 return frame().inputMethodController();
27 } 27 }
28 Document& document() const { return *m_document; } 28 Document& document() const { return *m_document; }
29 LocalFrame& frame() const { return m_dummyPageHolder->frame(); } 29 LocalFrame& frame() const { return m_dummyPageHolder->frame(); }
30 Element* insertHTMLElement(const char* elementCode, const char* elementId); 30 Element* insertHTMLElement(const char* elementCode, const char* elementId);
31 void createHTMLWithCompositionInputEventListeners();
32 void createHTMLWithCompositionEndEventListener(const SelectionType);
31 33
32 private: 34 private:
33 void SetUp() override; 35 void SetUp() override;
34 36
35 std::unique_ptr<DummyPageHolder> m_dummyPageHolder; 37 std::unique_ptr<DummyPageHolder> m_dummyPageHolder;
36 Persistent<Document> m_document; 38 Persistent<Document> m_document;
37 }; 39 };
38 40
39 void InputMethodControllerTest::SetUp() { 41 void InputMethodControllerTest::SetUp() {
40 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); 42 m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
41 m_document = &m_dummyPageHolder->document(); 43 m_document = &m_dummyPageHolder->document();
42 DCHECK(m_document); 44 DCHECK(m_document);
43 } 45 }
44 46
45 Element* InputMethodControllerTest::insertHTMLElement(const char* elementCode, 47 Element* InputMethodControllerTest::insertHTMLElement(const char* elementCode,
46 const char* elementId) { 48 const char* elementId) {
47 document().write(elementCode); 49 document().write(elementCode);
48 document().updateStyleAndLayout(); 50 document().updateStyleAndLayout();
49 Element* element = document().getElementById(elementId); 51 Element* element = document().getElementById(elementId);
50 element->focus(); 52 element->focus();
51 return element; 53 return element;
52 } 54 }
53 55
56 void InputMethodControllerTest::createHTMLWithCompositionInputEventListeners() {
57 document().settings()->setScriptEnabled(true);
58 Element* editable =
59 insertHTMLElement("<div id='sample' contenteditable></div>", "sample");
60 Element* script = document().createElement("script");
61 script->setInnerHTML(
62 "document.getElementById('sample').addEventListener('beforeinput', "
63 "event => document.title = `beforeinput.data:${event.data};`);"
yosin_UTC9 2016/11/17 05:38:06 nit: s/event =>/ event ->/
yabinh 2016/11/17 06:58:15 It seems that "event ->" doesn't work.
yabinh 2016/11/17 18:18:45 According to ES6, there is only fat arrow function
64 "document.getElementById('sample').addEventListener('input', "
65 "event => document.title += `input.data:${event.data};`);"
yosin_UTC9 2016/11/17 05:38:06 nit: s/event =>/ event ->/
66 "document.getElementById('sample').addEventListener('compositionend', "
67 "event => document.title += `compositionend.data:${event.data};`);");
yosin_UTC9 2016/11/17 05:38:06 nit: s/event =>/ event ->/
68 document().body()->appendChild(script);
69 document().view()->updateAllLifecyclePhases();
70 editable->focus();
71 }
72
73 void InputMethodControllerTest::createHTMLWithCompositionEndEventListener(
74 const SelectionType type) {
75 document().settings()->setScriptEnabled(true);
76 Element* editable =
77 insertHTMLElement("<div id='sample' contentEditable></div>", "sample");
78 Element* script = document().createElement("script");
79
80 switch (type) {
81 case NoSelection:
82 script->setInnerHTML(
83 // If the caret position is set before firing 'compositonend' event
84 // (and it should), the final caret position will be reset to null.
85 "document.getElementById('sample').addEventListener('compositionend',"
86 "event => getSelection().removeAllRanges());");
87 break;
88 case CaretSelection:
89 script->setInnerHTML(
90 // If the caret position is set before firing 'compositonend' event
91 // (and it should), the final caret position will be reset to [3,3].
92 "document.getElementById('sample').addEventListener('compositionend',"
93 "event => {"
94 " const node = document.getElementById('sample').firstChild;"
95 " getSelection().collapse(node, 3);"
96 "});");
97 break;
98 case RangeSelection:
99 script->setInnerHTML(
100 // If the caret position is set before firing 'compositonend' event
101 // (and it should), the final caret position will be reset to [2,4].
102 "document.getElementById('sample').addEventListener('compositionend',"
103 "event => {"
104 " const node = document.getElementById('sample').firstChild;"
105 " var range = document.createRange();"
yosin_UTC9 2016/11/17 05:38:06 nit: s/var/const/
106 " range.setStart(node, 2);"
107 " range.setEnd(node, 4);"
108 " const selection = getSelection();"
109 " selection.removeAllRanges();"
110 " selection.addRange(range);"
yosin_UTC9 2016/11/17 05:38:06 We don't need to use |Rang| object. Just write as
yabinh 2016/11/17 06:58:15 Done.
111 "});");
112 break;
113 default:
114 NOTREACHED();
115 }
116 document().body()->appendChild(script);
117 document().view()->updateAllLifecyclePhases();
118 editable->focus();
119 }
120
54 TEST_F(InputMethodControllerTest, BackspaceFromEndOfInput) { 121 TEST_F(InputMethodControllerTest, BackspaceFromEndOfInput) {
55 HTMLInputElement* input = 122 HTMLInputElement* input =
56 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample")); 123 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample"));
57 124
58 input->setValue("fooX"); 125 input->setValue("fooX");
59 document().updateStyleAndLayout(); 126 document().updateStyleAndLayout();
60 controller().setEditableSelectionOffsets(PlainTextRange(4, 4)); 127 controller().setEditableSelectionOffsets(PlainTextRange(4, 4));
61 EXPECT_STREQ("fooX", input->value().utf8().data()); 128 EXPECT_STREQ("fooX", input->value().utf8().data());
62 controller().extendSelectionAndDelete(0, 0); 129 controller().extendSelectionAndDelete(0, 0);
63 EXPECT_STREQ("fooX", input->value().utf8().data()); 130 EXPECT_STREQ("fooX", input->value().utf8().data());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 input->setValue("fooX"); 163 input->setValue("fooX");
97 document().updateStyleAndLayout(); 164 document().updateStyleAndLayout();
98 controller().setEditableSelectionOffsets(PlainTextRange(4, 4)); 165 controller().setEditableSelectionOffsets(PlainTextRange(4, 4));
99 EXPECT_STREQ("fooX", input->value().utf8().data()); 166 EXPECT_STREQ("fooX", input->value().utf8().data());
100 controller().extendSelectionAndDelete(0, 1); 167 controller().extendSelectionAndDelete(0, 1);
101 EXPECT_STREQ("fooX", input->value().utf8().data()); 168 EXPECT_STREQ("fooX", input->value().utf8().data());
102 } 169 }
103 170
104 TEST_F(InputMethodControllerTest, SetCompositionFromExistingText) { 171 TEST_F(InputMethodControllerTest, SetCompositionFromExistingText) {
105 Element* div = insertHTMLElement( 172 Element* div = insertHTMLElement(
106 "<div id='sample' contenteditable='true'>hello world</div>", "sample"); 173 "<div id='sample' contenteditable>hello world</div>", "sample");
107 174
108 Vector<CompositionUnderline> underlines; 175 Vector<CompositionUnderline> underlines;
109 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0)); 176 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
110 controller().setCompositionFromExistingText(underlines, 0, 5); 177 controller().setCompositionFromExistingText(underlines, 0, 5);
111 178
112 Range* range = controller().compositionRange(); 179 Range* range = controller().compositionRange();
113 EXPECT_EQ(0, range->startOffset()); 180 EXPECT_EQ(0, range->startOffset());
114 EXPECT_EQ(5, range->endOffset()); 181 EXPECT_EQ(5, range->endOffset());
115 182
116 PlainTextRange plainTextRange(PlainTextRange::create(*div, *range)); 183 PlainTextRange plainTextRange(PlainTextRange::create(*div, *range));
117 EXPECT_EQ(0u, plainTextRange.start()); 184 EXPECT_EQ(0u, plainTextRange.start());
118 EXPECT_EQ(5u, plainTextRange.end()); 185 EXPECT_EQ(5u, plainTextRange.end());
119 } 186 }
120 187
121 TEST_F(InputMethodControllerTest, SetCompositionKeepingStyle) { 188 TEST_F(InputMethodControllerTest, SetCompositionKeepingStyle) {
122 Element* div = insertHTMLElement( 189 Element* div = insertHTMLElement(
123 "<div id='sample' " 190 "<div id='sample' "
124 "contenteditable='true'>abc1<b>2</b>34567<b>8</b>9</div>", 191 "contenteditable>abc1<b>2</b>34567<b>8</b>9</div>",
125 "sample"); 192 "sample");
126 193
127 Vector<CompositionUnderline> underlines; 194 Vector<CompositionUnderline> underlines;
128 underlines.append(CompositionUnderline(3, 12, Color(255, 0, 0), false, 0)); 195 underlines.append(CompositionUnderline(3, 12, Color(255, 0, 0), false, 0));
129 controller().setCompositionFromExistingText(underlines, 3, 12); 196 controller().setCompositionFromExistingText(underlines, 3, 12);
130 197
131 // Subtract a character. 198 // Subtract a character.
132 controller().setComposition(String("12345789"), underlines, 8, 8); 199 controller().setComposition(String("12345789"), underlines, 8, 8);
133 EXPECT_STREQ("abc1<b>2</b>3457<b>8</b>9", div->innerHTML().utf8().data()); 200 EXPECT_STREQ("abc1<b>2</b>3457<b>8</b>9", div->innerHTML().utf8().data());
134 201
135 // Append a character. 202 // Append a character.
136 controller().setComposition(String("123456789"), underlines, 9, 9); 203 controller().setComposition(String("123456789"), underlines, 9, 9);
137 EXPECT_STREQ("abc1<b>2</b>34567<b>8</b>9", div->innerHTML().utf8().data()); 204 EXPECT_STREQ("abc1<b>2</b>34567<b>8</b>9", div->innerHTML().utf8().data());
138 205
139 // Subtract and append characters. 206 // Subtract and append characters.
140 controller().setComposition(String("123hello789"), underlines, 11, 11); 207 controller().setComposition(String("123hello789"), underlines, 11, 11);
141 EXPECT_STREQ("abc1<b>2</b>3hello7<b>8</b>9", div->innerHTML().utf8().data()); 208 EXPECT_STREQ("abc1<b>2</b>3hello7<b>8</b>9", div->innerHTML().utf8().data());
142 } 209 }
143 210
144 TEST_F(InputMethodControllerTest, SetCompositionWithEmojiKeepingStyle) { 211 TEST_F(InputMethodControllerTest, SetCompositionWithEmojiKeepingStyle) {
145 // U+1F3E0 = 0xF0 0x9F 0x8F 0xA0 (UTF8). It's an emoji character. 212 // U+1F3E0 = 0xF0 0x9F 0x8F 0xA0 (UTF8). It's an emoji character.
146 Element* div = insertHTMLElement( 213 Element* div = insertHTMLElement(
147 "<div id='sample' contenteditable='true'><b>&#x1f3e0</b></div>", 214 "<div id='sample' contenteditable><b>&#x1f3e0</b></div>", "sample");
148 "sample");
149 215
150 Vector<CompositionUnderline> underlines; 216 Vector<CompositionUnderline> underlines;
151 underlines.append(CompositionUnderline(0, 2, Color(255, 0, 0), false, 0)); 217 underlines.append(CompositionUnderline(0, 2, Color(255, 0, 0), false, 0));
152 218
153 controller().setCompositionFromExistingText(underlines, 0, 2); 219 controller().setCompositionFromExistingText(underlines, 0, 2);
154 220
155 // 0xF0 0x9F 0x8F 0xAB is also an emoji character, with the same leading 221 // 0xF0 0x9F 0x8F 0xAB is also an emoji character, with the same leading
156 // surrogate pair to the previous one. 222 // surrogate pair to the previous one.
157 controller().setComposition(String::fromUTF8("\xF0\x9F\x8F\xAB"), underlines, 223 controller().setComposition(String::fromUTF8("\xF0\x9F\x8F\xAB"), underlines,
158 2, 2); 224 2, 2);
159 EXPECT_STREQ("<b>\xF0\x9F\x8F\xAB</b>", div->innerHTML().utf8().data()); 225 EXPECT_STREQ("<b>\xF0\x9F\x8F\xAB</b>", div->innerHTML().utf8().data());
160 226
161 controller().setComposition(String::fromUTF8("\xF0\x9F\x8F\xA0"), underlines, 227 controller().setComposition(String::fromUTF8("\xF0\x9F\x8F\xA0"), underlines,
162 2, 2); 228 2, 2);
163 EXPECT_STREQ("<b>\xF0\x9F\x8F\xA0</b>", div->innerHTML().utf8().data()); 229 EXPECT_STREQ("<b>\xF0\x9F\x8F\xA0</b>", div->innerHTML().utf8().data());
164 } 230 }
165 231
166 TEST_F(InputMethodControllerTest, 232 TEST_F(InputMethodControllerTest,
167 SetCompositionWithTeluguSignVisargaKeepingStyle) { 233 SetCompositionWithTeluguSignVisargaKeepingStyle) {
168 // U+0C03 = 0xE0 0xB0 0x83 (UTF8), a telugu sign visarga with one code point. 234 // U+0C03 = 0xE0 0xB0 0x83 (UTF8), a telugu sign visarga with one code point.
169 // It's one grapheme cluster if separated. It can also form one grapheme 235 // It's one grapheme cluster if separated. It can also form one grapheme
170 // cluster with another code point(e.g, itself). 236 // cluster with another code point(e.g, itself).
171 Element* div = insertHTMLElement( 237 Element* div = insertHTMLElement(
172 "<div id='sample' contenteditable='true'><b>&#xc03</b></div>", "sample"); 238 "<div id='sample' contenteditable><b>&#xc03</b></div>", "sample");
173 239
174 Vector<CompositionUnderline> underlines; 240 Vector<CompositionUnderline> underlines;
175 underlines.append(CompositionUnderline(0, 2, Color(255, 0, 0), false, 0)); 241 underlines.append(CompositionUnderline(0, 2, Color(255, 0, 0), false, 0));
176 controller().setCompositionFromExistingText(underlines, 0, 1); 242 controller().setCompositionFromExistingText(underlines, 0, 1);
177 243
178 // 0xE0 0xB0 0x83 0xE0 0xB0 0x83, a telugu character with 2 code points in 244 // 0xE0 0xB0 0x83 0xE0 0xB0 0x83, a telugu character with 2 code points in
179 // 1 grapheme cluster. 245 // 1 grapheme cluster.
180 controller().setComposition(String::fromUTF8("\xE0\xB0\x83\xE0\xB0\x83"), 246 controller().setComposition(String::fromUTF8("\xE0\xB0\x83\xE0\xB0\x83"),
181 underlines, 2, 2); 247 underlines, 2, 2);
182 EXPECT_STREQ("<b>\xE0\xB0\x83\xE0\xB0\x83</b>", 248 EXPECT_STREQ("<b>\xE0\xB0\x83\xE0\xB0\x83</b>",
183 div->innerHTML().utf8().data()); 249 div->innerHTML().utf8().data());
184 250
185 controller().setComposition(String::fromUTF8("\xE0\xB0\x83"), underlines, 1, 251 controller().setComposition(String::fromUTF8("\xE0\xB0\x83"), underlines, 1,
186 1); 252 1);
187 EXPECT_STREQ("<b>\xE0\xB0\x83</b>", div->innerHTML().utf8().data()); 253 EXPECT_STREQ("<b>\xE0\xB0\x83</b>", div->innerHTML().utf8().data());
188 } 254 }
189 255
190 TEST_F(InputMethodControllerTest, SelectionOnConfirmExistingText) { 256 TEST_F(InputMethodControllerTest, SelectionOnConfirmExistingText) {
191 insertHTMLElement("<div id='sample' contenteditable='true'>hello world</div>", 257 insertHTMLElement("<div id='sample' contenteditable>hello world</div>",
192 "sample"); 258 "sample");
193 259
194 Vector<CompositionUnderline> underlines; 260 Vector<CompositionUnderline> underlines;
195 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0)); 261 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
196 controller().setCompositionFromExistingText(underlines, 0, 5); 262 controller().setCompositionFromExistingText(underlines, 0, 5);
197 263
198 controller().finishComposingText(InputMethodController::KeepSelection); 264 controller().finishComposingText(InputMethodController::KeepSelection);
199 EXPECT_EQ(0, frame().selection().start().computeOffsetInContainerNode()); 265 EXPECT_EQ(0, frame().selection().start().computeOffsetInContainerNode());
200 EXPECT_EQ(0, frame().selection().end().computeOffsetInContainerNode()); 266 EXPECT_EQ(0, frame().selection().end().computeOffsetInContainerNode());
201 } 267 }
(...skipping 23 matching lines...) Expand all
225 controller().setComposition(String(""), underlines, 0, 3); 291 controller().setComposition(String(""), underlines, 0, 3);
226 292
227 EXPECT_STREQ("", input->value().utf8().data()); 293 EXPECT_STREQ("", input->value().utf8().data());
228 } 294 }
229 295
230 TEST_F(InputMethodControllerTest, 296 TEST_F(InputMethodControllerTest,
231 SetCompositionFromExistingTextWithCollapsedWhiteSpace) { 297 SetCompositionFromExistingTextWithCollapsedWhiteSpace) {
232 // Creates a div with one leading new line char. The new line char is hidden 298 // Creates a div with one leading new line char. The new line char is hidden
233 // from the user and IME, but is visible to InputMethodController. 299 // from the user and IME, but is visible to InputMethodController.
234 Element* div = insertHTMLElement( 300 Element* div = insertHTMLElement(
235 "<div id='sample' contenteditable='true'>\nhello world</div>", "sample"); 301 "<div id='sample' contenteditable>\nhello world</div>", "sample");
236 302
237 Vector<CompositionUnderline> underlines; 303 Vector<CompositionUnderline> underlines;
238 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0)); 304 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
239 controller().setCompositionFromExistingText(underlines, 0, 5); 305 controller().setCompositionFromExistingText(underlines, 0, 5);
240 306
241 Range* range = controller().compositionRange(); 307 Range* range = controller().compositionRange();
242 EXPECT_EQ(1, range->startOffset()); 308 EXPECT_EQ(1, range->startOffset());
243 EXPECT_EQ(6, range->endOffset()); 309 EXPECT_EQ(6, range->endOffset());
244 310
245 PlainTextRange plainTextRange(PlainTextRange::create(*div, *range)); 311 PlainTextRange plainTextRange(PlainTextRange::create(*div, *range));
246 EXPECT_EQ(0u, plainTextRange.start()); 312 EXPECT_EQ(0u, plainTextRange.start());
247 EXPECT_EQ(5u, plainTextRange.end()); 313 EXPECT_EQ(5u, plainTextRange.end());
248 } 314 }
249 315
250 TEST_F(InputMethodControllerTest, 316 TEST_F(InputMethodControllerTest,
251 SetCompositionFromExistingTextWithInvalidOffsets) { 317 SetCompositionFromExistingTextWithInvalidOffsets) {
252 insertHTMLElement("<div id='sample' contenteditable='true'>test</div>", 318 insertHTMLElement("<div id='sample' contenteditable>test</div>", "sample");
253 "sample");
254 319
255 Vector<CompositionUnderline> underlines; 320 Vector<CompositionUnderline> underlines;
256 underlines.append(CompositionUnderline(7, 8, Color(255, 0, 0), false, 0)); 321 underlines.append(CompositionUnderline(7, 8, Color(255, 0, 0), false, 0));
257 controller().setCompositionFromExistingText(underlines, 7, 8); 322 controller().setCompositionFromExistingText(underlines, 7, 8);
258 323
259 EXPECT_FALSE(controller().compositionRange()); 324 EXPECT_FALSE(controller().compositionRange());
260 } 325 }
261 326
262 TEST_F(InputMethodControllerTest, ConfirmPasswordComposition) { 327 TEST_F(InputMethodControllerTest, ConfirmPasswordComposition) {
263 HTMLInputElement* input = toHTMLInputElement(insertHTMLElement( 328 HTMLInputElement* input = toHTMLInputElement(insertHTMLElement(
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 document().updateStyleAndLayout(); 615 document().updateStyleAndLayout();
551 controller().setEditableSelectionOffsets(PlainTextRange(2, 2)); 616 controller().setEditableSelectionOffsets(PlainTextRange(2, 2));
552 EXPECT_STREQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86", 617 EXPECT_STREQ("\xF0\x9F\x8F\x86\xF0\x9F\x8F\x86",
553 input->value().utf8().data()); 618 input->value().utf8().data());
554 controller().deleteSurroundingText(1, 1); 619 controller().deleteSurroundingText(1, 1);
555 EXPECT_STREQ("", input->value().utf8().data()); 620 EXPECT_STREQ("", input->value().utf8().data());
556 } 621 }
557 622
558 TEST_F(InputMethodControllerTest, DeleteSurroundingTextForMultipleNodes) { 623 TEST_F(InputMethodControllerTest, DeleteSurroundingTextForMultipleNodes) {
559 Element* div = insertHTMLElement( 624 Element* div = insertHTMLElement(
560 "<div id='sample' contenteditable='true'>aaa" 625 "<div id='sample' contenteditable>aaa"
561 "<div id='sample2' contenteditable='true'>bbb" 626 "<div id='sample2' contenteditable>bbb"
562 "<div id='sample3' contenteditable='true'>ccc" 627 "<div id='sample3' contenteditable>ccc"
563 "<div id='sample4' contenteditable='true'>ddd" 628 "<div id='sample4' contenteditable>ddd"
564 "<div id='sample5' contenteditable='true'>eee" 629 "<div id='sample5' contenteditable>eee"
565 "</div></div></div></div></div>", 630 "</div></div></div></div></div>",
566 "sample"); 631 "sample");
567 632
568 controller().setEditableSelectionOffsets(PlainTextRange(8, 8)); 633 controller().setEditableSelectionOffsets(PlainTextRange(8, 8));
569 EXPECT_STREQ("aaa\nbbb\nccc\nddd\neee", div->innerText().utf8().data()); 634 EXPECT_STREQ("aaa\nbbb\nccc\nddd\neee", div->innerText().utf8().data());
570 EXPECT_EQ(8u, controller().getSelectionOffsets().start()); 635 EXPECT_EQ(8u, controller().getSelectionOffsets().start());
571 EXPECT_EQ(8u, controller().getSelectionOffsets().end()); 636 EXPECT_EQ(8u, controller().getSelectionOffsets().end());
572 637
573 controller().deleteSurroundingText(1, 0); 638 controller().deleteSurroundingText(1, 0);
574 EXPECT_STREQ("aaa\nbbbccc\nddd\neee", div->innerText().utf8().data()); 639 EXPECT_STREQ("aaa\nbbbccc\nddd\neee", div->innerText().utf8().data());
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 EXPECT_STREQ("heABllo", input->value().utf8().data()); 706 EXPECT_STREQ("heABllo", input->value().utf8().data());
642 EXPECT_EQ(7u, controller().getSelectionOffsets().start()); 707 EXPECT_EQ(7u, controller().getSelectionOffsets().start());
643 EXPECT_EQ(7u, controller().getSelectionOffsets().end()); 708 EXPECT_EQ(7u, controller().getSelectionOffsets().end());
644 } 709 }
645 710
646 TEST_F(InputMethodControllerTest, 711 TEST_F(InputMethodControllerTest,
647 SetCompositionForContentEditableWithNewCaretPositions) { 712 SetCompositionForContentEditableWithNewCaretPositions) {
648 // There are 7 nodes and 5+1+5+1+3+4+3 characters: "hello", '\n', "world", 713 // There are 7 nodes and 5+1+5+1+3+4+3 characters: "hello", '\n', "world",
649 // "\n", "012", "3456", "789". 714 // "\n", "012", "3456", "789".
650 Element* div = insertHTMLElement( 715 Element* div = insertHTMLElement(
651 "<div id='sample' contenteditable='true'>" 716 "<div id='sample' contenteditable>"
652 "hello" 717 "hello"
653 "<div id='sample2' contenteditable='true'>world" 718 "<div id='sample2' contenteditable>world"
654 "<p>012<b>3456</b><i>789</i></p>" 719 "<p>012<b>3456</b><i>789</i></p>"
655 "</div>" 720 "</div>"
656 "</div>", 721 "</div>",
657 "sample"); 722 "sample");
658 723
659 controller().setEditableSelectionOffsets(PlainTextRange(17, 17)); 724 controller().setEditableSelectionOffsets(PlainTextRange(17, 17));
660 EXPECT_STREQ("hello\nworld\n0123456789", div->innerText().utf8().data()); 725 EXPECT_STREQ("hello\nworld\n0123456789", div->innerText().utf8().data());
661 EXPECT_EQ(17u, controller().getSelectionOffsets().start()); 726 EXPECT_EQ(17u, controller().getSelectionOffsets().start());
662 EXPECT_EQ(17u, controller().getSelectionOffsets().end()); 727 EXPECT_EQ(17u, controller().getSelectionOffsets().end());
663 728
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 // The caret exceeds right boundary. 802 // The caret exceeds right boundary.
738 // "hello\nworld\n01234AB56789*". 803 // "hello\nworld\n01234AB56789*".
739 controller().setComposition("AB", underlines, 100, 100); 804 controller().setComposition("AB", underlines, 100, 100);
740 EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().utf8().data()); 805 EXPECT_STREQ("hello\nworld\n01234AB56789", div->innerText().utf8().data());
741 EXPECT_EQ(24u, controller().getSelectionOffsets().start()); 806 EXPECT_EQ(24u, controller().getSelectionOffsets().start());
742 EXPECT_EQ(24u, controller().getSelectionOffsets().end()); 807 EXPECT_EQ(24u, controller().getSelectionOffsets().end());
743 } 808 }
744 809
745 TEST_F(InputMethodControllerTest, SetCompositionWithEmptyText) { 810 TEST_F(InputMethodControllerTest, SetCompositionWithEmptyText) {
746 Element* div = insertHTMLElement( 811 Element* div = insertHTMLElement(
747 "<div id='sample' contenteditable='true'>hello</div>", "sample"); 812 "<div id='sample' contenteditable>hello</div>", "sample");
748 813
749 controller().setEditableSelectionOffsets(PlainTextRange(2, 2)); 814 controller().setEditableSelectionOffsets(PlainTextRange(2, 2));
750 EXPECT_STREQ("hello", div->innerText().utf8().data()); 815 EXPECT_STREQ("hello", div->innerText().utf8().data());
751 EXPECT_EQ(2u, controller().getSelectionOffsets().start()); 816 EXPECT_EQ(2u, controller().getSelectionOffsets().start());
752 EXPECT_EQ(2u, controller().getSelectionOffsets().end()); 817 EXPECT_EQ(2u, controller().getSelectionOffsets().end());
753 818
754 Vector<CompositionUnderline> underlines0; 819 Vector<CompositionUnderline> underlines0;
755 underlines0.append(CompositionUnderline(0, 0, Color(255, 0, 0), false, 0)); 820 underlines0.append(CompositionUnderline(0, 0, Color(255, 0, 0), false, 0));
756 Vector<CompositionUnderline> underlines2; 821 Vector<CompositionUnderline> underlines2;
757 underlines2.append(CompositionUnderline(0, 2, Color(255, 0, 0), false, 0)); 822 underlines2.append(CompositionUnderline(0, 2, Color(255, 0, 0), false, 0));
758 823
759 controller().setComposition("AB", underlines2, 2, 2); 824 controller().setComposition("AB", underlines2, 2, 2);
760 // With previous composition. 825 // With previous composition.
761 controller().setComposition("", underlines0, 2, 2); 826 controller().setComposition("", underlines0, 2, 2);
762 EXPECT_STREQ("hello", div->innerText().utf8().data()); 827 EXPECT_STREQ("hello", div->innerText().utf8().data());
763 EXPECT_EQ(4u, controller().getSelectionOffsets().start()); 828 EXPECT_EQ(4u, controller().getSelectionOffsets().start());
764 EXPECT_EQ(4u, controller().getSelectionOffsets().end()); 829 EXPECT_EQ(4u, controller().getSelectionOffsets().end());
765 830
766 // Without previous composition. 831 // Without previous composition.
767 controller().setComposition("", underlines0, -1, -1); 832 controller().setComposition("", underlines0, -1, -1);
768 EXPECT_STREQ("hello", div->innerText().utf8().data()); 833 EXPECT_STREQ("hello", div->innerText().utf8().data());
769 EXPECT_EQ(3u, controller().getSelectionOffsets().start()); 834 EXPECT_EQ(3u, controller().getSelectionOffsets().start());
770 EXPECT_EQ(3u, controller().getSelectionOffsets().end()); 835 EXPECT_EQ(3u, controller().getSelectionOffsets().end());
771 } 836 }
772 837
773 TEST_F(InputMethodControllerTest, InsertLineBreakWhileComposingText) { 838 TEST_F(InputMethodControllerTest, InsertLineBreakWhileComposingText) {
774 Element* div = insertHTMLElement( 839 Element* div =
775 "<div id='sample' contenteditable='true'></div>", "sample"); 840 insertHTMLElement("<div id='sample' contenteditable></div>", "sample");
776 841
777 Vector<CompositionUnderline> underlines; 842 Vector<CompositionUnderline> underlines;
778 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0)); 843 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
779 controller().setComposition("hello", underlines, 5, 5); 844 controller().setComposition("hello", underlines, 5, 5);
780 EXPECT_STREQ("hello", div->innerText().utf8().data()); 845 EXPECT_STREQ("hello", div->innerText().utf8().data());
781 EXPECT_EQ(5u, controller().getSelectionOffsets().start()); 846 EXPECT_EQ(5u, controller().getSelectionOffsets().start());
782 EXPECT_EQ(5u, controller().getSelectionOffsets().end()); 847 EXPECT_EQ(5u, controller().getSelectionOffsets().end());
783 848
784 frame().editor().insertLineBreak(); 849 frame().editor().insertLineBreak();
785 EXPECT_STREQ("\n\n", div->innerText().utf8().data()); 850 EXPECT_STREQ("\n\n", div->innerText().utf8().data());
786 EXPECT_EQ(1u, controller().getSelectionOffsets().start()); 851 EXPECT_EQ(1u, controller().getSelectionOffsets().start());
787 EXPECT_EQ(1u, controller().getSelectionOffsets().end()); 852 EXPECT_EQ(1u, controller().getSelectionOffsets().end());
788 } 853 }
789 854
790 TEST_F(InputMethodControllerTest, InsertLineBreakAfterConfirmingText) { 855 TEST_F(InputMethodControllerTest, InsertLineBreakAfterConfirmingText) {
791 Element* div = insertHTMLElement( 856 Element* div =
792 "<div id='sample' contenteditable='true'></div>", "sample"); 857 insertHTMLElement("<div id='sample' contenteditable></div>", "sample");
793 858
794 controller().commitText("hello", 0); 859 controller().commitText("hello", 0);
795 EXPECT_STREQ("hello", div->innerText().utf8().data()); 860 EXPECT_STREQ("hello", div->innerText().utf8().data());
796 861
797 controller().setEditableSelectionOffsets(PlainTextRange(2, 2)); 862 controller().setEditableSelectionOffsets(PlainTextRange(2, 2));
798 EXPECT_EQ(2u, controller().getSelectionOffsets().start()); 863 EXPECT_EQ(2u, controller().getSelectionOffsets().start());
799 EXPECT_EQ(2u, controller().getSelectionOffsets().end()); 864 EXPECT_EQ(2u, controller().getSelectionOffsets().end());
800 865
801 frame().editor().insertLineBreak(); 866 frame().editor().insertLineBreak();
802 EXPECT_STREQ("he\nllo", div->innerText().utf8().data()); 867 EXPECT_STREQ("he\nllo", div->innerText().utf8().data());
803 EXPECT_EQ(3u, controller().getSelectionOffsets().start()); 868 EXPECT_EQ(3u, controller().getSelectionOffsets().start());
804 EXPECT_EQ(3u, controller().getSelectionOffsets().end()); 869 EXPECT_EQ(3u, controller().getSelectionOffsets().end());
805 } 870 }
806 871
807 TEST_F(InputMethodControllerTest, CompositionInputEventIsComposing) { 872 TEST_F(InputMethodControllerTest, CompositionInputEventIsComposing) {
808 document().settings()->setScriptEnabled(true); 873 document().settings()->setScriptEnabled(true);
809 Element* editable = insertHTMLElement( 874 Element* editable =
810 "<div id='sample' contentEditable='true'></div>", "sample"); 875 insertHTMLElement("<div id='sample' contenteditable></div>", "sample");
811 Element* script = document().createElement("script"); 876 Element* script = document().createElement("script");
812 script->setInnerHTML( 877 script->setInnerHTML(
813 "document.getElementById('sample').addEventListener('beforeinput', " 878 "document.getElementById('sample').addEventListener('beforeinput', "
814 "function(event) {" 879 "event => {"
815 " document.title = `beforeinput.isComposing:${event.isComposing};`;" 880 " document.title = `beforeinput.isComposing:${event.isComposing};`;"
816 "});" 881 "});"
817 "document.getElementById('sample').addEventListener('input', " 882 "document.getElementById('sample').addEventListener('input', "
818 "function(event) {" 883 "event => {"
819 " document.title += `input.isComposing:${event.isComposing};`;" 884 " document.title += `input.isComposing:${event.isComposing};`;"
820 "});"); 885 "});");
821 document().body()->appendChild(script, ASSERT_NO_EXCEPTION); 886 document().body()->appendChild(script);
yosin_UTC9 2016/11/17 05:38:06 http://crrev.com/2506903005 is being committed. Pl
822 document().view()->updateAllLifecyclePhases(); 887 document().view()->updateAllLifecyclePhases();
823 888
824 // Simulate composition in the |contentEditable|. 889 // Simulate composition in the |contentEditable|.
825 Vector<CompositionUnderline> underlines; 890 Vector<CompositionUnderline> underlines;
826 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0)); 891 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
827 editable->focus(); 892 editable->focus();
828 893
829 document().setTitle(emptyString()); 894 document().setTitle(emptyString());
830 controller().setComposition("foo", underlines, 0, 3); 895 controller().setComposition("foo", underlines, 0, 3);
831 EXPECT_STREQ("beforeinput.isComposing:true;input.isComposing:true;", 896 EXPECT_STREQ("beforeinput.isComposing:true;input.isComposing:true;",
832 document().title().utf8().data()); 897 document().title().utf8().data());
833 898
834 document().setTitle(emptyString()); 899 document().setTitle(emptyString());
835 controller().finishComposingText(InputMethodController::KeepSelection); 900 controller().finishComposingText(InputMethodController::KeepSelection);
836 // Last pair of InputEvent should also be inside composition scope. 901 // Last pair of InputEvent should also be inside composition scope.
837 EXPECT_STREQ("beforeinput.isComposing:true;input.isComposing:true;", 902 EXPECT_STREQ("beforeinput.isComposing:true;input.isComposing:true;",
838 document().title().utf8().data()); 903 document().title().utf8().data());
839 } 904 }
840 905
841 TEST_F(InputMethodControllerTest, CompositionInputEventData) { 906 TEST_F(InputMethodControllerTest, CompositionInputEventForReplace) {
842 document().settings()->setScriptEnabled(true); 907 createHTMLWithCompositionInputEventListeners();
843 Element* editable = insertHTMLElement(
844 "<div id='sample' contentEditable='true'></div>", "sample");
845 Element* script = document().createElement("script");
846 script->setInnerHTML(
847 "document.getElementById('sample').addEventListener('beforeinput', "
848 "function(event) {"
849 " document.title = `beforeinput.data:${event.data};`;"
850 "});"
851 "document.getElementById('sample').addEventListener('input', "
852 "function(event) {"
853 " document.title += `input.data:${event.data};`;"
854 "});");
855 document().body()->appendChild(script, ASSERT_NO_EXCEPTION);
856 document().view()->updateAllLifecyclePhases();
857 908
858 // Simulate composition in the |contentEditable|. 909 // Simulate composition in the |contentEditable|.
859 Vector<CompositionUnderline> underlines; 910 Vector<CompositionUnderline> underlines;
860 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0)); 911 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
861 editable->focus();
862 912
863 document().setTitle(emptyString()); 913 document().setTitle(emptyString());
864 controller().setComposition("n", underlines, 0, 1); 914 controller().setComposition("hell", underlines, 4, 4);
915 EXPECT_STREQ("beforeinput.data:hell;input.data:hell;",
916 document().title().utf8().data());
917
918 // Replace the existing composition.
919 // TODO(yabinh): should be "beforeinput.data:hello;input.data:hello;".
920 document().setTitle(emptyString());
921 controller().setComposition("hello", underlines, 0, 0);
922 EXPECT_STREQ("beforeinput.data:o;input.data:o;",
923 document().title().utf8().data());
924 }
925
926 TEST_F(InputMethodControllerTest, CompositionInputEventForConfirm) {
927 createHTMLWithCompositionInputEventListeners();
928
929 // Simulate composition in the |contentEditable|.
930 Vector<CompositionUnderline> underlines;
931 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
932
933 document().setTitle(emptyString());
934 controller().setComposition("hello", underlines, 5, 5);
935 EXPECT_STREQ("beforeinput.data:hello;input.data:hello;",
936 document().title().utf8().data());
937
938 // Confirm the ongoing composition.
939 document().setTitle(emptyString());
940 controller().finishComposingText(InputMethodController::KeepSelection);
941 EXPECT_STREQ(
942 "beforeinput.data:hello;input.data:hello;compositionend.data:hello;",
943 document().title().utf8().data());
944 }
945
946 TEST_F(InputMethodControllerTest, CompositionInputEventForDelete) {
947 createHTMLWithCompositionInputEventListeners();
948
949 // Simulate composition in the |contentEditable|.
950 Vector<CompositionUnderline> underlines;
951 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
952
953 document().setTitle(emptyString());
954 controller().setComposition("hello", underlines, 5, 5);
955 EXPECT_STREQ("beforeinput.data:hello;input.data:hello;",
956 document().title().utf8().data());
957
958 // Delete the existing composition.
959 document().setTitle(emptyString());
960 controller().setComposition("", underlines, 0, 0);
961 EXPECT_STREQ("beforeinput.data:;compositionend.data:;",
962 document().title().utf8().data());
963 }
964
965 TEST_F(InputMethodControllerTest, CompositionInputEventForInsert) {
966 createHTMLWithCompositionInputEventListeners();
967
968 // Simulate composition in the |contentEditable|.
969 Vector<CompositionUnderline> underlines;
970 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
971
972 // Insert new text without previous composition.
973 document().setTitle(emptyString());
974 document().updateStyleAndLayout();
975 controller().commitText("hello", 0);
976 EXPECT_STREQ("beforeinput.data:hello;input.data:hello;",
977 document().title().utf8().data());
978
979 document().setTitle(emptyString());
980 controller().setComposition("n", underlines, 1, 1);
865 EXPECT_STREQ("beforeinput.data:n;input.data:n;", 981 EXPECT_STREQ("beforeinput.data:n;input.data:n;",
866 document().title().utf8().data()); 982 document().title().utf8().data());
867 983
984 // Insert new text with previous composition.
868 document().setTitle(emptyString()); 985 document().setTitle(emptyString());
869 controller().setComposition("ni", underlines, 0, 1); 986 document().updateStyleAndLayout();
870 EXPECT_STREQ("beforeinput.data:i;input.data:i;", 987 controller().commitText("hello", 1);
871 document().title().utf8().data()); 988 EXPECT_STREQ(
989 "beforeinput.data:hello;input.data:hello;compositionend.data:hello;",
990 document().title().utf8().data());
991 }
872 992
873 document().setTitle(emptyString()); 993 TEST_F(InputMethodControllerTest, CompositionEndEventForConfirm) {
874 controller().finishComposingText(InputMethodController::KeepSelection); 994 createHTMLWithCompositionEndEventListener(CaretSelection);
875 EXPECT_STREQ("beforeinput.data:ni;input.data:ni;", 995
876 document().title().utf8().data()); 996 // Simulate composition in the |contentEditable|.
997 Vector<CompositionUnderline> underlines;
998 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
999
1000 controller().setComposition("hello", underlines, 1, 1);
1001 document().updateStyleAndLayout();
1002 EXPECT_EQ(1u, controller().getSelectionOffsets().start());
1003 EXPECT_EQ(1u, controller().getSelectionOffsets().end());
1004
1005 // Confirm the ongoing composition. Note that it moves the caret to the end of
1006 // text [5,5] before firing 'compositonend' event.
1007 controller().finishComposingText(InputMethodController::DoNotKeepSelection);
1008 document().updateStyleAndLayout();
1009 EXPECT_EQ(3u, controller().getSelectionOffsets().start());
1010 EXPECT_EQ(3u, controller().getSelectionOffsets().end());
1011 }
1012
1013 TEST_F(InputMethodControllerTest, CompositionEndEventForInsert) {
1014 createHTMLWithCompositionEndEventListener(CaretSelection);
1015
1016 // Simulate composition in the |contentEditable|.
1017 Vector<CompositionUnderline> underlines;
1018 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
1019
1020 controller().setComposition("n", underlines, 1, 1);
1021
1022 // Insert new text with previous composition. Note that it moves the caret to
1023 // [4,4] before firing 'compositonend' event.
1024 document().updateStyleAndLayout();
1025 controller().commitText("hello", -1);
1026 document().updateStyleAndLayout();
1027 EXPECT_EQ(3u, controller().getSelectionOffsets().start());
1028 EXPECT_EQ(3u, controller().getSelectionOffsets().end());
1029 }
1030
1031 TEST_F(InputMethodControllerTest, CompositionEndEventWithRangeSelection) {
1032 createHTMLWithCompositionEndEventListener(RangeSelection);
1033
1034 // Simulate composition in the |contentEditable|.
1035 Vector<CompositionUnderline> underlines;
1036 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
1037
1038 controller().setComposition("hello", underlines, 1, 1);
1039 document().updateStyleAndLayout();
1040 EXPECT_EQ(1u, controller().getSelectionOffsets().start());
1041 EXPECT_EQ(1u, controller().getSelectionOffsets().end());
1042
1043 // Confirm the ongoing composition. Note that it moves the caret to the end of
1044 // text [5,5] before firing 'compositonend' event.
1045 controller().finishComposingText(InputMethodController::DoNotKeepSelection);
1046 document().updateStyleAndLayout();
1047 EXPECT_EQ(2u, controller().getSelectionOffsets().start());
1048 EXPECT_EQ(4u, controller().getSelectionOffsets().end());
1049 }
1050
1051 TEST_F(InputMethodControllerTest, CompositionEndEventWithNoSelection) {
1052 createHTMLWithCompositionEndEventListener(NoSelection);
1053
1054 // Simulate composition in the |contentEditable|.
1055 Vector<CompositionUnderline> underlines;
1056 underlines.append(CompositionUnderline(0, 5, Color(255, 0, 0), false, 0));
1057
1058 controller().setComposition("hello", underlines, 1, 1);
1059 document().updateStyleAndLayout();
1060 EXPECT_EQ(1u, controller().getSelectionOffsets().start());
1061 EXPECT_EQ(1u, controller().getSelectionOffsets().end());
1062
1063 // Confirm the ongoing composition. Note that it moves the caret to the end of
1064 // text [5,5] before firing 'compositonend' event.
1065 controller().finishComposingText(InputMethodController::DoNotKeepSelection);
1066 document().updateStyleAndLayout();
1067 EXPECT_TRUE(controller().getSelectionOffsets().isNull());
877 } 1068 }
878 1069
879 } // namespace blink 1070 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/InputMethodController.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698