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

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

Issue 2755013004: Improve how DocumentMarkerController updates markers in response to text edits (Closed)
Patch Set: Put shifting logic in relocateMarkerIfNeeded() method Created 3 years, 9 months 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
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 <memory> 7 #include <memory>
8 #include "core/dom/Document.h" 8 #include "core/dom/Document.h"
9 #include "core/dom/Element.h" 9 #include "core/dom/Element.h"
10 #include "core/dom/Range.h" 10 #include "core/dom/Range.h"
(...skipping 1548 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 DocumentMarker::TextMatch); 1559 DocumentMarker::TextMatch);
1560 // Delete "Initial" 1560 // Delete "Initial"
1561 Vector<CompositionUnderline> emptyUnderlines; 1561 Vector<CompositionUnderline> emptyUnderlines;
1562 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); 1562 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7);
1563 controller().commitText(String(""), emptyUnderlines, 0); 1563 controller().commitText(String(""), emptyUnderlines, 0);
1564 1564
1565 // Delete "blah" 1565 // Delete "blah"
1566 controller().setCompositionFromExistingText(emptyUnderlines, 6, 10); 1566 controller().setCompositionFromExistingText(emptyUnderlines, 6, 10);
1567 controller().commitText(String(""), emptyUnderlines, 0); 1567 controller().commitText(String(""), emptyUnderlines, 0);
1568 1568
1569 // Check that the marker was split when the space at the beginning was 1569 // Check that the marker is still attached to " text" and includes the space
1570 // converted to an nbsp 1570 // before "text" but not the space after
1571 EXPECT_EQ(2u, document().markers().markers().size()); 1571 EXPECT_EQ(1u, document().markers().markers().size());
1572 EXPECT_STREQ( 1572 ASSERT_STREQ(
1573 "\xC2\xA0", // UTF-8 for an nbsp 1573 "\xC2\xA0text",
1574 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); 1574 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data());
1575 EXPECT_STREQ(
1576 "text",
1577 getMarkedText(document().markers(), div->firstChild(), 1).utf8().data());
1578 } 1575 }
1579 1576
1580 TEST_F(InputMethodControllerTest, 1577 TEST_F(InputMethodControllerTest,
1581 Marker_WhitespaceFixupAroundMarkerEndingWithSpace) { 1578 Marker_WhitespaceFixupAroundMarkerEndingWithSpace) {
1582 Element* div = insertHTMLElement( 1579 Element* div = insertHTMLElement(
1583 "<div id='sample' contenteditable>Initial text blah</div>", "sample"); 1580 "<div id='sample' contenteditable>Initial text blah</div>", "sample");
1584 1581
1585 // Add marker under "text " (use TextMatch since Composition markers don't 1582 // Add marker under "text " (use TextMatch since Composition markers don't
1586 // persist across editing operations) 1583 // persist across editing operations)
1587 EphemeralRange markerRange = PlainTextRange(8, 13).createRange(*div); 1584 EphemeralRange markerRange = PlainTextRange(8, 13).createRange(*div);
1588 document().markers().addMarker(markerRange.startPosition(), 1585 document().markers().addMarker(markerRange.startPosition(),
1589 markerRange.endPosition(), 1586 markerRange.endPosition(),
1590 DocumentMarker::TextMatch); 1587 DocumentMarker::TextMatch);
1591 // Delete "Initial" 1588 // Delete "Initial"
1592 Vector<CompositionUnderline> emptyUnderlines; 1589 Vector<CompositionUnderline> emptyUnderlines;
1593 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); 1590 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7);
1594 controller().commitText(String(""), emptyUnderlines, 0); 1591 controller().commitText(String(""), emptyUnderlines, 0);
1595 1592
1596 // Delete "blah" 1593 // Delete "blah"
1597 controller().setCompositionFromExistingText(emptyUnderlines, 6, 10); 1594 controller().setCompositionFromExistingText(emptyUnderlines, 6, 10);
1598 controller().commitText(String(""), emptyUnderlines, 0); 1595 controller().commitText(String(""), emptyUnderlines, 0);
1599 1596
1600 // Check that the marker was split when the space at the end was 1597 // Check that the marker is still attached to "text " and includes the space
1601 // converted to an nbsp 1598 // after "text" but not the space before
1602 EXPECT_EQ(2u, document().markers().markers().size()); 1599 EXPECT_EQ(1u, document().markers().markers().size());
1603 EXPECT_STREQ( 1600 ASSERT_STREQ(
1604 "text", 1601 "text\xC2\xA0",
1605 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); 1602 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data());
1606 EXPECT_STREQ(
1607 "\xC2\xA0", // UTF-8 for an nbsp
1608 getMarkedText(document().markers(), div->firstChild(), 1).utf8().data());
1609 } 1603 }
1610 1604
1611 TEST_F(InputMethodControllerTest, 1605 TEST_F(InputMethodControllerTest,
1612 Marker_WhitespaceFixupAroundMarkerBeginningAndEndingWithSpaces) { 1606 Marker_WhitespaceFixupAroundMarkerBeginningAndEndingWithSpaces) {
1613 Element* div = insertHTMLElement( 1607 Element* div = insertHTMLElement(
1614 "<div id='sample' contenteditable>Initial text blah</div>", "sample"); 1608 "<div id='sample' contenteditable>Initial text blah</div>", "sample");
1615 1609
1616 // Add marker under " text " (use TextMatch since Composition markers don't 1610 // Add marker under " text " (use TextMatch since Composition markers don't
1617 // persist across editing operations) 1611 // persist across editing operations)
1618 EphemeralRange markerRange = PlainTextRange(7, 13).createRange(*div); 1612 EphemeralRange markerRange = PlainTextRange(7, 13).createRange(*div);
1619 document().markers().addMarker(markerRange.startPosition(), 1613 document().markers().addMarker(markerRange.startPosition(),
1620 markerRange.endPosition(), 1614 markerRange.endPosition(),
1621 DocumentMarker::TextMatch); 1615 DocumentMarker::TextMatch);
1622 1616
1623 // Delete "Initial" 1617 // Delete "Initial"
1624 Vector<CompositionUnderline> emptyUnderlines; 1618 Vector<CompositionUnderline> emptyUnderlines;
1625 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); 1619 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7);
1626 controller().commitText(String(""), emptyUnderlines, 0); 1620 controller().commitText(String(""), emptyUnderlines, 0);
1627 1621
1628 // Delete "blah" 1622 // Delete "blah"
1629 controller().setCompositionFromExistingText(emptyUnderlines, 6, 10); 1623 controller().setCompositionFromExistingText(emptyUnderlines, 6, 10);
1630 controller().commitText(String(""), emptyUnderlines, 0); 1624 controller().commitText(String(""), emptyUnderlines, 0);
1631 1625
1632 // Check that the marker was split into three pieces when the two spaces were 1626 // Check that the marker is still attached to " text " and includes both the
1633 // converted to nbsps 1627 // space before "text" and the space after
1634 EXPECT_EQ(3u, document().markers().markers().size()); 1628 EXPECT_EQ(1u, document().markers().markers().size());
1635 EXPECT_STREQ( 1629 ASSERT_STREQ(
1636 "\xC2\xA0", // UTF-8 for an nbsp 1630 "\xC2\xA0text\xC2\xA0",
1637 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); 1631 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data());
1638 EXPECT_STREQ(
1639 "text",
1640 getMarkedText(document().markers(), div->firstChild(), 1).utf8().data());
1641 EXPECT_STREQ(
1642 "\xC2\xA0", // UTF-8 for an nbsp
1643 getMarkedText(document().markers(), div->firstChild(), 2).utf8().data());
1644 } 1632 }
1645 1633
1646 TEST_F(InputMethodControllerTest, Marker_ReplaceStartOfMarker) { 1634 TEST_F(InputMethodControllerTest, Marker_ReplaceStartOfMarker) {
1647 Element* div = insertHTMLElement( 1635 Element* div = insertHTMLElement(
1648 "<div id='sample' contenteditable>Initial text</div>", "sample"); 1636 "<div id='sample' contenteditable>Initial text</div>", "sample");
1649 1637
1650 // Add marker under "Initial text" 1638 // Add marker under "Initial text"
1651 EphemeralRange markerRange = PlainTextRange(0, 12).createRange(*div); 1639 EphemeralRange markerRange = PlainTextRange(0, 12).createRange(*div);
1652 document().markers().addMarker(markerRange.startPosition(), 1640 document().markers().addMarker(markerRange.startPosition(),
1653 markerRange.endPosition(), 1641 markerRange.endPosition(),
1654 DocumentMarker::TextMatch); 1642 DocumentMarker::TextMatch);
1655 1643
1656 // Replace "Initial" with "Original" 1644 // Replace "Initial" with "Original"
1657 Vector<CompositionUnderline> emptyUnderlines; 1645 Vector<CompositionUnderline> emptyUnderlines;
1658 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7); 1646 controller().setCompositionFromExistingText(emptyUnderlines, 0, 7);
1659 controller().commitText(String("Original"), emptyUnderlines, 0); 1647 controller().commitText(String("Original"), emptyUnderlines, 0);
1660 1648
1661 // Verify marker is under "al text" 1649 // Verify marker is under "Original text"
1662 // ("Initial" and "Original" have "al" as a common suffix)
1663 EXPECT_EQ(1u, document().markers().markers().size()); 1650 EXPECT_EQ(1u, document().markers().markers().size());
1664 EXPECT_STREQ( 1651 ASSERT_STREQ(
1665 "al text", 1652 "Original text",
1666 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); 1653 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data());
1667 } 1654 }
1668 1655
1669 TEST_F(InputMethodControllerTest, Marker_ReplaceTextContainsStartOfMarker) { 1656 TEST_F(InputMethodControllerTest, Marker_ReplaceTextContainsStartOfMarker) {
1670 Element* div = insertHTMLElement( 1657 Element* div = insertHTMLElement(
1671 "<div id='sample' contenteditable>This is some initial text</div>", 1658 "<div id='sample' contenteditable>This is some initial text</div>",
1672 "sample"); 1659 "sample");
1673 1660
1674 // Add marker under "initial text" 1661 // Add marker under "initial text"
1675 EphemeralRange markerRange = PlainTextRange(13, 25).createRange(*div); 1662 EphemeralRange markerRange = PlainTextRange(13, 25).createRange(*div);
(...skipping 21 matching lines...) Expand all
1697 EphemeralRange markerRange = PlainTextRange(0, 12).createRange(*div); 1684 EphemeralRange markerRange = PlainTextRange(0, 12).createRange(*div);
1698 document().markers().addMarker(markerRange.startPosition(), 1685 document().markers().addMarker(markerRange.startPosition(),
1699 markerRange.endPosition(), 1686 markerRange.endPosition(),
1700 DocumentMarker::TextMatch); 1687 DocumentMarker::TextMatch);
1701 1688
1702 // Replace "text" with "string" 1689 // Replace "text" with "string"
1703 Vector<CompositionUnderline> emptyUnderlines; 1690 Vector<CompositionUnderline> emptyUnderlines;
1704 controller().setCompositionFromExistingText(emptyUnderlines, 8, 12); 1691 controller().setCompositionFromExistingText(emptyUnderlines, 8, 12);
1705 controller().commitText(String("string"), emptyUnderlines, 0); 1692 controller().commitText(String("string"), emptyUnderlines, 0);
1706 1693
1707 // Verify marker is under "Initial " 1694 // Verify marker is under "Initial string"
1708 EXPECT_EQ(1u, document().markers().markers().size()); 1695 EXPECT_EQ(1u, document().markers().markers().size());
1709 EXPECT_STREQ( 1696 ASSERT_STREQ(
1710 "Initial ", 1697 "Initial string",
1711 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data()); 1698 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data());
1712 } 1699 }
1713 1700
1714 TEST_F(InputMethodControllerTest, Marker_ReplaceTextContainsEndOfMarker) { 1701 TEST_F(InputMethodControllerTest, Marker_ReplaceTextContainsEndOfMarker) {
1715 Element* div = insertHTMLElement( 1702 Element* div = insertHTMLElement(
1716 "<div id='sample' contenteditable>This is some initial text</div>", 1703 "<div id='sample' contenteditable>This is some initial text</div>",
1717 "sample"); 1704 "sample");
1718 1705
1719 // Add marker under "some initial" 1706 // Add marker under "some initial"
1720 EphemeralRange markerRange = PlainTextRange(8, 20).createRange(*div); 1707 EphemeralRange markerRange = PlainTextRange(8, 20).createRange(*div);
(...skipping 23 matching lines...) Expand all
1744 EphemeralRange markerRange = PlainTextRange(8, 12).createRange(*div); 1731 EphemeralRange markerRange = PlainTextRange(8, 12).createRange(*div);
1745 document().markers().addMarker(markerRange.startPosition(), 1732 document().markers().addMarker(markerRange.startPosition(),
1746 markerRange.endPosition(), 1733 markerRange.endPosition(),
1747 DocumentMarker::TextMatch); 1734 DocumentMarker::TextMatch);
1748 1735
1749 // Replace "text" with "string" 1736 // Replace "text" with "string"
1750 Vector<CompositionUnderline> emptyUnderlines; 1737 Vector<CompositionUnderline> emptyUnderlines;
1751 controller().setCompositionFromExistingText(emptyUnderlines, 8, 12); 1738 controller().setCompositionFromExistingText(emptyUnderlines, 8, 12);
1752 controller().commitText(String("string"), emptyUnderlines, 0); 1739 controller().commitText(String("string"), emptyUnderlines, 0);
1753 1740
1754 // Verify marker was removed 1741 // Verify marker is under "string"
1755 EXPECT_EQ(0u, document().markers().markers().size()); 1742 EXPECT_EQ(1u, document().markers().markers().size());
1743 ASSERT_STREQ(
1744 "string",
1745 getMarkedText(document().markers(), div->firstChild(), 0).utf8().data());
1756 } 1746 }
1757 1747
1758 TEST_F(InputMethodControllerTest, Marker_ReplaceTextWithMarkerAtBeginning) { 1748 TEST_F(InputMethodControllerTest, Marker_ReplaceTextWithMarkerAtBeginning) {
1759 Element* div = insertHTMLElement( 1749 Element* div = insertHTMLElement(
1760 "<div id='sample' contenteditable>Initial text</div>", "sample"); 1750 "<div id='sample' contenteditable>Initial text</div>", "sample");
1761 1751
1762 // Add marker under "Initial" 1752 // Add marker under "Initial"
1763 EphemeralRange markerRange = PlainTextRange(0, 7).createRange(*div); 1753 EphemeralRange markerRange = PlainTextRange(0, 7).createRange(*div);
1764 document().markers().addMarker(markerRange.startPosition(), 1754 document().markers().addMarker(markerRange.startPosition(),
1765 markerRange.endPosition(), 1755 markerRange.endPosition(),
(...skipping 25 matching lines...) Expand all
1791 // Replace "Initial text" with "New string" 1781 // Replace "Initial text" with "New string"
1792 Vector<CompositionUnderline> emptyUnderlines; 1782 Vector<CompositionUnderline> emptyUnderlines;
1793 controller().setCompositionFromExistingText(emptyUnderlines, 0, 12); 1783 controller().setCompositionFromExistingText(emptyUnderlines, 0, 12);
1794 controller().commitText(String("New string"), emptyUnderlines, 0); 1784 controller().commitText(String("New string"), emptyUnderlines, 0);
1795 1785
1796 // Verify marker was removed 1786 // Verify marker was removed
1797 EXPECT_EQ(0u, document().markers().markers().size()); 1787 EXPECT_EQ(0u, document().markers().markers().size());
1798 } 1788 }
1799 1789
1800 } // namespace blink 1790 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698