Addressing post-review comments after r226614
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Jan 2018 20:55:36 +0000 (20:55 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Jan 2018 20:55:36 +0000 (20:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182151

Patch by Chris Nardi <cnardi@chromium.org> on 2018-01-26
Reviewed by Myles C. Maxfield.

PerformanceTests:

* StitchMarker/wtf/text/StringImpl.h:
(WTF::isSpaceOrNewline):
* StitchMarker/wtf/text/TextBreakIterator.cpp:
(WTF::numCodeUnitsInGraphemeClusters):
* StitchMarker/wtf/text/TextBreakIterator.h:

Source/WebCore:

* html/HTMLTextAreaElement.cpp:
(WebCore::HTMLTextAreaElement::sanitizeUserInputValue):
* html/TextFieldInputType.cpp:
(WebCore::limitLength):
* platform/LocalizedStrings.cpp:
(WebCore::truncatedStringForLookupMenuItem):
* rendering/updating/RenderTreeBuilderFirstLetter.cpp:
(WebCore::RenderTreeBuilder::FirstLetter::createRenderers):

Source/WTF:

* wtf/text/StringImpl.h:
(WTF::isSpaceOrNewline):
* wtf/text/TextBreakIterator.cpp:
(WTF::numCodeUnitsInGraphemeClusters):
* wtf/text/TextBreakIterator.h:

Tools:

* TestWebKitAPI/Tests/WTF/TextBreakIterator.cpp:
(TestWebKitAPI::TEST):

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

15 files changed:
PerformanceTests/ChangeLog
PerformanceTests/StitchMarker/wtf/text/StringImpl.h
PerformanceTests/StitchMarker/wtf/text/TextBreakIterator.cpp
PerformanceTests/StitchMarker/wtf/text/TextBreakIterator.h
Source/WTF/ChangeLog
Source/WTF/wtf/text/StringImpl.h
Source/WTF/wtf/text/TextBreakIterator.cpp
Source/WTF/wtf/text/TextBreakIterator.h
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLTextAreaElement.cpp
Source/WebCore/html/TextFieldInputType.cpp
Source/WebCore/platform/LocalizedStrings.cpp
Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WTF/TextBreakIterator.cpp

index 93aa8a7..2c19602 100644 (file)
@@ -1,3 +1,16 @@
+2018-01-26  Chris Nardi  <cnardi@chromium.org>
+
+        Addressing post-review comments after r226614
+        https://bugs.webkit.org/show_bug.cgi?id=182151
+
+        Reviewed by Myles C. Maxfield.
+
+        * StitchMarker/wtf/text/StringImpl.h:
+        (WTF::isSpaceOrNewline):
+        * StitchMarker/wtf/text/TextBreakIterator.cpp:
+        (WTF::numCodeUnitsInGraphemeClusters):
+        * StitchMarker/wtf/text/TextBreakIterator.h:
+
 2018-01-22  Antti Koivisto  <antti@apple.com>
 
         StyleBench: Separate test for :nth pseudo classes
index 96e85d5..9009060 100644 (file)
@@ -1065,7 +1065,7 @@ inline int codePointCompare(const StringImpl* string1, const StringImpl* string2
     return codePointCompare16(string1, string2);
 }
 
-inline bool isSpaceOrNewline(UChar c)
+inline bool isSpaceOrNewline(UChar32 c)
 {
     // Use isASCIISpace() for basic Latin-1.
     // This will include newlines, which aren't included in Unicode DirWS.
index f8b7c40..3f454c9 100644 (file)
@@ -280,7 +280,7 @@ unsigned numGraphemeClusters(StringView string)
     return numGraphemeClusters;
 }
 
-unsigned numCharactersInGraphemeClusters(StringView string, unsigned numGraphemeClusters)
+unsigned numCodeUnitsInGraphemeClusters(StringView string, unsigned numGraphemeClusters)
 {
     unsigned stringLength = string.length();
 
index e9e05c0..4115008 100644 (file)
@@ -331,9 +331,10 @@ private:
 // counted as 1 grapheme cluster.
 WTF_EXPORT_PRIVATE unsigned numGraphemeClusters(StringView);
 
-// Returns the number of characters which will be less than or equal to
-// the specified grapheme cluster length.
-WTF_EXPORT_PRIVATE unsigned numCharactersInGraphemeClusters(StringView, unsigned);
+// Returns the number of code units that create the specified number of
+// grapheme clusters. If there are fewer clusters in the string than specified,
+// the length of the string is returned.
+WTF_EXPORT_PRIVATE unsigned numCodeUnitsInGraphemeClusters(StringView, unsigned);
 
 }
 
index 805d9c0..3a7f814 100644 (file)
@@ -1,3 +1,16 @@
+2018-01-26  Chris Nardi  <cnardi@chromium.org>
+
+        Addressing post-review comments after r226614
+        https://bugs.webkit.org/show_bug.cgi?id=182151
+
+        Reviewed by Myles C. Maxfield.
+
+        * wtf/text/StringImpl.h:
+        (WTF::isSpaceOrNewline):
+        * wtf/text/TextBreakIterator.cpp:
+        (WTF::numCodeUnitsInGraphemeClusters):
+        * wtf/text/TextBreakIterator.h:
+
 2018-01-26  Filip Pizlo  <fpizlo@apple.com>
 
         Fix style - need to use C comments.
index af1cc9a..7029f19 100644 (file)
@@ -575,7 +575,7 @@ int codePointCompare(const StringImpl*, const StringImpl*);
 
 // FIXME: Should rename this to make clear it uses the Unicode definition of whitespace.
 // Most WebKit callers don't want that would use isASCIISpace or isHTMLSpace instead.
-bool isSpaceOrNewline(UChar);
+bool isSpaceOrNewline(UChar32);
 
 template<typename CharacterType> unsigned lengthOfNullTerminatedString(const CharacterType*);
 
@@ -736,7 +736,7 @@ inline int codePointCompare(const StringImpl* string1, const StringImpl* string2
     return codePointCompare(string1->characters16(), string1->length(), string2->characters16(), string2->length());
 }
 
-inline bool isSpaceOrNewline(UChar character)
+inline bool isSpaceOrNewline(UChar32 character)
 {
     // Use isASCIISpace() for all Latin-1 characters. This will include newlines, which aren't included in Unicode DirWS.
     return character <= 0xFF ? isASCIISpace(character) : u_charDirection(character) == U_WHITE_SPACE_NEUTRAL;
index e9ce9c3..5b88b44 100644 (file)
@@ -284,7 +284,7 @@ unsigned numGraphemeClusters(StringView string)
     return numGraphemeClusters;
 }
 
-unsigned numCharactersInGraphemeClusters(StringView string, unsigned numGraphemeClusters)
+unsigned numCodeUnitsInGraphemeClusters(StringView string, unsigned numGraphemeClusters)
 {
     unsigned stringLength = string.length();
 
index b22ea61..392329d 100644 (file)
@@ -340,9 +340,10 @@ private:
 // counted as 1 grapheme cluster.
 WTF_EXPORT_PRIVATE unsigned numGraphemeClusters(StringView);
 
-// Returns the number of characters which will be less than or equal to
-// the specified grapheme cluster length.
-WTF_EXPORT_PRIVATE unsigned numCharactersInGraphemeClusters(StringView, unsigned);
+// Returns the number of code units that create the specified number of
+// grapheme clusters. If there are fewer clusters in the string than specified,
+// the length of the string is returned.
+WTF_EXPORT_PRIVATE unsigned numCodeUnitsInGraphemeClusters(StringView, unsigned);
 
 }
 
index 0d98564..38326ba 100644 (file)
@@ -1,3 +1,19 @@
+2018-01-26  Chris Nardi  <cnardi@chromium.org>
+
+        Addressing post-review comments after r226614
+        https://bugs.webkit.org/show_bug.cgi?id=182151
+
+        Reviewed by Myles C. Maxfield.
+
+        * html/HTMLTextAreaElement.cpp:
+        (WebCore::HTMLTextAreaElement::sanitizeUserInputValue):
+        * html/TextFieldInputType.cpp:
+        (WebCore::limitLength):
+        * platform/LocalizedStrings.cpp:
+        (WebCore::truncatedStringForLookupMenuItem):
+        * rendering/updating/RenderTreeBuilderFirstLetter.cpp:
+        (WebCore::RenderTreeBuilder::FirstLetter::createRenderers):
+
 2018-01-26  Antoine Quint  <graouts@apple.com>
 
         [iOS] prefers-reduced-motion media query is not working
index b8996ea..b486170 100644 (file)
@@ -319,7 +319,7 @@ void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent&
 
 String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue, unsigned maxLength)
 {
-    return proposedValue.left(numCharactersInGraphemeClusters(proposedValue, maxLength));
+    return proposedValue.left(numCodeUnitsInGraphemeClusters(proposedValue, maxLength));
 }
 
 RefPtr<TextControlInnerTextElement> HTMLTextAreaElement::innerTextElement() const
index bec34ba..afc030a 100644 (file)
@@ -395,7 +395,7 @@ static String limitLength(const String& string, unsigned maxNumGraphemeClusters)
     if (stringView.is8Bit())
         limitedLength = std::min(firstNonTabControlCharacterIndex, maxNumGraphemeClusters);
     else
-        limitedLength = numCharactersInGraphemeClusters(stringView.substring(0, firstNonTabControlCharacterIndex), maxNumGraphemeClusters);
+        limitedLength = numCodeUnitsInGraphemeClusters(stringView.substring(0, firstNonTabControlCharacterIndex), maxNumGraphemeClusters);
     return string.left(limitedLength);
 }
 
