OLD | NEW |
---|---|
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 712 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 EXPECT_STREQ("aaa\nbbbddd\neee", div->innerText().utf8().data()); | 723 EXPECT_STREQ("aaa\nbbbddd\neee", div->innerText().utf8().data()); |
724 EXPECT_EQ(7u, controller().getSelectionOffsets().start()); | 724 EXPECT_EQ(7u, controller().getSelectionOffsets().start()); |
725 EXPECT_EQ(7u, controller().getSelectionOffsets().end()); | 725 EXPECT_EQ(7u, controller().getSelectionOffsets().end()); |
726 | 726 |
727 controller().deleteSurroundingText(5, 5); | 727 controller().deleteSurroundingText(5, 5); |
728 EXPECT_STREQ("aaee", div->innerText().utf8().data()); | 728 EXPECT_STREQ("aaee", div->innerText().utf8().data()); |
729 EXPECT_EQ(2u, controller().getSelectionOffsets().start()); | 729 EXPECT_EQ(2u, controller().getSelectionOffsets().start()); |
730 EXPECT_EQ(2u, controller().getSelectionOffsets().end()); | 730 EXPECT_EQ(2u, controller().getSelectionOffsets().end()); |
731 } | 731 } |
732 | 732 |
733 TEST_F(InputMethodControllerTest, | |
734 DeleteSurroundingTextInCodePointsWithMultiCodeTextOnTheLeft) { | |
735 HTMLInputElement* input = | |
736 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample")); | |
737 | |
738 // 'a' + "black star" + SPACE + "trophy" + SPACE + composed text (U+0E01 | |
739 // "ka kai" + U+0E49 "mai tho"). | |
740 // A "black star" is 1 grapheme cluster. It has 1 code point, and its length | |
741 // is 1 (abbreviated as [1,1,1]). A "trophy": [1,1,2]. The composed text: | |
742 // [1,2,2]. | |
743 input->setValue(String::fromUTF8( | |
744 "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89")); | |
745 document().updateStyleAndLayout(); | |
746 // The cursor is at the end of the text. | |
747 controller().setEditableSelectionOffsets(PlainTextRange(8, 8)); | |
748 | |
749 controller().deleteSurroundingTextInCodePoints(2, 0); | |
750 EXPECT_STREQ("a\xE2\x98\x85 \xF0\x9F\x8F\x86 ", input->value().utf8().data()); | |
751 controller().deleteSurroundingTextInCodePoints(4, 0); | |
752 EXPECT_STREQ("a", input->value().utf8().data()); | |
753 | |
754 // 'a' + "black star" + SPACE + "trophy" + SPACE + composed text | |
755 input->setValue(String::fromUTF8( | |
756 "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89")); | |
757 document().updateStyleAndLayout(); | |
758 // The cursor is at the end of the text. | |
759 controller().setEditableSelectionOffsets(PlainTextRange(8, 8)); | |
760 | |
761 // TODO(yabinh): We should only delete 1 code point instead of the entire | |
762 // grapheme cluster (2 code points). The root cause is that we adjust the | |
763 // selection by grapheme cluster in deleteSurroundingText(). | |
764 controller().deleteSurroundingTextInCodePoints(1, 0); | |
765 EXPECT_STREQ("a\xE2\x98\x85 \xF0\x9F\x8F\x86 ", input->value().utf8().data()); | |
766 } | |
767 | |
768 TEST_F(InputMethodControllerTest, | |
769 DeleteSurroundingTextInCodePointsWithMultiCodeTextOnTheRight) { | |
770 HTMLInputElement* input = | |
771 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample")); | |
772 | |
773 // 'a' + "black star" + SPACE + "trophy" + SPACE + composed text | |
774 input->setValue(String::fromUTF8( | |
775 "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89")); | |
776 document().updateStyleAndLayout(); | |
777 controller().setEditableSelectionOffsets(PlainTextRange(0, 0)); | |
778 | |
779 controller().deleteSurroundingTextInCodePoints(0, 5); | |
780 EXPECT_STREQ("\xE0\xB8\x81\xE0\xB9\x89", input->value().utf8().data()); | |
781 | |
782 controller().deleteSurroundingTextInCodePoints(0, 1); | |
783 // TODO(yabinh): Same here. We should only delete 1 code point. | |
784 EXPECT_STREQ("", input->value().utf8().data()); | |
785 } | |
786 | |
787 TEST_F(InputMethodControllerTest, | |
788 DeleteSurroundingTextInCodePointsWithMultiCodeTextOnBothSides) { | |
789 HTMLInputElement* input = | |
790 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample")); | |
791 | |
792 // 'a' + "black star" + SPACE + "trophy" + SPACE + composed text | |
793 input->setValue(String::fromUTF8( | |
794 "a\xE2\x98\x85 \xF0\x9F\x8F\x86 \xE0\xB8\x81\xE0\xB9\x89")); | |
795 document().updateStyleAndLayout(); | |
796 controller().setEditableSelectionOffsets(PlainTextRange(3, 3)); | |
797 controller().deleteSurroundingTextInCodePoints(2, 2); | |
798 EXPECT_STREQ("a\xE0\xB8\x81\xE0\xB9\x89", input->value().utf8().data()); | |
799 } | |
800 | |
801 TEST_F(InputMethodControllerTest, DeleteSurroundingTextInCodePointsWithImage) { | |
802 Element* div = insertHTMLElement( | |
803 "<div id='sample' contenteditable>aaa" | |
804 "<img src='empty.png'>bbb</div>", | |
805 "sample"); | |
806 | |
807 controller().setEditableSelectionOffsets(PlainTextRange(4, 4)); | |
808 controller().deleteSurroundingTextInCodePoints(1, 1); | |
809 EXPECT_STREQ("aaabb", div->innerText().utf8().data()); | |
810 EXPECT_EQ(3u, controller().getSelectionOffsets().start()); | |
811 EXPECT_EQ(3u, controller().getSelectionOffsets().end()); | |
812 } | |
813 | |
814 TEST_F(InputMethodControllerTest, | |
815 DeleteSurroundingTextInCodePointsWithInvalidSurrogatePair) { | |
816 HTMLInputElement* input = | |
817 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample")); | |
818 | |
819 // 'a' + high surrogate of "trophy" + "black star" + low surrogate of "trophy" | |
820 // + SPACE | |
821 const UChar UText[] = {'a', 0xD83C, 0x2605, 0xDFC6, ' ', '\0'}; | |
yosin_UTC9
2017/02/09 07:19:27
s/UText/utext/ or another. Don't start variable na
yabinh
2017/02/09 10:37:03
Done.
| |
822 const String& text = String(UText); | |
823 | |
824 input->setValue(text); | |
825 document().updateStyleAndLayout(); | |
826 // The invalid high surrogate is encoded as '\xED\xA0\xBC', and invalid low | |
827 // surrogate is encoded as '\xED\xBF\x86'. | |
828 EXPECT_STREQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86 ", | |
829 input->value().utf8().data()); | |
830 | |
831 controller().setEditableSelectionOffsets(PlainTextRange(5, 5)); | |
832 // Delete a SPACE. | |
833 controller().deleteSurroundingTextInCodePoints(1, 0); | |
834 EXPECT_STREQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", | |
835 input->value().utf8().data()); | |
836 // Do nothing since there is an invalid surrogate in the requested range. | |
837 controller().deleteSurroundingTextInCodePoints(2, 0); | |
838 EXPECT_STREQ("a\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", | |
839 input->value().utf8().data()); | |
840 | |
841 controller().setEditableSelectionOffsets(PlainTextRange(0, 0)); | |
842 // Delete 'a'. | |
843 controller().deleteSurroundingTextInCodePoints(0, 1); | |
844 EXPECT_STREQ("\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", | |
845 input->value().utf8().data()); | |
846 // Do nothing since there is an invalid surrogate in the requested range. | |
847 controller().deleteSurroundingTextInCodePoints(0, 2); | |
848 EXPECT_STREQ("\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", | |
849 input->value().utf8().data()); | |
850 } | |
851 | |
733 TEST_F(InputMethodControllerTest, SetCompositionForInputWithNewCaretPositions) { | 852 TEST_F(InputMethodControllerTest, SetCompositionForInputWithNewCaretPositions) { |
734 HTMLInputElement* input = | 853 HTMLInputElement* input = |
735 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample")); | 854 toHTMLInputElement(insertHTMLElement("<input id='sample'>", "sample")); |
736 | 855 |
737 input->setValue("hello"); | 856 input->setValue("hello"); |
738 document().updateStyleAndLayout(); | 857 document().updateStyleAndLayout(); |
739 controller().setEditableSelectionOffsets(PlainTextRange(2, 2)); | 858 controller().setEditableSelectionOffsets(PlainTextRange(2, 2)); |
740 EXPECT_STREQ("hello", input->value().utf8().data()); | 859 EXPECT_STREQ("hello", input->value().utf8().data()); |
741 EXPECT_EQ(2u, controller().getSelectionOffsets().start()); | 860 EXPECT_EQ(2u, controller().getSelectionOffsets().start()); |
742 EXPECT_EQ(2u, controller().getSelectionOffsets().end()); | 861 EXPECT_EQ(2u, controller().getSelectionOffsets().end()); |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1190 | 1309 |
1191 controller().commitText(String("string"), underlines, 0); | 1310 controller().commitText(String("string"), underlines, 0); |
1192 | 1311 |
1193 ASSERT_EQ(1u, document().markers().markers().size()); | 1312 ASSERT_EQ(1u, document().markers().markers().size()); |
1194 | 1313 |
1195 EXPECT_EQ(9u, document().markers().markers()[0]->startOffset()); | 1314 EXPECT_EQ(9u, document().markers().markers()[0]->startOffset()); |
1196 EXPECT_EQ(15u, document().markers().markers()[0]->endOffset()); | 1315 EXPECT_EQ(15u, document().markers().markers()[0]->endOffset()); |
1197 } | 1316 } |
1198 | 1317 |
1199 } // namespace blink | 1318 } // namespace blink |
OLD | NEW |