index bad6f48..80fd4e2 100644 (file)
@@ -85,7 +85,7 @@ static String truncatedStringForLookupMenuItem(const String& original)
     unsigned maxNumberOfGraphemeClustersInLookupMenuItem = 24;
 
     String trimmed = original.stripWhiteSpace();
-    unsigned numberOfCharacters = numCharactersInGraphemeClusters(trimmed, maxNumberOfGraphemeClustersInLookupMenuItem);
+    unsigned numberOfCharacters = numCodeUnitsInGraphemeClusters(trimmed, maxNumberOfGraphemeClustersInLookupMenuItem);
     return numberOfCharacters == trimmed.length() ? trimmed : makeString(trimmed.left(numberOfCharacters), horizontalEllipsis);
 }
 
index 245564f..3feabd5 100644 (file)
@@ -219,24 +219,24 @@ void RenderTreeBuilder::FirstLetter::createRenderers(RenderBlock& firstLetterBlo
 
         // Account for leading spaces and punctuation.
         while (length < oldText.length() && shouldSkipForFirstLetter(oldText.characterStartingAt(length)))
-            length += numCharactersInGraphemeClusters(StringView(oldText).substring(length), 1);
+            length += numCodeUnitsInGraphemeClusters(StringView(oldText).substring(length), 1);
 
         // Account for first grapheme cluster.
-        length += numCharactersInGraphemeClusters(StringView(oldText).substring(length), 1);
+        length += numCodeUnitsInGraphemeClusters(StringView(oldText).substring(length), 1);
 
         // Keep looking for whitespace and allowed punctuation, but avoid
         // accumulating just whitespace into the :first-letter.
-        unsigned numCharacters = 0;
-        for (unsigned scanLength = length; scanLength < oldText.length(); scanLength += numCharacters) {
+        unsigned numCodeUnits = 0;
+        for (unsigned scanLength = length; scanLength < oldText.length(); scanLength += numCodeUnits) {
             UChar32 c = oldText.characterStartingAt(scanLength);
 
             if (!shouldSkipForFirstLetter(c))
                 break;
 
-            numCharacters = numCharactersInGraphemeClusters(StringView(oldText).substring(scanLength), 1);
+            numCodeUnits = numCodeUnitsInGraphemeClusters(StringView(oldText).substring(scanLength), 1);
 
             if (isPunctuationForFirstLetter(c))
-                length = scanLength + numCharacters;
+                length = scanLength + numCodeUnits;
         }
 
         auto* textNode = currentTextChild.textNode();
index 1318caf..48d86b2 100644 (file)
@@ -1,3 +1,13 @@
+2018-01-26  Chris Nardi  <cnardi@chromium.org>
+
+        Addressing post-review comments after r226614
+        https://bugs.webkit.org/show_bug.cgi?id=182151
+
+        Reviewed by Myles C. Maxfield.
+
+        * TestWebKitAPI/Tests/WTF/TextBreakIterator.cpp:
+        (TestWebKitAPI::TEST):
+
 2018-01-25  Per Arne Vollan  <pvollan@apple.com>
 
         Unreviewed, rolling out r224920.
index c2f84e3..d4d7008 100644 (file)
@@ -65,82 +65,82 @@ TEST(WTF, TextBreakIteratorNumGraphemeClusters)
     EXPECT_EQ(3U, numGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' })));
 }
 
-TEST(WTF, TextBreakIteratorNumCharactersInGraphemeClusters)
+TEST(WTF, TextBreakIteratorNumCodeUnitsInGraphemeClusters)
 {
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { }, 0));
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { }, 1));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { "" }, 0));
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { "" }, 1));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(makeUTF16({ }), 0));
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(makeUTF16({ }), 1));
-
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(StringView { "a" }, 1));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(makeUTF16({ 'a' }), 1));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(StringView { "\n" }, 1));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(StringView { "\r" }, 1));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(makeUTF16({ '\n' }), 1));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(makeUTF16({ '\r' }), 1));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { "abc" }, 0));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(StringView { "abc" }, 1));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(StringView { "abc" }, 2));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(StringView { "abc" }, 3));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(StringView { "abc" }, 4));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 0));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 1));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 2));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 3));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 4));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { "\r\n" }, 0));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(StringView { "\r\n" }, 1));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(StringView { "\r\n" }, 2));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(StringView { "\r\n" }, 3));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n' }), 0));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n' }), 1));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n' }), 2));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n' }), 3));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { "\n\r" }, 0));
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(StringView { "\n\r" }, 1));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(StringView { "\n\r" }, 2));
-
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(makeUTF16({ '\n', '\r' }), 1));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ '\n', '\r' }), 2));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { "\r\n\r" }, 0));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(StringView { "\r\n\r" }, 1));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(StringView { "\r\n\r" }, 2));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(StringView { "\r\n\r" }, 3));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 0));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 1));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 2));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 3));
-
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ 'g', 0x308 }), 1));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(makeUTF16({ 0x1100, 0x1161, 0x11A8 }), 1));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ 0x0BA8, 0x0BBF }), 1));
-
-    EXPECT_EQ(1U, numCharactersInGraphemeClusters(makeUTF16({ 0x308, 'g' }), 1));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(StringView { "\r\nbc" }, 0));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(StringView { "\r\nbc" }, 1));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(StringView { "\r\nbc" }, 2));
-    EXPECT_EQ(4U, numCharactersInGraphemeClusters(StringView { "\r\nbc" }, 3));
-    EXPECT_EQ(4U, numCharactersInGraphemeClusters(StringView { "\r\nbc" }, 4));
-    EXPECT_EQ(4U, numCharactersInGraphemeClusters(StringView { "\r\nbc" }, 5));
-
-    EXPECT_EQ(0U, numCharactersInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 0));
-    EXPECT_EQ(2U, numCharactersInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 1));
-    EXPECT_EQ(3U, numCharactersInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 2));
-    EXPECT_EQ(4U, numCharactersInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 3));
-    EXPECT_EQ(4U, numCharactersInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 4));
-    EXPECT_EQ(4U, numCharactersInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 5));
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { }, 0));
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { }, 1));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { "" }, 0));
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { "" }, 1));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(makeUTF16({ }), 0));
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(makeUTF16({ }), 1));
+
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(StringView { "a" }, 1));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'a' }), 1));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(StringView { "\n" }, 1));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(StringView { "\r" }, 1));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\n' }), 1));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r' }), 1));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { "abc" }, 0));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(StringView { "abc" }, 1));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(StringView { "abc" }, 2));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(StringView { "abc" }, 3));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(StringView { "abc" }, 4));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 0));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 1));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 2));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 3));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'a', 'b', 'c' }), 4));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { "\r\n" }, 0));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(StringView { "\r\n" }, 1));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(StringView { "\r\n" }, 2));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(StringView { "\r\n" }, 3));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n' }), 0));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n' }), 1));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n' }), 2));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n' }), 3));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { "\n\r" }, 0));
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(StringView { "\n\r" }, 1));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(StringView { "\n\r" }, 2));
+
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\n', '\r' }), 1));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\n', '\r' }), 2));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { "\r\n\r" }, 0));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(StringView { "\r\n\r" }, 1));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(StringView { "\r\n\r" }, 2));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(StringView { "\r\n\r" }, 3));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 0));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 1));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 2));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(makeUTF16({ '\r', '\n', '\r' }), 3));
+
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'g', 0x308 }), 1));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(makeUTF16({ 0x1100, 0x1161, 0x11A8 }), 1));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ 0x0BA8, 0x0BBF }), 1));
+
+    EXPECT_EQ(1U, numCodeUnitsInGraphemeClusters(makeUTF16({ 0x308, 'g' }), 1));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(StringView { "\r\nbc" }, 0));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(StringView { "\r\nbc" }, 1));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(StringView { "\r\nbc" }, 2));
+    EXPECT_EQ(4U, numCodeUnitsInGraphemeClusters(StringView { "\r\nbc" }, 3));
+    EXPECT_EQ(4U, numCodeUnitsInGraphemeClusters(StringView { "\r\nbc" }, 4));
+    EXPECT_EQ(4U, numCodeUnitsInGraphemeClusters(StringView { "\r\nbc" }, 5));
+
+    EXPECT_EQ(0U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 0));
+    EXPECT_EQ(2U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 1));
+    EXPECT_EQ(3U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 2));
+    EXPECT_EQ(4U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 3));
+    EXPECT_EQ(4U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 4));
+    EXPECT_EQ(4U, numCodeUnitsInGraphemeClusters(makeUTF16({ 'g', 0x308, 'b', 'c' }), 5));
 }
 
 } // namespace TestWebKitAPI