Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Feb 2014 16:32:05 +0000 (16:32 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 8 Feb 2014 16:32:05 +0000 (16:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128233

Reviewed by Anders Carlsson.

Source/WebCore:

* accessibility/AccessibilityNodeObject.cpp: Removed unneeded TextIterator.h include.

* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::hasMisspelling): Updated to use StringView for checkSpelling.

* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(AXAttributeStringSetSpelling): Changed to take a StringView.
(AXAttributedStringAppendText): Ditto.
(-[WebAccessibilityObjectWrapper doAXAttributedStringForTextMarkerRange:]): Pass StringView.

* editing/Editor.cpp:
(WebCore::Editor::misspelledWordAtCaretOrRange): Pass StringView.
(WebCore::Editor::misspelledSelectionString): Ditto.
(WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): Ditto.

* editing/TextCheckingHelper.cpp:
(WebCore::findGrammaticalErrors): Renamed this function. Changed to use StringView.
(WebCore::findMisspellings): Use StringView.
(WebCore::TextCheckingHelper::findFirstMisspelling): Ditto. Also separated out assertions
that were asserting multiple things with &&.
(WebCore::TextCheckingHelper::findFirstMisspellingOrBadGrammar): Ditto.
(WebCore::TextCheckingHelper::findFirstGrammarDetail): Ditto.
(WebCore::TextCheckingHelper::findFirstBadGrammar): Ditto.
(WebCore::TextCheckingHelper::isUngrammatical): Ditto.
(WebCore::TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange): Ditto.
(WebCore::checkTextOfParagraph): Ditto.

* editing/TextCheckingHelper.h: Made TextCheckingParagraph::text public. Deleted
TextCheckingParagraph::textDeprecatedCharacters. Added comments about additional
TextCheckingParagraph refinements. Changed checkTextOfParagraph to take a client
reference instead of pointer and StringView instead of characters pointer with length.

* editing/TextIterator.cpp:
(WebCore::TextIterator::appendTextToStringBuilder): Use data members directly,
rather than using functions, since we already checked m_textCharacters for null.
(WebCore::CharacterIterator::string): Use text() instead of characters().
(WebCore::WordAwareIterator::WordAwareIterator): Removed initialization of
m_previousText now that it's a StringView rather than a pointer.
(WebCore::WordAwareIterator::advance): Use TextIterator::text instead of
TextIterator::characters. Also added a FIXME about a fundamental problem
with the implementation of this class!
(WebCore::WordAwareIterator::length): Updated for m_previousText change.
(WebCore::WordAwareIterator::text): Replaced WordAwareIterator::characters with this.
(WebCore::SearchBuffer::append): Changed to take a StringView.
(WebCore::SearchBuffer::prependContext): Ditto.
(WebCore::SearchBuffer::isWordStartMatch): Use StringView.
(WebCore::SearchBuffer::search): Ditto.
(WebCore::findPlainText): Ditto.

* editing/TextIterator.h: Added TextIterator::text that returns a StringView, and
renamed TextIterator::characters to TextIterator::deprecatedTextIteratorCharacters
(easy to search for in source code). Added SimplifiedBackwardsTextIterator::text
and removed SimplifiedBackwardsTextIterator::characters. Added CharacterIterator::text,
and removed CharacterIterator::characters. Added WordAwareIterator::text and removed
WorkdAwareIterator::characters. Changed WordAwareIterator data members to use StringView.

* editing/VisibleSelection.cpp:
(WebCore::VisibleSelection::appendTrailingWhitespace): Use TextIterator::text instead
of TextIterator::characters.

* editing/VisibleUnits.cpp:
(WebCore::previousBoundary): Updated to use StringView.
(WebCore::nextBoundary): Ditto.
(WebCore::startWordBoundary): Ditto.
(WebCore::startOfWord): Ditto.
(WebCore::endWordBoundary): Ditto.
(WebCore::endOfWord): Fixed formatting.
(WebCore::previousWordPositionBoundary): Updated to use StringView.
(WebCore::previousWordPosition): Fixed formatting and got rid of local variable.
(WebCore::nextWordPositionBoundary): Updated to use StringView.
(WebCore::nextWordPosition): Fixed formatting and got rid of local variable.
(WebCore::inSameLine): Fixed formatting.
(WebCore::isStartOfLine): Ditto.
(WebCore::isEndOfLine): Ditto.
(WebCore::absoluteLineDirectionPointToLocalPointInBlock): Changed to take a reference.
(WebCore::previousLinePosition): Fixed formatting chand changed to pass a reference.
(WebCore::nextLinePosition): Ditto.
(WebCore::startSentenceBoundary): Updated to use StringView and got rid of a local.
(WebCore::startOfSentence): Fixed formatting.
(WebCore::endSentenceBoundary): Updated to use StringView and got rid of a local.
(WebCore::endOfSentence): Fixed formatting.
(WebCore::previousSentencePositionBoundary): Updated to use StringView and got rid of
a local.
(WebCore::previousSentencePosition): Ditto.
(WebCore::nextSentencePositionBoundary): Ditto.
(WebCore::nextSentencePosition): Fixed formatting.
(WebCore::endOfParagraph): Ditto.
(WebCore::inSameParagraph): Ditto.
(WebCore::isStartOfParagraph): Ditto.
(WebCore::isEndOfParagraph): Ditto.
(WebCore::inSameBlock): Ditto.
(WebCore::isStartOfBlock): Ditto.
(WebCore::isEndOfBlock): Ditto.
(WebCore::startOfDocument): Ditto.
(WebCore::endOfDocument): Ditto.
(WebCore::inSameDocument): Ditto.
(WebCore::isStartOfDocument): Ditto.
(WebCore::isEndOfDocument): Ditto.
(WebCore::isEndOfEditableOrNonEditableContent): Ditto.

* loader/EmptyClients.h: Use StringView.

* platform/mac/HTMLConverter.mm:
(+[WebHTMLConverter editingAttributedStringFromRange:]): Use StringView.

* platform/text/TextBoundaries.cpp:
(WebCore::endOfFirstWordBoundaryContext): Use StringView and unsigned.
(WebCore::startOfLastWordBoundaryContext): Ditto.

* platform/text/TextBoundaries.h: Change interfaces to use StringView,
and in some cases, unsigned instead of int. All call sites were better off
with unsigned.

* platform/text/TextCheckerClient.h: Use StringView.

* platform/text/mac/TextBoundaries.mm: Changed conditionals to say
USE(APPKIT) instead of PLATFORM(IOS), since that's the real issue.
(WebCore::isSkipCharacter): Tweaked formatting.
(WebCore::isWhitespaceCharacter): Ditto.
(WebCore::isWordDelimitingCharacter): Ditto, also removed local variable.
(WebCore::isSymbolCharacter): Ditto.
(WebCore::tokenizerForString): Ditto.
(WebCore::findSimpleWordBoundary): Use StringView. Also changed to mostly
use unsigned instead of int.
(WebCore::findComplexWordBoundary): Use StringView. Also restructured to
be much more readable, with early returns and such.
(WebCore::findWordBoundary): Use StringView and unsigned.
(WebCore::findEndWordBoundary): Removed redudant copy of the findWordBoundary
function and changed this to just call findWordBoundary. The reason this
function exists is to optimize this case for some non-Mac, non-iOS platforms.
We can always do that for Mac and/or iOS later if we like.
(WebCore::findNextWordFromIndex): Use StringView. Also use wordBreakIterator
instead of using UBreakIterator directly so we get a cached iterator instead
of creating and destroying a new one each time this function is called.

* bindings/objc/DOMUIKitExtensions.mm: Removed unneeded includes.
* dom/Element.cpp: Ditto.
* dom/PositionIterator.cpp: Ditto.
* editing/ApplyBlockElementCommand.cpp: Ditto.
* editing/IndentOutdentCommand.cpp: Ditto.
* editing/InsertListCommand.cpp: Ditto.
* editing/markup.cpp: Ditto.
* html/HTMLElement.cpp: Ditto.
* html/HTMLTextAreaElement.cpp: Ditto.
* page/Frame.cpp: Ditto.
* rendering/RenderTextControl.cpp: Ditto.

Source/WebKit/efl:

* WebCoreSupport/EditorClientEfl.cpp:
(WebCore::EditorClientEfl::checkSpellingOfString): Use StringView.
(WebCore::EditorClientEfl::checkGrammarOfString): Ditto.
* WebCoreSupport/EditorClientEfl.h: Ditto.

Source/WebKit/gtk:

* WebCoreSupport/TextCheckerClientGtk.cpp:
(WebKit::TextCheckerClientGtk::checkSpellingOfString): Use StringView.
(WebKit::TextCheckerClientGtk::checkGrammarOfString): Ditto.
* WebCoreSupport/TextCheckerClientGtk.h: Ditto.

Source/WebKit/mac:

* WebCoreSupport/WebEditorClient.h: Made most data members private. Moved inlines
for iOS out of the class definition. Fixed formatting. Added missing virtual keyword.
Changed interfaces to use StringView.

* WebCoreSupport/WebEditorClient.mm:
(WebEditorClient::checkTextOfParagraph): Use the new StringView::createNSStringWithoutCopying
function instead of a similar function that was local in this file.
(WebEditorClient::ignoreWordInSpellDocument): Tweaked formatting.
(WebEditorClient::checkSpellingOfString): Changed to take a StringView.
(WebEditorClient::checkGrammarOfString): Ditto.

* WebView/WebTextIterator.mm:
(-[WebTextIterator currentTextPointer]): Call TextIterator::deprecatedTextIteratorCharacters.
(-[WebTextIterator currentText]): Convert a the text to an NSString with TextIterator::text
instead of with TextIterator::characters/length.

Source/WebKit/win:

* WebCoreSupport/WebEditorClient.cpp:
(WebEditorClient::checkSpellingOfString): Use StringView.
(WebEditorClient::checkGrammarOfString): Ditto.
* WebCoreSupport/WebEditorClient.h: Ditto.

Source/WebKit/wince:

* WebCoreSupport/EditorClientWinCE.cpp:
(WebKit::EditorClientWinCE::checkSpellingOfString): Use StringView.
(WebKit::EditorClientWinCE::checkGrammarOfString): Ditto.
* WebCoreSupport/EditorClientWinCE.h: Ditto.

Source/WebKit2:

* WebProcess/InjectedBundle/API/mac/WKDOMTextIterator.mm:
(-[WKDOMTextIterator currentTextPointer]): Call TextIterator::deprecatedTextIteratorCharacters.

* WebProcess/WebCoreSupport/WebEditorClient.cpp:
(WebKit::WebEditorClient::checkSpellingOfString): Use StringView.
(WebKit::WebEditorClient::checkGrammarOfString): Ditto.
* WebProcess/WebCoreSupport/WebEditorClient.h: Ditto.

Source/WTF:

* WTF.xcodeproj/project.pbxproj: Added new source files.

* wtf/text/StringView.h: Added operator[], createCFStringWithoutCopying, and
createNSStringWithoutCopying.
* wtf/text/cf/StringViewCF.cpp:
(WTF::StringView::createCFStringWithoutCopying): Added.
* wtf/text/mac/StringViewObjC.mm:
(WTF::StringView::createNSString): Added.
(WTF::StringView::createNSStringWithoutCopying): Added.

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

53 files changed:
Source/WTF/ChangeLog
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/text/StringView.h
Source/WTF/wtf/text/cf/StringViewCF.cpp [new file with mode: 0644]
Source/WTF/wtf/text/mac/StringViewObjC.mm [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/accessibility/AccessibilityNodeObject.cpp
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm
Source/WebCore/bindings/objc/DOMUIKitExtensions.mm
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/PositionIterator.cpp
Source/WebCore/editing/ApplyBlockElementCommand.cpp
Source/WebCore/editing/Editor.cpp
Source/WebCore/editing/IndentOutdentCommand.cpp
Source/WebCore/editing/InsertListCommand.cpp
Source/WebCore/editing/TextCheckingHelper.cpp
Source/WebCore/editing/TextCheckingHelper.h
Source/WebCore/editing/TextIterator.cpp
Source/WebCore/editing/TextIterator.h
Source/WebCore/editing/VisibleSelection.cpp
Source/WebCore/editing/VisibleUnits.cpp
Source/WebCore/editing/markup.cpp
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLTextAreaElement.cpp
Source/WebCore/loader/EmptyClients.h
Source/WebCore/page/Frame.cpp
Source/WebCore/platform/mac/HTMLConverter.mm
Source/WebCore/platform/text/TextBoundaries.cpp
Source/WebCore/platform/text/TextBoundaries.h
Source/WebCore/platform/text/TextCheckerClient.h
Source/WebCore/platform/text/mac/TextBoundaries.mm
Source/WebCore/rendering/RenderTextControl.cpp
Source/WebKit/efl/ChangeLog
Source/WebKit/efl/WebCoreSupport/EditorClientEfl.cpp
Source/WebKit/efl/WebCoreSupport/EditorClientEfl.h
Source/WebKit/gtk/ChangeLog
Source/WebKit/gtk/WebCoreSupport/TextCheckerClientGtk.cpp
Source/WebKit/gtk/WebCoreSupport/TextCheckerClientGtk.h
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/WebCoreSupport/WebEditorClient.h
Source/WebKit/mac/WebCoreSupport/WebEditorClient.mm
Source/WebKit/mac/WebView/WebTextIterator.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebCoreSupport/WebEditorClient.cpp
Source/WebKit/win/WebCoreSupport/WebEditorClient.h
Source/WebKit/wince/ChangeLog
Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.cpp
Source/WebKit/wince/WebCoreSupport/EditorClientWinCE.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/InjectedBundle/API/mac/WKDOMTextIterator.mm
Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebEditorClient.h

index 996402f..d1bc824 100644 (file)
@@ -1,3 +1,20 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * WTF.xcodeproj/project.pbxproj: Added new source files.
+
+        * wtf/text/StringView.h: Added operator[], createCFStringWithoutCopying, and
+        createNSStringWithoutCopying.
+        * wtf/text/cf/StringViewCF.cpp:
+        (WTF::StringView::createCFStringWithoutCopying): Added.
+        * wtf/text/mac/StringViewObjC.mm:
+        (WTF::StringView::createNSString): Added.
+        (WTF::StringView::createNSStringWithoutCopying): Added.
+
 2014-02-06  Andreas Kling  <akling@apple.com>
 
         Remove unused ENABLE(REPAINT_THROTTLING) flag.
index 1c49a01..90913f0 100644 (file)
@@ -71,6 +71,8 @@
                7E29C33E15FFD79B00516D61 /* ObjcRuntimeExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E29C33D15FFD79B00516D61 /* ObjcRuntimeExtras.h */; };
                8134013815B092FD001FF0B8 /* Base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8134013615B092FD001FF0B8 /* Base64.cpp */; };
                8134013915B092FD001FF0B8 /* Base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 8134013715B092FD001FF0B8 /* Base64.h */; };
+               93934BD318A1E8C300D0D6A1 /* StringViewObjC.mm in Sources */ = {isa = PBXBuildFile; fileRef = 93934BD218A1E8C300D0D6A1 /* StringViewObjC.mm */; };
+               93934BD518A1F16900D0D6A1 /* StringViewCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93934BD418A1F16900D0D6A1 /* StringViewCF.cpp */; };
                93AC91A818942FC400244939 /* LChar.h in Headers */ = {isa = PBXBuildFile; fileRef = 93AC91A718942FC400244939 /* LChar.h */; };
                93B1AA80180E5AF3004A2F05 /* PassRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B1AA7F180E5AF3004A2F05 /* PassRef.h */; };
                974CFC8E16A4F327006D5404 /* WeakPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 974CFC8D16A4F327006D5404 /* WeakPtr.h */; };
                7E29C33D15FFD79B00516D61 /* ObjcRuntimeExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ObjcRuntimeExtras.h; sourceTree = "<group>"; };
                8134013615B092FD001FF0B8 /* Base64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Base64.cpp; sourceTree = "<group>"; };
                8134013715B092FD001FF0B8 /* Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64.h; sourceTree = "<group>"; };
+               93934BD218A1E8C300D0D6A1 /* StringViewObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = StringViewObjC.mm; path = mac/StringViewObjC.mm; sourceTree = "<group>"; };
+               93934BD418A1F16900D0D6A1 /* StringViewCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringViewCF.cpp; path = cf/StringViewCF.cpp; sourceTree = "<group>"; };
                93AC91A718942FC400244939 /* LChar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LChar.h; sourceTree = "<group>"; };
                93B1AA7F180E5AF3004A2F05 /* PassRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PassRef.h; sourceTree = "<group>"; };
                974CFC8D16A4F327006D5404 /* WeakPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakPtr.h; sourceTree = "<group>"; };
                A5BA15F11824339F00A82E69 /* mac */ = {
                        isa = PBXGroup;
                        children = (
+                               93934BD218A1E8C300D0D6A1 /* StringViewObjC.mm */,
                                A5BA15F41824348000A82E69 /* StringImplMac.mm */,
                                A5BA15F2182433A900A82E69 /* StringMac.mm */,
                        );
                                A5BA15F7182435A600A82E69 /* AtomicStringCF.cpp */,
                                A5BA15F8182435A600A82E69 /* StringCF.cpp */,
                                A5BA15F9182435A600A82E69 /* StringImplCF.cpp */,
+                               93934BD418A1F16900D0D6A1 /* StringViewCF.cpp */,
                        );
                        name = cf;
                        sourceTree = "<group>";
                                A8A473BC151A825B004123FF /* DynamicAnnotations.cpp in Sources */,
                                A8A473B3151A825B004123FF /* fast-dtoa.cc in Sources */,
                                A8A473C3151A825B004123FF /* FastMalloc.cpp in Sources */,
-                               A5BA15FC182435A600A82E69 /* StringImplCF.cpp in Sources */,
                                A5BA15FA182435A600A82E69 /* AtomicStringCF.cpp in Sources */,
                                E15556F518A0CC18006F48FB /* CryptographicUtilities.cpp in Sources */,
                                0F9D3360165DBA73005AD387 /* FilePrintStream.cpp in Sources */,
                                A8A47400151A825B004123FF /* PageAllocationAligned.cpp in Sources */,
                                A8A47402151A825B004123FF /* PageBlock.cpp in Sources */,
                                0F9D3362165DBA73005AD387 /* PrintStream.cpp in Sources */,
-                               A5BA15F51824348000A82E69 /* StringImplMac.mm in Sources */,
                                143F611F1565F0F900DB514A /* RAMSize.cpp in Sources */,
                                A8A47414151A825B004123FF /* RandomNumber.cpp in Sources */,
                                A8A4741A151A825B004123FF /* RefCountedLeakCounter.cpp in Sources */,
                                2CDED0F318115C85004DBA70 /* RunLoop.cpp in Sources */,
                                2CDED0EF18115C38004DBA70 /* RunLoopCF.cpp in Sources */,
                                1469419316EAAF6D0024E146 /* RunLoopTimerCF.cpp in Sources */,
+                               A8A47421151A825B004123FF /* SHA1.cpp in Sources */,
                                1469419916EAB0410024E146 /* SchedulePairCF.cpp in Sources */,
-                               A5BA15F3182433A900A82E69 /* StringMac.mm in Sources */,
                                1469419716EAAFF80024E146 /* SchedulePairMac.mm in Sources */,
-                               A8A47421151A825B004123FF /* SHA1.cpp in Sources */,
                                A748745217A0BDAE00FA04CB /* SixCharacterHash.cpp in Sources */,
                                A8A47425151A825B004123FF /* SizeLimits.cpp in Sources */,
                                A8A47427151A825B004123FF /* StackBounds.cpp in Sources */,
                                FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */,
                                A8A4743C151A825B004123FF /* StringBuilder.cpp in Sources */,
                                A8A47440151A825B004123FF /* StringImpl.cpp in Sources */,
+                               A5BA15FC182435A600A82E69 /* StringImplCF.cpp in Sources */,
+                               A5BA15F51824348000A82E69 /* StringImplMac.mm in Sources */,
+                               A5BA15F3182433A900A82E69 /* StringMac.mm in Sources */,
                                0FDDBFA71666DFA300C55FEF /* StringPrintStream.cpp in Sources */,
                                A8A47443151A825B004123FF /* StringStatics.cpp in Sources */,
+                               93934BD518A1F16900D0D6A1 /* StringViewCF.cpp in Sources */,
+                               93934BD318A1E8C300D0D6A1 /* StringViewObjC.mm in Sources */,
                                A8A473B7151A825B004123FF /* strtod.cc in Sources */,
                                A8A47431151A825B004123FF /* TCSystemAlloc.cpp in Sources */,
                                A8A47448151A825B004123FF /* ThreadIdentifierDataPthreads.cpp in Sources */,
index 70f4eb0..068989f 100644 (file)
@@ -127,6 +127,25 @@ public:
         return StringImpl::createWithoutCopying(characters16(), length());
     }
 
+    UChar operator[](unsigned index) const
+    {
+        ASSERT(index < length());
+        if (is8Bit())
+            return characters8()[index];
+        return characters16()[index];
+    }
+
+#if USE(CF)
+    // This function converts null strings to empty strings.
+    WTF_EXPORT_STRING_API RetainPtr<CFStringRef> createCFStringWithoutCopying() const;
+#endif
+
+#ifdef __OBJC__
+    // These functions convert null strings to empty strings.
+    WTF_EXPORT_STRING_API RetainPtr<NSString> createNSString() const;
+    WTF_EXPORT_STRING_API RetainPtr<NSString> createNSStringWithoutCopying() const;
+#endif
+
 private:
     void initialize(const LChar* characters, unsigned length)
     {
diff --git a/Source/WTF/wtf/text/cf/StringViewCF.cpp b/Source/WTF/wtf/text/cf/StringViewCF.cpp
new file mode 100644 (file)
index 0000000..3a8f61a
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "StringView.h"
+
+#import "RetainPtr.h"
+
+namespace WTF {
+
+RetainPtr<CFStringRef> StringView::createCFStringWithoutCopying() const
+{
+    if (is8Bit())
+        return adoptCF(CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, characters8(), length(), kCFStringEncodingISOLatin1, false, kCFAllocatorNull));
+
+    return adoptCF(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, characters16(), length(), kCFAllocatorNull));
+}
+
+}
diff --git a/Source/WTF/wtf/text/mac/StringViewObjC.mm b/Source/WTF/wtf/text/mac/StringViewObjC.mm
new file mode 100644 (file)
index 0000000..70cdbb0
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "StringView.h"
+
+#import "RetainPtr.h"
+
+namespace WTF {
+
+RetainPtr<NSString> StringView::createNSString() const
+{
+    if (is8Bit())
+        return adoptNS([[NSString alloc] initWithBytes:const_cast<LChar*>(characters8()) length:length() encoding:NSISOLatin1StringEncoding]);
+
+    return adoptNS([[NSString alloc] initWithCharacters:const_cast<UChar*>(characters16()) length:length()]);
+}
+
+RetainPtr<NSString> StringView::createNSStringWithoutCopying() const
+{
+    if (is8Bit())
+        return adoptNS([[NSString alloc] initWithBytesNoCopy:const_cast<LChar*>(characters8()) length:length() encoding:NSISOLatin1StringEncoding freeWhenDone:NO]);
+
+    return adoptNS([[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(characters16()) length:length() freeWhenDone:NO]);
+}
+
+}
index 45f3fd3..d266595 100644 (file)
@@ -1,3 +1,157 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * accessibility/AccessibilityNodeObject.cpp: Removed unneeded TextIterator.h include.
+
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::hasMisspelling): Updated to use StringView for checkSpelling.
+
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (AXAttributeStringSetSpelling): Changed to take a StringView.
+        (AXAttributedStringAppendText): Ditto.
+        (-[WebAccessibilityObjectWrapper doAXAttributedStringForTextMarkerRange:]): Pass StringView.
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::misspelledWordAtCaretOrRange): Pass StringView.
+        (WebCore::Editor::misspelledSelectionString): Ditto.
+        (WebCore::Editor::markAllMisspellingsAndBadGrammarInRanges): Ditto.
+
+        * editing/TextCheckingHelper.cpp:
+        (WebCore::findGrammaticalErrors): Renamed this function. Changed to use StringView.
+        (WebCore::findMisspellings): Use StringView.
+        (WebCore::TextCheckingHelper::findFirstMisspelling): Ditto. Also separated out assertions
+        that were asserting multiple things with &&.
+        (WebCore::TextCheckingHelper::findFirstMisspellingOrBadGrammar): Ditto.
+        (WebCore::TextCheckingHelper::findFirstGrammarDetail): Ditto.
+        (WebCore::TextCheckingHelper::findFirstBadGrammar): Ditto.
+        (WebCore::TextCheckingHelper::isUngrammatical): Ditto.
+        (WebCore::TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange): Ditto.
+        (WebCore::checkTextOfParagraph): Ditto.
+
+        * editing/TextCheckingHelper.h: Made TextCheckingParagraph::text public. Deleted
+        TextCheckingParagraph::textDeprecatedCharacters. Added comments about additional
+        TextCheckingParagraph refinements. Changed checkTextOfParagraph to take a client
+        reference instead of pointer and StringView instead of characters pointer with length.
+
+        * editing/TextIterator.cpp:
+        (WebCore::TextIterator::appendTextToStringBuilder): Use data members directly,
+        rather than using functions, since we already checked m_textCharacters for null.
+        (WebCore::CharacterIterator::string): Use text() instead of characters().
+        (WebCore::WordAwareIterator::WordAwareIterator): Removed initialization of
+        m_previousText now that it's a StringView rather than a pointer.
+        (WebCore::WordAwareIterator::advance): Use TextIterator::text instead of
+        TextIterator::characters. Also added a FIXME about a fundamental problem
+        with the implementation of this class!
+        (WebCore::WordAwareIterator::length): Updated for m_previousText change.
+        (WebCore::WordAwareIterator::text): Replaced WordAwareIterator::characters with this.
+        (WebCore::SearchBuffer::append): Changed to take a StringView.
+        (WebCore::SearchBuffer::prependContext): Ditto.
+        (WebCore::SearchBuffer::isWordStartMatch): Use StringView.
+        (WebCore::SearchBuffer::search): Ditto.
+        (WebCore::findPlainText): Ditto.
+
+        * editing/TextIterator.h: Added TextIterator::text that returns a StringView, and
+        renamed TextIterator::characters to TextIterator::deprecatedTextIteratorCharacters
+        (easy to search for in source code). Added SimplifiedBackwardsTextIterator::text
+        and removed SimplifiedBackwardsTextIterator::characters. Added CharacterIterator::text,
+        and removed CharacterIterator::characters. Added WordAwareIterator::text and removed
+        WorkdAwareIterator::characters. Changed WordAwareIterator data members to use StringView.
+
+        * editing/VisibleSelection.cpp:
+        (WebCore::VisibleSelection::appendTrailingWhitespace): Use TextIterator::text instead
+        of TextIterator::characters.
+
+        * editing/VisibleUnits.cpp:
+        (WebCore::previousBoundary): Updated to use StringView.
+        (WebCore::nextBoundary): Ditto.
+        (WebCore::startWordBoundary): Ditto.
+        (WebCore::startOfWord): Ditto.
+        (WebCore::endWordBoundary): Ditto.
+        (WebCore::endOfWord): Fixed formatting.
+        (WebCore::previousWordPositionBoundary): Updated to use StringView.
+        (WebCore::previousWordPosition): Fixed formatting and got rid of local variable.
+        (WebCore::nextWordPositionBoundary): Updated to use StringView.
+        (WebCore::nextWordPosition): Fixed formatting and got rid of local variable.
+        (WebCore::inSameLine): Fixed formatting.
+        (WebCore::isStartOfLine): Ditto.
+        (WebCore::isEndOfLine): Ditto.
+        (WebCore::absoluteLineDirectionPointToLocalPointInBlock): Changed to take a reference.
+        (WebCore::previousLinePosition): Fixed formatting chand changed to pass a reference.
+        (WebCore::nextLinePosition): Ditto.
+        (WebCore::startSentenceBoundary): Updated to use StringView and got rid of a local.
+        (WebCore::startOfSentence): Fixed formatting.
+        (WebCore::endSentenceBoundary): Updated to use StringView and got rid of a local.
+        (WebCore::endOfSentence): Fixed formatting.
+        (WebCore::previousSentencePositionBoundary): Updated to use StringView and got rid of
+        a local.
+        (WebCore::previousSentencePosition): Ditto.
+        (WebCore::nextSentencePositionBoundary): Ditto.
+        (WebCore::nextSentencePosition): Fixed formatting.
+        (WebCore::endOfParagraph): Ditto.
+        (WebCore::inSameParagraph): Ditto.
+        (WebCore::isStartOfParagraph): Ditto.
+        (WebCore::isEndOfParagraph): Ditto.
+        (WebCore::inSameBlock): Ditto.
+        (WebCore::isStartOfBlock): Ditto.
+        (WebCore::isEndOfBlock): Ditto.
+        (WebCore::startOfDocument): Ditto.
+        (WebCore::endOfDocument): Ditto.
+        (WebCore::inSameDocument): Ditto.
+        (WebCore::isStartOfDocument): Ditto.
+        (WebCore::isEndOfDocument): Ditto.
+        (WebCore::isEndOfEditableOrNonEditableContent): Ditto.
+
+        * loader/EmptyClients.h: Use StringView.
+
+        * platform/mac/HTMLConverter.mm:
+        (+[WebHTMLConverter editingAttributedStringFromRange:]): Use StringView.
+
+        * platform/text/TextBoundaries.cpp:
+        (WebCore::endOfFirstWordBoundaryContext): Use StringView and unsigned.
+        (WebCore::startOfLastWordBoundaryContext): Ditto.
+
+        * platform/text/TextBoundaries.h: Change interfaces to use StringView,
+        and in some cases, unsigned instead of int. All call sites were better off
+        with unsigned.
+
+        * platform/text/TextCheckerClient.h: Use StringView.
+
+        * platform/text/mac/TextBoundaries.mm: Changed conditionals to say
+        USE(APPKIT) instead of PLATFORM(IOS), since that's the real issue.
+        (WebCore::isSkipCharacter): Tweaked formatting.
+        (WebCore::isWhitespaceCharacter): Ditto.
+        (WebCore::isWordDelimitingCharacter): Ditto, also removed local variable.
+        (WebCore::isSymbolCharacter): Ditto.
+        (WebCore::tokenizerForString): Ditto.
+        (WebCore::findSimpleWordBoundary): Use StringView. Also changed to mostly
+        use unsigned instead of int.
+        (WebCore::findComplexWordBoundary): Use StringView. Also restructured to
+        be much more readable, with early returns and such.
+        (WebCore::findWordBoundary): Use StringView and unsigned.
+        (WebCore::findEndWordBoundary): Removed redudant copy of the findWordBoundary
+        function and changed this to just call findWordBoundary. The reason this
+        function exists is to optimize this case for some non-Mac, non-iOS platforms.
+        We can always do that for Mac and/or iOS later if we like.
+        (WebCore::findNextWordFromIndex): Use StringView. Also use wordBreakIterator
+        instead of using UBreakIterator directly so we get a cached iterator instead
+        of creating and destroying a new one each time this function is called.
+
+        * bindings/objc/DOMUIKitExtensions.mm: Removed unneeded includes.
+        * dom/Element.cpp: Ditto.
+        * dom/PositionIterator.cpp: Ditto.
+        * editing/ApplyBlockElementCommand.cpp: Ditto.
+        * editing/IndentOutdentCommand.cpp: Ditto.
+        * editing/InsertListCommand.cpp: Ditto.
+        * editing/markup.cpp: Ditto.
+        * html/HTMLElement.cpp: Ditto.
+        * html/HTMLTextAreaElement.cpp: Ditto.
+        * page/Frame.cpp: Ditto.
+        * rendering/RenderTextControl.cpp: Ditto.
+
 2014-02-08  Andreas Kling  <akling@apple.com>
 
         Remove two unused function declarations.
index 0cc9e65..66e93fb 100644 (file)
@@ -74,7 +74,6 @@
 #include "SVGNames.h"
 #include "Text.h"
 #include "TextControlInnerElements.h"
-#include "TextIterator.h"
 #include "UserGestureIndicator.h"
 #include "VisibleUnits.h"
 #include "Widget.h"
index 2100cba..8b943ae 100644 (file)
@@ -59,7 +59,6 @@
 #include "Settings.h"
 #include "TextCheckerClient.h"
 #include "TextCheckingHelper.h"
-#include "TextIterator.h"
 #include "UserGestureIndicator.h"
 #include "VisibleUnits.h"
 #include "htmlediting.h"
@@ -330,13 +329,11 @@ bool AccessibilityObject::hasMisspelling() const
     if (!textChecker)
         return false;
     
-    const UChar* chars = stringValue().deprecatedCharacters();
-    int charsLength = stringValue().length();
     bool isMisspelled = false;
 
     if (unifiedTextCheckerEnabled(frame)) {
         Vector<TextCheckingResult> results;
-        checkTextOfParagraph(textChecker, chars, charsLength, TextCheckingTypeSpelling, results);
+        checkTextOfParagraph(*textChecker, stringValue(), TextCheckingTypeSpelling, results);
         if (!results.isEmpty())
             isMisspelled = true;
         return isMisspelled;
@@ -344,7 +341,7 @@ bool AccessibilityObject::hasMisspelling() const
 
     int misspellingLength = 0;
     int misspellingLocation = -1;
-    textChecker->checkSpellingOfString(chars, charsLength, &misspellingLocation, &misspellingLength);
+    textChecker->checkSpellingOfString(stringValue(), &misspellingLocation, &misspellingLength);
     if (misspellingLength || misspellingLocation != -1)
         isMisspelled = true;
     
index 1bffbe7..d6799aa 100644 (file)
@@ -853,7 +853,7 @@ static void AXAttributeStringSetBlockquoteLevel(NSMutableAttributedString* attrS
         [attrString removeAttribute:NSAccessibilityBlockQuoteLevelAttribute range:range];
 }
 
-static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, const UChar* chars, int charLength, NSRange range)
+static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString, Node* node, StringView text, NSRange range)
 {
     if (unifiedTextCheckerEnabled(node->document().frame())) {
         // Check the spelling directly since document->markersForNode() does not store the misspelled marking when the cursor is in a word.
@@ -861,7 +861,7 @@ static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString,
         
         // checkTextOfParagraph is the only spelling/grammar checker implemented in WK1 and WK2
         Vector<TextCheckingResult> results;
-        checkTextOfParagraph(checker, chars, charLength, TextCheckingTypeSpelling, results);
+        checkTextOfParagraph(*checker, text, TextCheckingTypeSpelling, results);
         
         size_t size = results.size();
         NSNumber* trueValue = [NSNumber numberWithBool:YES];
@@ -874,15 +874,11 @@ static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString,
         }
         return;
     }
-    
-    int currentPosition = 0;
-    while (charLength > 0) {
-        const UChar* charData = chars + currentPosition;
-        TextCheckerClient* checker = node->document().frame()->editor().textChecker();
-        
+
+    for (unsigned currentPosition = 0; currentPosition < text.length(); ) {
         int misspellingLocation = -1;
         int misspellingLength = 0;
-        checker->checkSpellingOfString(charData, charLength, &misspellingLocation, &misspellingLength);
+        node->document().frame()->editor().textChecker()->checkSpellingOfString(text.substring(currentPosition), &misspellingLocation, &misspellingLength);
         if (misspellingLocation == -1 || !misspellingLength)
             break;
         
@@ -891,8 +887,8 @@ static void AXAttributeStringSetSpelling(NSMutableAttributedString* attrString,
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
         AXAttributeStringSetNumber(attrString, NSAccessibilityMarkedMisspelledTextAttribute, [NSNumber numberWithBool:YES], spellRange);
 #endif
-        charLength -= (misspellingLocation + misspellingLength);
-        currentPosition += (misspellingLocation + misspellingLength);
+
+        currentPosition += misspellingLocation + misspellingLength;
     }
 }
 
@@ -945,17 +941,17 @@ static void AXAttributeStringSetElement(NSMutableAttributedString* attrString, N
         [attrString removeAttribute:attribute range:range];
 }
 
-static void AXAttributedStringAppendText(NSMutableAttributedString* attrString, Node* node, const UChar* chars, int length)
+static void AXAttributedStringAppendText(NSMutableAttributedString* attrString, Node* node, StringView text)
 {
     // skip invisible text
     if (!node->renderer())
         return;
     
     // easier to calculate the range before appending the string
-    NSRange attrStringRange = NSMakeRange([attrString length], length);
+    NSRange attrStringRange = NSMakeRange([attrString length], text.length());
     
     // append the string from this node
-    [[attrString mutableString] appendString:[NSString stringWithCharacters:chars length:length]];
+    [[attrString mutableString] appendString:text.createNSStringWithoutCopying().get()];
     
     // add new attributes and remove irrelevant inherited ones
     // NOTE: color attributes are handled specially because -[NSMutableAttributedString addAttribute: value: range:] does not merge
@@ -976,7 +972,7 @@ static void AXAttributedStringAppendText(NSMutableAttributedString* attrString,
     AXAttributeStringSetElement(attrString, NSAccessibilityLinkTextAttribute, AccessibilityObject::anchorElementForNode(node), attrStringRange);
     
     // do spelling last because it tends to break up the range
-    AXAttributeStringSetSpelling(attrString, node, chars, length, attrStringRange);
+    AXAttributeStringSetSpelling(attrString, node, text, attrStringRange);
 }
 
 static NSString* nsStringForReplacedNode(Node* replacedNode)
@@ -1028,9 +1024,8 @@ static NSString* nsStringForReplacedNode(Node* replacedNode)
             // Add the text of the list marker item if necessary.
             String listMarkerText = m_object->listMarkerTextForNodeAndPosition(node, VisiblePosition(it.range()->startPosition()));
             if (!listMarkerText.isEmpty())
-                AXAttributedStringAppendText(attrString, node, listMarkerText.deprecatedCharacters(), listMarkerText.length());
-            
-            AXAttributedStringAppendText(attrString, node, it.characters(), it.length());
+                AXAttributedStringAppendText(attrString, node, listMarkerText);
+            AXAttributedStringAppendText(attrString, node, it.text());
         } else {
             Node* replacedNode = node->childNode(offset);
             NSString *attachmentString = nsStringForReplacedNode(replacedNode);
index 0710e81..26e6c89 100644 (file)
@@ -63,7 +63,6 @@
 #import "RenderText.h"
 #import "ResourceBuffer.h"
 #import "SharedBuffer.h"
-#import "TextIterator.h"
 #import "VisiblePosition.h"
 #import "VisibleUnits.h"
 
@@ -87,7 +86,6 @@ using WebCore::RenderObject;
 using WebCore::RenderStyle;
 using WebCore::RenderText;
 using WebCore::RootInlineBox;
-using WebCore::TextIterator;
 using WebCore::VisiblePosition;
 
 @implementation DOMRange (UIKitExtensions)
index fc6c900..5333447 100644 (file)
@@ -73,7 +73,6 @@
 #include "Settings.h"
 #include "StyleProperties.h"
 #include "StyleResolver.h"
-#include "TextIterator.h"
 #include "VoidCallback.h"
 #include "WheelEvent.h"
 #include "XMLNSNames.h"
index 191d77e..97812dd 100644 (file)
@@ -29,7 +29,6 @@
 #include "HTMLNames.h"
 #include "RenderBlock.h"
 #include "RenderText.h"
-#include "TextIterator.h"
 #include "htmlediting.h"
 
 namespace WebCore {
index 2deb1b4..b58d53c 100644 (file)
@@ -32,7 +32,6 @@
 #include "RenderElement.h"
 #include "RenderStyle.h"
 #include "Text.h"
-#include "TextIterator.h"
 #include "VisibleUnits.h"
 #include "htmlediting.h"
 
index bf2188d..fb77098 100644 (file)
@@ -2107,7 +2107,7 @@ String Editor::misspelledWordAtCaretOrRange(Node* clickedNode) const
     int wordLength = word.length();
     int misspellingLocation = -1;
     int misspellingLength = 0;
-    textChecker()->checkSpellingOfString(word.deprecatedCharacters(), wordLength, &misspellingLocation, &misspellingLength);
+    textChecker()->checkSpellingOfString(word, &misspellingLocation, &misspellingLength);
 
     return misspellingLength == wordLength ? word : String();
 }
@@ -2121,7 +2121,7 @@ String Editor::misspelledSelectionString() const
 
     int misspellingLocation = -1;
     int misspellingLength = 0;
-    textChecker()->checkSpellingOfString(selectedString.deprecatedCharacters(), length, &misspellingLocation, &misspellingLength);
+    textChecker()->checkSpellingOfString(selectedString, &misspellingLocation, &misspellingLength);
     
     // The selection only counts as misspelled if the selected text is exactly one misspelled word
     if (misspellingLength != length)
@@ -2423,14 +2423,13 @@ void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textC
     RefPtr<SpellCheckRequest> request = SpellCheckRequest::create(resolveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessIncremental, asynchronous ? paragraphRange : rangeToCheck, paragraphRange);
 
     if (asynchronous) {
-        m_spellChecker->requestCheckingFor(request);
+        m_spellChecker->requestCheckingFor(request.release());
         return;
     }
 
     Vector<TextCheckingResult> results;
-    checkTextOfParagraph(textChecker(), paragraphToCheck.textDeprecatedCharacters(), paragraphToCheck.textLength(),
-        resolveTextCheckingTypeMask(textCheckingOptions), results);
-    markAndReplaceFor(request, results);
+    checkTextOfParagraph(*textChecker(), paragraphToCheck.text(), resolveTextCheckingTypeMask(textCheckingOptions), results);
+    markAndReplaceFor(request.release(), results);
 }
 
 static bool isAutomaticTextReplacementType(TextCheckingType type)
index 63958bb..c233623 100644 (file)
@@ -35,7 +35,6 @@
 #include "RenderObject.h"
 #include "SplitElementCommand.h"
 #include "Text.h"
-#include "TextIterator.h"
 #include "VisibleUnits.h"
 #include "htmlediting.h"
 
index d3ead97..a3b0fa4 100644 (file)
  */
 
 #include "config.h"
+#include "InsertListCommand.h"
+
 #include "Element.h"
 #include "ElementTraversal.h"
-#include "InsertListCommand.h"
 #include "ExceptionCodePlaceholder.h"
 #include "htmlediting.h"
 #include "HTMLElement.h"
 #include "HTMLNames.h"
-#include "TextIterator.h"
+#include "Range.h"
 #include "VisibleUnits.h"
 
 namespace WebCore {
index 0e89cfc..b7dd334 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,61 +43,68 @@ namespace WebCore {
 #if !USE(UNIFIED_TEXT_CHECKING)
 
 #if USE(GRAMMAR_CHECKING)
-static void findBadGrammars(TextCheckerClient* client, const UChar* text, int start, int length, Vector<TextCheckingResult>& results)
-{
-    int checkLocation = start;
-    int checkLength = length;
 
-    while (0 < checkLength) {
+static void findGrammaticalErrors(TextCheckerClient& client, StringView text, Vector<TextCheckingResult>& results)
+{
+    for (unsigned checkLocation = 0; checkLocation < text.length(); ) {
         int badGrammarLocation = -1;
         int badGrammarLength = 0;
         Vector<GrammarDetail> badGrammarDetails;
-        client->checkGrammarOfString(text + checkLocation, checkLength, badGrammarDetails, &badGrammarLocation, &badGrammarLength);
+        client.checkGrammarOfString(text.substring(checkLocation), badGrammarDetails, &badGrammarLocation, &badGrammarLength);
         if (!badGrammarLength)
             break;
-        ASSERT(0 <= badGrammarLocation && badGrammarLocation <= checkLength);
-        ASSERT(0 < badGrammarLength && badGrammarLocation + badGrammarLength <= checkLength);
+
+        ASSERT(badGrammarLocation >= 0);
+        ASSERT(static_cast<unsigned>(badGrammarLocation) <= text.length() - checkLocation);
+        ASSERT(badGrammarLength > 0);
+        ASSERT(static_cast<unsigned>(badGrammarLength) <= text.length() - checkLocation - badGrammarLocation);
+
         TextCheckingResult badGrammar;
         badGrammar.type = TextCheckingTypeGrammar;
         badGrammar.location = checkLocation + badGrammarLocation;
         badGrammar.length = badGrammarLength;
-        badGrammar.details.swap(badGrammarDetails);
+        badGrammar.details = std::move(badGrammarDetails);
         results.append(badGrammar);
 
-        checkLocation += (badGrammarLocation + badGrammarLength);
-        checkLength -= (badGrammarLocation + badGrammarLength);
+        checkLocation += badGrammarLocation + badGrammarLength;
     }
 }
+
 #endif
 
-static void findMisspellings(TextCheckerClient* client, const UChar* text, int length, Vector<TextCheckingResult>& results)
+static void findMisspellings(TextCheckerClient& client, StringView text, Vector<TextCheckingResult>& results)
 {
-    TextBreakIterator* iterator = wordBreakIterator(StringView(text, length));
+    TextBreakIterator* iterator = wordBreakIterator(text);
     if (!iterator)
         return;
-    int wordStart = textBreakCurrent(iterator);
-    while (0 <= wordStart) {
+    for (int wordStart = textBreakCurrent(iterator); wordStart > 0; ) {
         int wordEnd = textBreakNext(iterator);
         if (wordEnd < 0)
             break;
+
         int wordLength = wordEnd - wordStart;
         int misspellingLocation = -1;
         int misspellingLength = 0;
-        client->checkSpellingOfString(text + wordStart, wordLength, &misspellingLocation, &misspellingLength);
-        if (0 < misspellingLength) {
-            ASSERT(0 <= misspellingLocation && misspellingLocation <= wordLength);
-            ASSERT(0 < misspellingLength && misspellingLocation + misspellingLength <= wordLength);
+        client.checkSpellingOfString(text.substring(wordStart, wordLength), &misspellingLocation, &misspellingLength);
+
+        if (misspellingLength > 0) {
+            ASSERT(misspellingLocation >= 0);
+            ASSERT(misspellingLocation <= wordLength);
+            ASSERT(misspellingLength > 0);
+            ASSERT(misspellingLocation + misspellingLength <= wordLength);
+
             TextCheckingResult misspelling;
             misspelling.type = TextCheckingTypeSpelling;
             misspelling.location = wordStart + misspellingLocation;
             misspelling.length = misspellingLength;
-            misspelling.replacement = client->getAutoCorrectSuggestionForMisspelledWord(String(text + misspelling.location, misspelling.length));
+            misspelling.replacement = client.getAutoCorrectSuggestionForMisspelledWord(text.substring(misspelling.location, misspelling.length).toStringWithoutCopying());
             results.append(misspelling);
         }
 
         wordStart = wordEnd;
     }
 }
+
 #endif
 
 static PassRefPtr<Range> expandToParagraphBoundary(PassRefPtr<Range> range)
@@ -234,6 +241,7 @@ TextCheckingHelper::~TextCheckingHelper()
 }
 
 #if !PLATFORM(IOS)
+
 String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, bool markAll, RefPtr<Range>& firstMisspellingRange)
 {
     WordAwareIterator it(m_range.get());
@@ -243,15 +251,14 @@ String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, boo
     int currentChunkOffset = 0;
 
     while (!it.atEnd()) {
-        const UChar* chars = it.characters();
-        int len = it.length();
-        
+        StringView text = it.text();
+        int textLength = text.length();
+
         // Skip some work for one-space-char hunks
-        if (!(len == 1 && chars[0] == ' ')) {
-            
+        if (textLength == 1 && text[0] == ' ') {
             int misspellingLocation = -1;
             int misspellingLength = 0;
-            m_client->textChecker()->checkSpellingOfString(chars, len, &misspellingLocation, &misspellingLength);
+            m_client->textChecker()->checkSpellingOfString(text, &misspellingLocation, &misspellingLength);
 
             // 5490627 shows that there was some code path here where the String constructor below crashes.
             // We don't know exactly what combination of bad input caused this, so we're making this much
@@ -259,19 +266,18 @@ String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, boo
             ASSERT(misspellingLength >= 0);
             ASSERT(misspellingLocation >= -1);
             ASSERT(!misspellingLength || misspellingLocation >= 0);
-            ASSERT(misspellingLocation < len);
-            ASSERT(misspellingLength <= len);
-            ASSERT(misspellingLocation + misspellingLength <= len);
-            
-            if (misspellingLocation >= 0 && misspellingLength > 0 && misspellingLocation < len && misspellingLength <= len && misspellingLocation + misspellingLength <= len) {
-                
+            ASSERT(misspellingLocation < textLength);
+            ASSERT(misspellingLength <= textLength);
+            ASSERT(misspellingLocation + misspellingLength <= textLength);
+
+            if (misspellingLocation >= 0 && misspellingLength > 0 && misspellingLocation < textLength && misspellingLength <= textLength && misspellingLocation + misspellingLength <= textLength) {
                 // Compute range of misspelled word
                 RefPtr<Range> misspellingRange = TextIterator::subrange(m_range.get(), currentChunkOffset + misspellingLocation, misspellingLength);
 
                 // Remember first-encountered misspelling and its offset.
                 if (!firstMisspelling) {
                     firstMisspellingOffset = currentChunkOffset + misspellingLocation;
-                    firstMisspelling = String(chars + misspellingLocation, misspellingLength);
+                    firstMisspelling = text.substring(misspellingLocation, misspellingLength).toString();
                     firstMisspellingRange = misspellingRange;
                 }
 
@@ -284,7 +290,7 @@ String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, boo
             }
         }
         
-        currentChunkOffset += len;
+        currentChunkOffset += textLength;
         it.advance();
     }
     
@@ -345,26 +351,29 @@ String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, b
                 
                 Vector<TextCheckingResult> results;
                 TextCheckingTypeMask checkingTypes = checkGrammar ? (TextCheckingTypeSpelling | TextCheckingTypeGrammar) : TextCheckingTypeSpelling;
-                checkTextOfParagraph(m_client->textChecker(), paragraphString.deprecatedCharacters(), paragraphString.length(), checkingTypes, results);
+                checkTextOfParagraph(*m_client->textChecker(), paragraphString, checkingTypes, results);
                 
                 for (unsigned i = 0; i < results.size(); i++) {
                     const TextCheckingResult* result = &results[i];
                     if (result->type == TextCheckingTypeSpelling && result->location >= currentStartOffset && result->location + result->length <= currentEndOffset) {
-                        ASSERT(result->length > 0 && result->location >= 0);
+                        ASSERT(result->length > 0);
+                        ASSERT(result->location >= 0);
                         spellingLocation = result->location;
                         misspelledWord = paragraphString.substring(result->location, result->length);
                         ASSERT(misspelledWord.length());
                         break;
                     }
                     if (checkGrammar && result->type == TextCheckingTypeGrammar && result->location < currentEndOffset && result->location + result->length > currentStartOffset) {
-                        ASSERT(result->length > 0 && result->location >= 0);
+                        ASSERT(result->length > 0);
+                        ASSERT(result->location >= 0);
                         // We can't stop after the first grammar result, since there might still be a spelling result after
                         // it begins but before the first detail in it, but we can stop if we find a second grammar result.
                         if (foundGrammar)
                             break;
                         for (unsigned j = 0; j < result->details.size(); j++) {
                             const GrammarDetail* detail = &result->details[j];
-                            ASSERT(detail->length > 0 && detail->location >= 0);
+                            ASSERT(detail->length > 0);
+                            ASSERT(detail->location >= 0);
                             if (result->location + detail->location >= currentStartOffset && result->location + detail->location + detail->length <= currentEndOffset && (!foundGrammar || result->location + detail->location < grammarDetailLocation)) {
                                 grammarDetailIndex = j;
                                 grammarDetailLocation = result->location + detail->location;
@@ -414,9 +423,11 @@ String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, b
     }
     return firstFoundItem;
 }
+
 #endif // !PLATFORM(IOS)
 
 #if USE(GRAMMAR_CHECKING)
+
 int TextCheckingHelper::findFirstGrammarDetail(const Vector<GrammarDetail>& grammarDetails, int badGrammarPhraseLocation, int startOffset, int endOffset, bool markAll) const
 {
     // Found some bad grammar. Find the earliest detail range that starts in our search range (if any).
@@ -425,7 +436,8 @@ int TextCheckingHelper::findFirstGrammarDetail(const Vector<GrammarDetail>& gram
     int earliestDetailIndex = -1;
     for (unsigned i = 0; i < grammarDetails.size(); i++) {
         const GrammarDetail* detail = &grammarDetails[i];
-        ASSERT(detail->length > 0 && detail->location >= 0);
+        ASSERT(detail->length > 0);
+        ASSERT(detail->location >= 0);
         
         int detailStartOffsetInParagraph = badGrammarPhraseLocation + detail->location;
         
@@ -469,12 +481,11 @@ String TextCheckingHelper::findFirstBadGrammar(GrammarDetail& outGrammarDetail,
     TextCheckingParagraph paragraph(m_range);
     
     // Start checking from beginning of paragraph, but skip past results that occur before the start of the original search range.
-    int startOffset = 0;
-    while (startOffset < paragraph.checkingEnd()) {
+    for (int startOffset = 0; startOffset < paragraph.checkingEnd(); ) {
         Vector<GrammarDetail> grammarDetails;
         int badGrammarPhraseLocation = -1;
         int badGrammarPhraseLength = 0;
-        m_client->textChecker()->checkGrammarOfString(paragraph.textDeprecatedCharacters() + startOffset, paragraph.textLength() - startOffset, grammarDetails, &badGrammarPhraseLocation, &badGrammarPhraseLength);
+        m_client->textChecker()->checkGrammarOfString(StringView(paragraph.text()).substring(startOffset), grammarDetails, &badGrammarPhraseLocation, &badGrammarPhraseLength);
         
         if (!badGrammarPhraseLength) {
             ASSERT(badGrammarPhraseLocation == -1);
@@ -484,7 +495,6 @@ String TextCheckingHelper::findFirstBadGrammar(GrammarDetail& outGrammarDetail,
         ASSERT(badGrammarPhraseLocation >= 0);
         badGrammarPhraseLocation += startOffset;
 
-        
         // Found some bad grammar. Find the earliest detail range that starts in our search range (if any).
         int badGrammarIndex = findFirstGrammarDetail(grammarDetails, badGrammarPhraseLocation, paragraph.checkingStart(), paragraph.checkingEnd(), markAll);
         if (badGrammarIndex >= 0) {
@@ -511,7 +521,6 @@ String TextCheckingHelper::findFirstBadGrammar(GrammarDetail& outGrammarDetail,
     return firstBadGrammarPhrase;
 }
 
-
 bool TextCheckingHelper::isUngrammatical() const
 {
     if (!m_client)
@@ -535,9 +544,10 @@ bool TextCheckingHelper::isUngrammatical() const
     // Bad grammar, but phrase (e.g. sentence) starts beyond start of range.
     if (grammarPhraseOffset > 0)
         return false;
-    
-    ASSERT(grammarDetail.location >= 0 && grammarDetail.length > 0);
-    
+
+    ASSERT(grammarDetail.location >= 0);
+    ASSERT(grammarDetail.length > 0);
+
     // Bad grammar, but start of detail (e.g. ungrammatical word) doesn't match start of range
     if (grammarDetail.location + grammarPhraseOffset)
         return false;
@@ -554,7 +564,8 @@ bool TextCheckingHelper::isUngrammatical() const
     
     return true;
 }
-#endif
+
+#endif // USE(GRAMMAR_CHECKING)
 
 Vector<String> TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange(bool checkGrammar, bool& misspelled, bool& ungrammatical) const
 {
@@ -575,7 +586,7 @@ Vector<String> TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange(bool
 
     Vector<TextCheckingResult> results;
     TextCheckingTypeMask checkingTypes = checkGrammar ? (TextCheckingTypeSpelling | TextCheckingTypeGrammar) : TextCheckingTypeSpelling;
-    checkTextOfParagraph(m_client->textChecker(), paragraph.textDeprecatedCharacters(), paragraph.textLength(), checkingTypes, results);
+    checkTextOfParagraph(*m_client->textChecker(), paragraph.text(), checkingTypes, results);
     
     for (unsigned i = 0; i < results.size(); i++) {
         const TextCheckingResult* result = &results[i];
@@ -597,7 +608,8 @@ Vector<String> TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange(bool
         if (result->type == TextCheckingTypeGrammar && paragraph.isCheckingRangeCoveredBy(result->location, result->length)) {
             for (unsigned j = 0; j < result->details.size(); j++) {
                 const GrammarDetail* detail = &result->details[j];
-                ASSERT(detail->length > 0 && detail->location >= 0);
+                ASSERT(detail->length > 0);
+                ASSERT(detail->location >= 0);
                 if (paragraph.checkingRangeMatches(result->location + detail->location, detail->length)) {
                     String badGrammarPhrase = paragraph.textSubstring(result->location, result->length);
                     ASSERT(badGrammarPhrase.length());
@@ -613,8 +625,8 @@ Vector<String> TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange(bool
     return guesses;
 }
 
-
 #if !PLATFORM(IOS)
+
 void TextCheckingHelper::markAllMisspellings(RefPtr<Range>& firstMisspellingRange)
 {
     // Use the "markAll" feature of findFirstMisspelling. Ignore the return value and the "out parameter";
@@ -633,6 +645,7 @@ void TextCheckingHelper::markAllBadGrammar()
     findFirstBadGrammar(ignoredGrammarDetail, ignoredOffset, true);
 }
 #endif
+
 #endif // !PLATFORM(IOS)
 
 bool TextCheckingHelper::unifiedTextCheckerEnabled() const
@@ -640,40 +653,33 @@ bool TextCheckingHelper::unifiedTextCheckerEnabled() const
     return m_range && WebCore::unifiedTextCheckerEnabled(m_range->ownerDocument().frame());
 }
 
-void checkTextOfParagraph(TextCheckerClient* client, const UChar* text, int length,
-                          TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results)
+void checkTextOfParagraph(TextCheckerClient& client, StringView text, TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results)
 {
 #if USE(UNIFIED_TEXT_CHECKING)
-    results = client->checkTextOfParagraph(StringView(text, length), checkingTypes);
+    results = client.checkTextOfParagraph(text, checkingTypes);
 #else
-    Vector<TextCheckingResult> spellingResult;
+    Vector<TextCheckingResult> mispellings;
     if (checkingTypes & TextCheckingTypeSpelling)
-        findMisspellings(client, text, length, spellingResult);
+        findMisspellings(client, text, mispellings);
 
 #if USE(GRAMMAR_CHECKING)
-    Vector<TextCheckingResult> grammarResult;
+    // Look for grammatical errors that occur before the first misspelling.
+    Vector<TextCheckingResult> grammaticalErrors;
     if (checkingTypes & TextCheckingTypeGrammar) {
-        // Only checks grammartical error before the first misspellings
-        int grammarCheckLength = length;
-        for (size_t i = 0; i < spellingResult.size(); ++i) {
-            if (spellingResult[i].location < grammarCheckLength)
-                grammarCheckLength = spellingResult[i].location;
-        }
-
-        findBadGrammars(client, text, 0, grammarCheckLength, grammarResult);
+        unsigned grammarCheckLength = text.length();
+        for (auto& mispelling : mispellings)
+            grammarCheckLength = std::min<unsigned>(grammarCheckLength, mispelling.location);
+        findGrammaticalErrors(client, text.substring(0, grammarCheckLength), grammaticalErrors);
     }
 
-    if (grammarResult.size())
-        results.swap(grammarResult);
+    results = std::move(grammaticalErrors);
 #endif
 
-    if (spellingResult.size()) {
-        if (results.isEmpty())
-            results.swap(spellingResult);
-        else
-            results.appendVector(spellingResult);
-    }
-#endif
+    if (results.isEmpty())
+        results = std::move(mispellings);
+    else
+        results.appendVector(mispellings);
+#endif // USE(UNIFIED_TEXT_CHECKING)
 }
 
 bool unifiedTextCheckerEnabled(const Frame* frame)
index a90c9c8..246d256 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * This library is free software; you can redistribute it and/or
@@ -43,13 +43,16 @@ public:
     int offsetTo(const Position&, ExceptionCode&) const;
     void expandRangeToNextEnd();
 
+    // FIXME: Consider changing this to return a StringView.
+    const String& text() const;
+
+    // FIXME: Consider removing these and just having the caller use text() directly.
     int textLength() const { return text().length(); }
     String textSubstring(unsigned pos, unsigned len = UINT_MAX) const { return text().substring(pos, len); }
-    const UChar* textDeprecatedCharacters() const { return text().deprecatedCharacters(); }
     UChar textCharAt(int index) const { return text()[static_cast<unsigned>(index)]; }
+    bool isTextEmpty() const { return text().isEmpty(); }
 
     bool isEmpty() const;
-    bool isTextEmpty() const { return text().isEmpty(); }
     bool isRangeEmpty() const { return checkingStart() >= checkingEnd(); }
 
     int checkingStart() const;
@@ -66,7 +69,6 @@ private:
     void invalidateParagraphRangeValues();
     PassRefPtr<Range> checkingRange() const { return m_checkingRange; }
     PassRefPtr<Range> offsetAsRange() const;
-    const String& text() const;
 
     RefPtr<Range> m_checkingRange;
     mutable RefPtr<Range> m_paragraphRange;
@@ -103,8 +105,7 @@ private:
 #endif
 };
 
-void checkTextOfParagraph(TextCheckerClient*, const UChar* text, int length,
-    TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results);
+void checkTextOfParagraph(TextCheckerClient&, StringView, TextCheckingTypeMask, Vector<TextCheckingResult>&);
 
 bool unifiedTextCheckerEnabled(const Frame*);
 
index 1e40780..1e63184 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2014 Apple Inc. All rights reserved.
  * Copyright (C) 2005 Alexey Proskuryakov.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -76,9 +76,9 @@ public:
     ~SearchBuffer();
 
     // Returns number of characters appended; guaranteed to be in the range [1, length].
-    size_t append(const UChar*, size_t length);
+    size_t append(StringView);
     bool needsMoreContext() const;
-    void prependContext(const UChar*, size_t length);
+    void prependContext(StringView);
     void reachedBreak();
 
     // Result is the size in characters of what was found.
@@ -480,7 +480,7 @@ UChar TextIterator::characterAt(unsigned index) const
         return 0;
 
     if (!m_textCharacters)
-        return string()[startOffset() + index];
+        return m_text[m_positionStartOffset + index];
 
     return m_textCharacters[index];
 }
@@ -488,9 +488,9 @@ UChar TextIterator::characterAt(unsigned index) const
 void TextIterator::appendTextToStringBuilder(StringBuilder& builder) const
 {
     if (!m_textCharacters)
-        builder.append(string(), startOffset(), length());
+        builder.append(m_text, m_positionStartOffset, m_textLength);
     else
-        builder.append(characters(), length());
+        builder.append(m_textCharacters, m_textLength);
 }
 
 bool TextIterator::handleTextNode()
@@ -1484,13 +1484,22 @@ void CharacterIterator::advance(int count)
     m_runOffset = 0;
 }
 
+static void append(Vector<UChar>& buffer, StringView string)
+{
+    unsigned oldSize = buffer.size();
+    unsigned length = string.length();
+    buffer.grow(oldSize + length);
+    for (unsigned i = 0; i < length; ++i)
+        buffer[oldSize + i] = string[i];
+}
+
 String CharacterIterator::string(int numChars)
 {
     Vector<UChar> result;
     result.reserveInitialCapacity(numChars);
     while (numChars > 0 && !atEnd()) {
         int runSize = std::min(numChars, length());
-        result.append(characters(), runSize);
+        append(result, text().substring(0, runSize));
         numChars -= runSize;
         advance(runSize);
     }
@@ -1580,8 +1589,7 @@ void BackwardsCharacterIterator::advance(int count)
 // --------
 
 WordAwareIterator::WordAwareIterator(const Range* r)
-    : m_previousText(0)
-    , m_didLookAhead(true) // so we consider the first chunk from the text iterator
+    : m_didLookAhead(true) // so we consider the first chunk from the text iterator
     , m_textIterator(r)
 {
     advance(); // get in position over the first chunk of text
@@ -1602,7 +1610,7 @@ WordAwareIterator::~WordAwareIterator()
 
 void WordAwareIterator::advance()
 {
-    m_previousText = 0;
+    m_previousText = StringView();
     m_buffer.clear();      // toss any old buffer we built up
 
     // If last time we did a look-ahead, start with that looked-ahead chunk now
@@ -1622,30 +1630,32 @@ void WordAwareIterator::advance()
     
     while (1) {
         // If this chunk ends in whitespace we can just use it as our chunk.
-        if (isSpaceOrNewline(m_textIterator.characters()[m_textIterator.length() - 1]))
+        if (isSpaceOrNewline(m_textIterator.text()[m_textIterator.length() - 1]))
             return;
 
         // If this is the first chunk that failed, save it in previousText before look ahead
         if (m_buffer.isEmpty()) {
-            m_previousText = m_textIterator.characters();
-            m_previousLength = m_textIterator.length();
+            // FIXME: It's not safe to keep a StringView alive to the previous text once the
+            // TextIterator advances. In cases where the TextIterator synthesizes a character,
+            // the pointer is no longer valid once we call advance. To fix this, we might need
+            // to add a new function to TextIterator to handle those cases.
+            m_previousText = m_textIterator.text();
         }
 
         // Look ahead to next chunk.  If it is whitespace or a break, we can use the previous stuff
         m_textIterator.advance();
-        if (m_textIterator.atEnd() || m_textIterator.length() == 0 || isSpaceOrNewline(m_textIterator.characters()[0])) {
+        if (m_textIterator.atEnd() || !m_textIterator.length() || isSpaceOrNewline(m_textIterator.text()[0])) {
             m_didLookAhead = true;
             return;
         }
 
         if (m_buffer.isEmpty()) {
             // Start gobbling chunks until we get to a suitable stopping point
-            m_buffer.append(m_previousText, m_previousLength);
-            m_previousText = 0;
+            append(m_buffer, m_previousText);
+            m_previousText = StringView();
         }
-        m_buffer.append(m_textIterator.characters(), m_textIterator.length());
-        int exception = 0;
-        m_range->setEnd(m_textIterator.range()->endContainer(), m_textIterator.range()->endOffset(), exception);
+        append(m_buffer, m_textIterator.text());
+        m_range->setEnd(m_textIterator.range()->endContainer(), m_textIterator.range()->endOffset());
     }
 }
 
@@ -1654,17 +1664,17 @@ int WordAwareIterator::length() const
     if (!m_buffer.isEmpty())
         return m_buffer.size();
     if (m_previousText)
-        return m_previousLength;
+        return m_previousText.length();
     return m_textIterator.length();
 }
 
-const UChar* WordAwareIterator::characters() const
+StringView WordAwareIterator::text() const
 {
     if (!m_buffer.isEmpty())
-        return m_buffer.data();
+        return StringView(m_buffer.data(), m_buffer.size());
     if (m_previousText)
         return m_previousText;
-    return m_textIterator.characters();
+    return m_textIterator.text();
 }
 
 // --------
@@ -2062,9 +2072,9 @@ inline SearchBuffer::~SearchBuffer()
     unlockSearcher();
 }
 
-inline size_t SearchBuffer::append(const UChar* characters, size_t length)
+inline size_t SearchBuffer::append(StringView text)
 {
-    ASSERT(length);
+    ASSERT(text.length());
 
     if (m_atBreak) {
         m_buffer.shrink(0);
@@ -2077,9 +2087,11 @@ inline size_t SearchBuffer::append(const UChar* characters, size_t length)
     }
 
     size_t oldLength = m_buffer.size();
-    size_t usableLength = std::min(m_buffer.capacity() - oldLength, length);
+    size_t usableLength = std::min<size_t>(m_buffer.capacity() - oldLength, text.length());
     ASSERT(usableLength);
-    m_buffer.append(characters, usableLength);
+    m_buffer.grow(oldLength + usableLength);
+    for (unsigned i = 0; i < usableLength; ++i)
+        m_buffer[oldLength + i] = text[i];
     foldQuoteMarksAndSoftHyphens(m_buffer.data() + oldLength, usableLength);
     return usableLength;
 }
@@ -2089,24 +2101,24 @@ inline bool SearchBuffer::needsMoreContext() const
     return m_needsMoreContext;
 }
 
-inline void SearchBuffer::prependContext(const UChar* characters, size_t length)
+inline void SearchBuffer::prependContext(StringView text)
 {
     ASSERT(m_needsMoreContext);
     ASSERT(m_prefixLength == m_buffer.size());
 
-    if (!length)
+    if (!text.length())
         return;
 
     m_atBreak = false;
 
-    size_t wordBoundaryContextStart = length;
+    size_t wordBoundaryContextStart = text.length();
     if (wordBoundaryContextStart) {
-        U16_BACK_1(characters, 0, wordBoundaryContextStart);
-        wordBoundaryContextStart = startOfLastWordBoundaryContext(characters, wordBoundaryContextStart);
+        U16_BACK_1(text, 0, wordBoundaryContextStart);
+        wordBoundaryContextStart = startOfLastWordBoundaryContext(text.substring(0, wordBoundaryContextStart));
     }
 
-    size_t usableLength = std::min(m_buffer.capacity() - m_prefixLength, length - wordBoundaryContextStart);
-    m_buffer.insert(0, characters + length - usableLength, usableLength);
+    size_t usableLength = std::min(m_buffer.capacity() - m_prefixLength, text.length() - wordBoundaryContextStart);
+    WebCore::append(m_buffer, text.substring(text.length() - usableLength, usableLength));
     m_prefixLength += usableLength;
 
     if (wordBoundaryContextStart || m_prefixLength == m_buffer.capacity())
@@ -2234,7 +2246,7 @@ inline bool SearchBuffer::isWordStartMatch(size_t start, size_t length) const
 
     size_t wordBreakSearchStart = start + length;
     while (wordBreakSearchStart > start)
-        wordBreakSearchStart = findNextWordFromIndex(m_buffer.data(), m_buffer.size(), wordBreakSearchStart, false /* backwards */);
+        wordBreakSearchStart = findNextWordFromIndex(StringView(m_buffer.data(), m_buffer.size()), wordBreakSearchStart, false /* backwards */);
     return wordBreakSearchStart == start;
 }
 
@@ -2275,9 +2287,9 @@ nextMatch:
         if (m_options & AtWordStarts) {
             // Ensure that there is sufficient context before matchStart the next time around for
             // determining if it is at a word boundary.
-            int wordBoundaryContextStart = matchStart;
+            unsigned wordBoundaryContextStart = matchStart;
             U16_BACK_1(m_buffer.data(), 0, wordBoundaryContextStart);
-            wordBoundaryContextStart = startOfLastWordBoundaryContext(m_buffer.data(), wordBoundaryContextStart);
+            wordBoundaryContextStart = startOfLastWordBoundaryContext(StringView(m_buffer.data(), wordBoundaryContextStart));
             overlap = std::min(size - 1, std::max(overlap, size - wordBoundaryContextStart));
         }
         memcpy(m_buffer.data(), m_buffer.data() + size - overlap, overlap * sizeof(UChar));
@@ -2601,14 +2613,14 @@ static size_t findPlainText(CharacterIterator& it, const String& target, FindOpt
         RefPtr<Range> beforeStartRange = startRange->ownerDocument().createRange();
         beforeStartRange->setEnd(startRange->startContainer(), startRange->startOffset(), IGNORE_EXCEPTION);
         for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) {
-            buffer.prependContext(backwardsIterator.characters(), backwardsIterator.length());
+            buffer.prependContext(backwardsIterator.text());
             if (!buffer.needsMoreContext())
                 break;
         }
     }
 
     while (!it.atEnd()) {
-        it.advance(buffer.append(it.characters(), it.length()));
+        it.advance(buffer.append(it.text()));
 tryAgain:
         size_t matchStartOffset;
         if (size_t newMatchLength = buffer.search(matchStartOffset)) {
index 8b8919f..c4a2c4f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2006, 2009, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #include "FindOptions.h"
 #include "Range.h"
 #include <wtf/Vector.h>
+#include <wtf/text/StringView.h>
 
 namespace WebCore {
 
@@ -93,8 +94,11 @@ public:
     bool atEnd() const { return !m_positionNode || m_shouldStop; }
     void advance();
     
+    StringView text() const { return m_textCharacters ? StringView(m_textCharacters, m_textLength) : StringView(m_text).substring(m_positionStartOffset, m_textLength); }
     int length() const { return m_textLength; }
-    const UChar* characters() const { return m_textCharacters ? m_textCharacters : m_text.deprecatedCharacters() + startOffset(); }
+
+    const UChar* deprecatedTextIteratorCharacters() const { return m_textCharacters ? m_textCharacters : m_text.deprecatedCharacters() + m_positionStartOffset; }
+
     UChar characterAt(unsigned index) const;
     void appendTextToStringBuilder(StringBuilder&) const;
     
@@ -107,8 +111,6 @@ public:
     static PassRefPtr<Range> subrange(Range* entireRange, int characterOffset, int characterCount);
     
 private:
-    int startOffset() const { return m_positionStartOffset; }
-    const String& string() const { return m_text; }
     void exitNode();
     bool shouldRepresentNodeOffsetZero();
     bool shouldEmitSpaceBeforeAndAfterNode(Node*);
@@ -209,9 +211,10 @@ public:
     void advance();
 
     Node* node() const { return m_node; }
+
+    StringView text() const { return StringView(m_textCharacters, m_textLength); }
     int length() const { return m_textLength; }
-    const UChar* characters() const { return m_textCharacters; }
-    
+
     PassRefPtr<Range> range() const;
         
 private:
@@ -279,13 +282,14 @@ public:
     bool atBreak() const { return m_atBreak; }
     bool atEnd() const { return m_textIterator.atEnd(); }
     
+    StringView text() const { return m_textIterator.text().substring(m_runOffset); }
     int length() const { return m_textIterator.length() - m_runOffset; }
-    const UChar* characters() const { return m_textIterator.characters() + m_runOffset; }
-    String string(int numChars);
+
+    String string(int numCharacters);
     
     int characterOffset() const { return m_offset; }
     PassRefPtr<Range> range() const;
-        
+
 private:
     int m_offset;
     int m_runOffset;
@@ -323,20 +327,18 @@ public:
     void advance();
     
     int length() const;
-    const UChar* characters() const;
-    
-    // Range of the text we're currently returning
+
+    StringView text() const;
     PassRefPtr<Range> range() const { return m_range; }
 
 private:
-    // text from the previous chunk from the textIterator
-    const UChar* m_previousText;
-    int m_previousLength;
+    // Text from the previous chunk from the text iterator.
+    StringView m_previousText;
 
-    // many chunks from textIterator concatenated
+    // Many chunks from text iterator concatenated.
     Vector<UChar> m_buffer;
     
-    // Did we have to look ahead in the textIterator to confirm the current chunk?
+    // Did we have to look ahead in the text iterator to confirm the current chunk?
     bool m_didLookAhead;
 
     RefPtr<Range> m_range;
index 445eb9b..900b698 100644 (file)
@@ -237,7 +237,7 @@ void VisibleSelection::appendTrailingWhitespace()
     CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
 
     for (; charIt.length(); charIt.advance(1)) {
-        UChar c = charIt.characters()[0];
+        UChar c = charIt.text()[0];
         if ((!isSpaceOrNewline(c) && c != noBreakSpace) || c == '\n')
             break;
         m_end = charIt.range()->endPosition();
index d81355a..bfa31f9 100644 (file)
@@ -55,13 +55,13 @@ static Node* previousLeafWithSameEditability(Node* node, EditableType editableTy
             return node;
         node = previousLeafNode(node);
     }
-    return 0;
+    return nullptr;
 }
 
 static Node* nextLeafWithSameEditability(Node* node, EditableType editableType = ContentIsEditable)
 {
     if (!node)
-        return 0;
+        return nullptr;
     
     bool editable = node->hasEditableStyle(editableType);
     node = nextLeafNode(node);
@@ -70,7 +70,7 @@ static Node* nextLeafWithSameEditability(Node* node, EditableType editableType =
             return node;
         node = nextLeafNode(node);
     }
-    return 0;
+    return nullptr;
 }
 
 // FIXME: consolidate with code in previousLinePosition.
@@ -142,7 +142,7 @@ CachedLogicallyOrderedLeafBoxes::CachedLogicallyOrderedLeafBoxes() : m_rootInlin
 const InlineBox* CachedLogicallyOrderedLeafBoxes::previousTextOrLineBreakBox(const RootInlineBox* root, const InlineTextBox* box)
 {
     if (!root)
-        return 0;
+        return nullptr;
 
     collectBoxes(root);
 
@@ -157,13 +157,13 @@ const InlineBox* CachedLogicallyOrderedLeafBoxes::previousTextOrLineBreakBox(con
             return box;
     }
 
-    return 0;
+    return nullptr;
 }
 
 const InlineBox* CachedLogicallyOrderedLeafBoxes::nextTextOrLineBreakBox(const RootInlineBox* root, const InlineTextBox* box)
 {
     if (!root)
-        return 0;
+        return nullptr;
 
     collectBoxes(root);
 
@@ -179,7 +179,7 @@ const InlineBox* CachedLogicallyOrderedLeafBoxes::nextTextOrLineBreakBox(const R
             return box;
     }
 
-    return 0;
+    return nullptr;
 }
 
 const Vector<InlineBox*>& CachedLogicallyOrderedLeafBoxes::collectBoxes(const RootInlineBox* root)
@@ -444,7 +444,43 @@ VisiblePosition rightWordPosition(const VisiblePosition& visiblePosition, bool s
 
 enum BoundarySearchContextAvailability { DontHaveMoreContext, MayHaveMoreContext };
 
-typedef unsigned (*BoundarySearchFunction)(const UChar*, unsigned length, unsigned offset, BoundarySearchContextAvailability, bool& needMoreContext);
+typedef unsigned (*BoundarySearchFunction)(StringView, unsigned offset, BoundarySearchContextAvailability, bool& needMoreContext);
+
+static void prepend(Vector<UChar, 1024>& buffer, StringView string)
+{
+    unsigned oldSize = buffer.size();
+    unsigned length = string.length();
+    buffer.grow(oldSize + length);
+    memmove(buffer.data() + length, buffer.data(), oldSize * sizeof(UChar));
+    for (unsigned i = 0; i < length; ++i)
+        buffer[i] = string[i];
+}
+
+static void prependRepeatedCharacter(Vector<UChar, 1024>& buffer, UChar character, unsigned count)
+{
+    unsigned oldSize = buffer.size();
+    buffer.grow(oldSize + count);
+    memmove(buffer.data() + count, buffer.data(), oldSize * sizeof(UChar));
+    for (unsigned i = 0; i < count; ++i)
+        buffer[i] = character;
+}
+
+static void append(Vector<UChar, 1024>& buffer, StringView string)
+{
+    unsigned oldSize = buffer.size();
+    unsigned length = string.length();
+    buffer.grow(oldSize + length);
+    for (unsigned i = 0; i < length; ++i)
+        buffer[oldSize + i] = string[i];
+}
+
+static void appendRepeatedCharacter(Vector<UChar, 1024>& buffer, UChar character, unsigned count)
+{
+    unsigned oldSize = buffer.size();
+    buffer.grow(oldSize + count);
+    for (unsigned i = 0; i < count; ++i)
+        buffer[oldSize + i] = character;
+}
 
 static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearchFunction searchFunction)
 {
@@ -468,12 +504,11 @@ static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch
         forwardsScanRange->setStart(end.deprecatedNode(), end.deprecatedEditingOffset(), ec);
         TextIterator forwardsIterator(forwardsScanRange.get());
         while (!forwardsIterator.atEnd()) {
-            const UChar* characters = forwardsIterator.characters();
-            int length = forwardsIterator.length();
-            int i = endOfFirstWordBoundaryContext(characters, length);
-            string.append(characters, i);
+            StringView text = forwardsIterator.text();
+            unsigned i = endOfFirstWordBoundaryContext(text);
+            append(string, text.substring(0, i));
             suffixLength += i;
-            if (i < length)
+            if (i < text.length())
                 break;
             forwardsIterator.advance();
         }
@@ -493,26 +528,22 @@ static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch
         bool inTextSecurityMode = it.node() && it.node()->renderer() && it.node()->renderer()->style().textSecurity() != TSNONE;
         // iterate to get chunks until the searchFunction returns a non-zero value.
         if (!inTextSecurityMode) 
-            string.insert(0, it.characters(), it.length());
+            prepend(string, it.text());
         else {
             // Treat bullets used in the text security mode as regular characters when looking for boundaries
-            String iteratorString(it.characters(), it.length());
-#if PLATFORM(IOS)
-            iteratorString = iteratorString.impl()->fill('x');
-#else
-            iteratorString.fill('x');
-#endif
-            string.insert(0, iteratorString.deprecatedCharacters(), iteratorString.length());
+            prependRepeatedCharacter(string, 'x', it.length());
+        }
+        if (string.size() > suffixLength) {
+            next = searchFunction(StringView(string.data(), string.size()), string.size() - suffixLength, MayHaveMoreContext, needMoreContext);
+            if (next > 1) // FIXME: This is a work around for https://webkit.org/b/115070. We need to provide more contexts in general case.
+                break;
         }
-        next = searchFunction(string.data(), string.size(), string.size() - suffixLength, MayHaveMoreContext, needMoreContext);
-        if (next > 1) // FIXME: This is a work around for https://webkit.org/b/115070. We need to provide more contexts in general case.
-            break;
         it.advance();
     }
-    if (needMoreContext) {
+    if (needMoreContext && string.size() > suffixLength) {
         // The last search returned the beginning of the buffer and asked for more context,
         // but there is no earlier text. Force a search with what's available.
-        next = searchFunction(string.data(), string.size(), string.size() - suffixLength, DontHaveMoreContext, needMoreContext);
+        next = searchFunction(StringView(string.data(), string.size()), string.size() - suffixLength, DontHaveMoreContext, needMoreContext);
         ASSERT(!needMoreContext);
     }
 
@@ -550,11 +581,10 @@ static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
         backwardsScanRange->setEnd(start.deprecatedNode(), start.deprecatedEditingOffset(), IGNORE_EXCEPTION);
         SimplifiedBackwardsTextIterator backwardsIterator(backwardsScanRange.get());
         while (!backwardsIterator.atEnd()) {
-            const UChar* characters = backwardsIterator.characters();
-            int length = backwardsIterator.length();
-            int i = startOfLastWordBoundaryContext(characters, length);
-            string.insert(0, characters + i, length - i);
-            prefixLength += length - i;
+            StringView text = backwardsIterator.text();
+            int i = startOfLastWordBoundaryContext(text);
+            prepend(string, text.substring(i));
+            prefixLength += text.length() - i;
             if (i > 0)
                 break;
             backwardsIterator.advance();
@@ -571,39 +601,35 @@ static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
         // Keep asking the iterator for chunks until the search function
         // returns an end value not equal to the length of the string passed to it.
         if (!inTextSecurityMode)
-            string.append(it.characters(), it.length());
+            append(string, it.text());
         else {
             // Treat bullets used in the text security mode as regular characters when looking for boundaries
-            String iteratorString(it.characters(), it.length());
-#if PLATFORM(IOS)
-            iteratorString = iteratorString.impl()->fill('x');
-#else
-            iteratorString.fill('x');
-#endif
-            string.append(iteratorString.deprecatedCharacters(), iteratorString.length());
+            appendRepeatedCharacter(string, 'x', it.length());
+        }
+        if (string.size() > prefixLength) {
+            next = searchFunction(StringView(string.data(), string.size()), prefixLength, MayHaveMoreContext, needMoreContext);
+            if (next != string.size())
+                break;
         }
-        next = searchFunction(string.data(), string.size(), prefixLength, MayHaveMoreContext, needMoreContext);
-        if (next != string.size())
-            break;
         it.advance();
     }
-    if (needMoreContext) {
+    if (needMoreContext && string.size() > prefixLength) {
         // The last search returned the end of the buffer and asked for more context,
         // but there is no further text. Force a search with what's available.
-        next = searchFunction(string.data(), string.size(), prefixLength, DontHaveMoreContext, needMoreContext);
+        next = searchFunction(StringView(string.data(), string.size()), prefixLength, DontHaveMoreContext, needMoreContext);
         ASSERT(!needMoreContext);
     }
     
-    if (it.atEnd() && next == string.size()) {
+    if (it.atEnd() && next == string.size())
         pos = it.range()->startPosition();
-    } else if (next != prefixLength) {
+    else if (next > prefixLength) {
         // Use the character iterator to translate the next value into a DOM position.
         CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
         charIt.advance(next - prefixLength - 1);
         RefPtr<Range> characterRange = charIt.range();
         pos = characterRange->endPosition();
         
-        if (*charIt.characters() == '\n') {
+        if (charIt.text()[0] == '\n') {
             // FIXME: workaround for collapsed range (where only start position is correct) emitted for some emitted newlines (see rdar://5192593)
             VisiblePosition visPos = VisiblePosition(pos);
             if (visPos == VisiblePosition(characterRange->startPosition())) {
@@ -619,21 +645,21 @@ static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
 
 // ---------
 
-static unsigned startWordBoundary(const UChar* characters, unsigned length, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
+static unsigned startWordBoundary(StringView text, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
 {
     ASSERT(offset);
-    if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset)) {
+    if (mayHaveMoreContext && !startOfLastWordBoundaryContext(text.substring(0, offset))) {
         needMoreContext = true;
         return 0;
     }
     needMoreContext = false;
     int start, end;
-    U16_BACK_1(characters, 0, offset);
-    findWordBoundary(characters, length, offset, &start, &end);
+    U16_BACK_1(text, 0, offset);
+    findWordBoundary(text, offset, &start, &end);
     return start;
 }
 
-VisiblePosition startOfWord(const VisiblePosition &c, EWordSide side)
+VisiblePosition startOfWord(const VisiblePositionc, EWordSide side)
 {
     // FIXME: This returns a null VP for c at the start of the document
     // and side == LeftWordIfOnBoundary
@@ -650,26 +676,20 @@ VisiblePosition startOfWord(const VisiblePosition &c, EWordSide side)
     return previousBoundary(p, startWordBoundary);
 }
 
-static unsigned endWordBoundary(const UChar* characters, unsigned length, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
+static unsigned endWordBoundary(StringView text, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
 {
-    ASSERT(offset <= length);
-    if (mayHaveMoreContext && endOfFirstWordBoundaryContext(characters + offset, length - offset) == static_cast<int>(length - offset)) {
+    ASSERT(offset <= text.length());
+    if (mayHaveMoreContext && endOfFirstWordBoundaryContext(text.substring(offset)) == text.length() - offset) {
         needMoreContext = true;
-        return length;
+        return text.length();
     }
     needMoreContext = false;
-#if PLATFORM(IOS)
-    // FIXME: Bug 126830: [iOS] Implement WebCore::findEndWordBoundary()
-    int start, end;
-    findWordBoundary(characters, length, offset, &start, &end);
-#else
     int end;
-    findEndWordBoundary(characters, length, offset, &end);
-#endif
+    findEndWordBoundary(text, offset, &end);
     return end;
 }
 
-VisiblePosition endOfWord(const VisiblePosition &c, EWordSide side)
+VisiblePosition endOfWord(const VisiblePositionc, EWordSide side)
 {
     VisiblePosition p = c;
     if (side == LeftWordIfOnBoundary) {
@@ -685,36 +705,34 @@ VisiblePosition endOfWord(const VisiblePosition &c, EWordSide side)
     return nextBoundary(p, endWordBoundary);
 }
 
-static unsigned previousWordPositionBoundary(const UChar* characters, unsigned length, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
+static unsigned previousWordPositionBoundary(StringView text, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
 {
-    if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset)) {
+    if (mayHaveMoreContext && !startOfLastWordBoundaryContext(text.substring(0, offset))) {
         needMoreContext = true;
         return 0;
     }
     needMoreContext = false;
-    return findNextWordFromIndex(characters, length, offset, false);
+    return findNextWordFromIndex(text, offset, false);
 }
 
-VisiblePosition previousWordPosition(const VisiblePosition &c)
+VisiblePosition previousWordPosition(const VisiblePosition& position)
 {
-    VisiblePosition prev = previousBoundary(c, previousWordPositionBoundary);
-    return c.honorEditingBoundaryAtOrBefore(prev);
+    return position.honorEditingBoundaryAtOrBefore(previousBoundary(position, previousWordPositionBoundary));
 }
 
-static unsigned nextWordPositionBoundary(const UChar* characters, unsigned length, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
+static unsigned nextWordPositionBoundary(StringView text, unsigned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMoreContext)
 {
-    if (mayHaveMoreContext && endOfFirstWordBoundaryContext(characters + offset, length - offset) == static_cast<int>(length - offset)) {
+    if (mayHaveMoreContext && endOfFirstWordBoundaryContext(text.substring(offset)) == text.length() - offset) {
         needMoreContext = true;
-        return length;
+        return text.length();
     }
     needMoreContext = false;
-    return findNextWordFromIndex(characters, length, offset, true);
+    return findNextWordFromIndex(text, offset, true);
 }
 
-VisiblePosition nextWordPosition(const VisiblePosition &c)
+VisiblePosition nextWordPosition(const VisiblePosition& position)
 {
-    VisiblePosition next = nextBoundary(c, nextWordPositionBoundary);    
-    return c.honorEditingBoundaryAtOrAfter(next);
+    return position.honorEditingBoundaryAtOrAfter(nextBoundary(position, nextWordPositionBoundary));
 }
 
 bool isStartOfWord(const VisiblePosition& p)
@@ -900,36 +918,35 @@ VisiblePosition logicalEndOfLine(const VisiblePosition& currentPosition)
     return endOfLine(currentPosition, UseLogicalOrdering);
 }
 
-bool inSameLine(const VisiblePosition &a, const VisiblePosition &b)
+bool inSameLine(const VisiblePosition& a, const VisiblePosition& b)
 {
     return a.isNotNull() && startOfLine(a) == startOfLine(b);
 }
 
-bool isStartOfLine(const VisiblePosition &p)
+bool isStartOfLine(const VisiblePositionp)
 {
     return p.isNotNull() && p == startOfLine(p);
 }
 
-bool isEndOfLine(const VisiblePosition &p)
+bool isEndOfLine(const VisiblePositionp)
 {
     return p.isNotNull() && p == endOfLine(p);
 }
 
-static inline IntPoint absoluteLineDirectionPointToLocalPointInBlock(RootInlineBox* root, int lineDirectionPoint)
+static inline IntPoint absoluteLineDirectionPointToLocalPointInBlock(RootInlineBox& root, int lineDirectionPoint)
 {
-    ASSERT(root);
-    RenderBlockFlow& containingBlock = root->blockFlow();
+    RenderBlockFlow& containingBlock = root.blockFlow();
     FloatPoint absoluteBlockPoint = containingBlock.localToAbsolute(FloatPoint());
     if (containingBlock.hasOverflowClip())
         absoluteBlockPoint -= containingBlock.scrolledContentOffset();
 
     if (containingBlock.isHorizontalWritingMode())
-        return IntPoint(lineDirectionPoint - absoluteBlockPoint.x(), root->blockDirectionPointInLine());
+        return IntPoint(lineDirectionPoint - absoluteBlockPoint.x(), root.blockDirectionPointInLine());
 
-    return IntPoint(root->blockDirectionPointInLine(), lineDirectionPoint - absoluteBlockPoint.y());
+    return IntPoint(root.blockDirectionPointInLine(), lineDirectionPoint - absoluteBlockPoint.y());
 }
 
-VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int lineDirectionPoint, EditableType editableType)
+VisiblePosition previousLinePosition(const VisiblePositionvisiblePosition, int lineDirectionPoint, EditableType editableType)
 {
     Position p = visiblePosition.deepEquivalent();
     Node* node = p.deprecatedNode();
@@ -967,7 +984,7 @@ VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
     
     if (root) {
         // FIXME: Can be wrong for multi-column layout and with transforms.
-        IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint);
+        IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(*root, lineDirectionPoint);
         RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
         Node* node = renderer.node();
         if (node && editingIgnoresContent(node))
@@ -984,7 +1001,7 @@ VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
     return VisiblePosition(firstPositionInNode(rootElement), DOWNSTREAM);
 }
 
-VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lineDirectionPoint, EditableType editableType)
+VisiblePosition nextLinePosition(const VisiblePositionvisiblePosition, int lineDirectionPoint, EditableType editableType)
 {
     Position p = visiblePosition.deepEquivalent();
     Node* node = p.deprecatedNode();
@@ -1025,7 +1042,7 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lin
     
     if (root) {
         // FIXME: Can be wrong for multi-column layout and with transforms.
-        IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint);
+        IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(*root, lineDirectionPoint);
         RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
         Node* node = renderer.node();
         if (node && editingIgnoresContent(node))
@@ -1044,56 +1061,50 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lin
 
 // ---------
 
-static unsigned startSentenceBoundary(const UChar* characters, unsigned length, unsigned, BoundarySearchContextAvailability, bool&)
+static unsigned startSentenceBoundary(StringView text, unsigned, BoundarySearchContextAvailability, bool&)
 {
-    TextBreakIterator* iterator = sentenceBreakIterator(StringView(characters, length));
     // FIXME: The following function can return -1; we don't handle that.
-    return textBreakPreceding(iterator, length);
+    return textBreakPreceding(sentenceBreakIterator(text), text.length());
 }
 
-VisiblePosition startOfSentence(const VisiblePosition &c)
+VisiblePosition startOfSentence(const VisiblePosition& position)
 {
-    return previousBoundary(c, startSentenceBoundary);
+    return previousBoundary(position, startSentenceBoundary);
 }
 
-static unsigned endSentenceBoundary(const UChar* characters, unsigned length, unsigned, BoundarySearchContextAvailability, bool&)
+static unsigned endSentenceBoundary(StringView text, unsigned, BoundarySearchContextAvailability, bool&)
 {
-    TextBreakIterator* iterator = sentenceBreakIterator(StringView(characters, length));
-    return textBreakNext(iterator);
+    return textBreakNext(sentenceBreakIterator(text));
 }
 
-// FIXME: This includes the space after the punctuation that marks the end of the sentence.
-VisiblePosition endOfSentence(const VisiblePosition &c)
+VisiblePosition endOfSentence(const VisiblePosition& position)
 {
-    return nextBoundary(c, endSentenceBoundary);
+    // FIXME: This includes the space after the punctuation that marks the end of the sentence.
+    return nextBoundary(position, endSentenceBoundary);
 }
 
-static unsigned previousSentencePositionBoundary(const UChar* characters, unsigned length, unsigned, BoundarySearchContextAvailability, bool&)
+static unsigned previousSentencePositionBoundary(StringView text, unsigned, BoundarySearchContextAvailability, bool&)
 {
     // FIXME: This is identical to startSentenceBoundary. I'm pretty sure that's not right.
-    TextBreakIterator* iterator = sentenceBreakIterator(StringView(characters, length));
     // FIXME: The following function can return -1; we don't handle that.
-    return textBreakPreceding(iterator, length);
+    return textBreakPreceding(sentenceBreakIterator(text), text.length());
 }
 
-VisiblePosition previousSentencePosition(const VisiblePosition &c)
+VisiblePosition previousSentencePosition(const VisiblePosition& position)
 {
-    VisiblePosition prev = previousBoundary(c, previousSentencePositionBoundary);
-    return c.honorEditingBoundaryAtOrBefore(prev);
+    return position.honorEditingBoundaryAtOrBefore(previousBoundary(position, previousSentencePositionBoundary));
 }
 
-static unsigned nextSentencePositionBoundary(const UChar* characters, unsigned length, unsigned, BoundarySearchContextAvailability, bool&)
+static unsigned nextSentencePositionBoundary(StringView text, unsigned, BoundarySearchContextAvailability, bool&)
 {
-    // FIXME: This is identical to endSentenceBoundary. This isn't right, it needs to 
-    // move to the equivlant position in the following sentence.
-    TextBreakIterator* iterator = sentenceBreakIterator(StringView(characters, length));
-    return textBreakFollowing(iterator, 0);
+    // FIXME: This is identical to endSentenceBoundary.
+    // That isn't right. This function needs to move to the equivalent position in the following sentence.
+    return textBreakFollowing(sentenceBreakIterator(text), 0);
 }
 
-VisiblePosition nextSentencePosition(const VisiblePosition &c)
+VisiblePosition nextSentencePosition(const VisiblePosition& position)
 {
-    VisiblePosition next = nextBoundary(c, nextSentencePositionBoundary);    
-    return c.honorEditingBoundaryAtOrAfter(next);
+    return position.honorEditingBoundaryAtOrAfter(nextBoundary(position, nextSentencePositionBoundary));
 }
 
 VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossingRule boundaryCrossingRule)
@@ -1175,7 +1186,7 @@ VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi
     return VisiblePosition(Position(node, type), DOWNSTREAM);
 }
 
-VisiblePosition endOfParagraph(const VisiblePosition &c, EditingBoundaryCrossingRule boundaryCrossingRule)
+VisiblePosition endOfParagraph(const VisiblePositionc, EditingBoundaryCrossingRule boundaryCrossingRule)
 {    
     if (c.isNull())
         return VisiblePosition();
@@ -1265,17 +1276,17 @@ VisiblePosition startOfNextParagraph(const VisiblePosition& visiblePosition)
     return afterParagraphEnd;
 }
 
-bool inSameParagraph(const VisiblePosition &a, const VisiblePosition &b, EditingBoundaryCrossingRule boundaryCrossingRule)
+bool inSameParagraph(const VisiblePosition& a, const VisiblePosition& b, EditingBoundaryCrossingRule boundaryCrossingRule)
 {
     return a.isNotNull() && startOfParagraph(a, boundaryCrossingRule) == startOfParagraph(b, boundaryCrossingRule);
 }
 
-bool isStartOfParagraph(const VisiblePosition &pos, EditingBoundaryCrossingRule boundaryCrossingRule)
+bool isStartOfParagraph(const VisiblePositionpos, EditingBoundaryCrossingRule boundaryCrossingRule)
 {
     return pos.isNotNull() && pos == startOfParagraph(pos, boundaryCrossingRule);
 }
 
-bool isEndOfParagraph(const VisiblePosition &pos, EditingBoundaryCrossingRule boundaryCrossingRule)
+bool isEndOfParagraph(const VisiblePositionpos, EditingBoundaryCrossingRule boundaryCrossingRule)
 {
     return pos.isNotNull() && pos == endOfParagraph(pos, boundaryCrossingRule);
 }
@@ -1324,17 +1335,17 @@ VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBounda
     return lastPositionInNode(endBlock);
 }
 
-bool inSameBlock(const VisiblePosition &a, const VisiblePosition &b)
+bool inSameBlock(const VisiblePosition& a, const VisiblePosition& b)
 {
     return !a.isNull() && enclosingBlock(a.deepEquivalent().containerNode()) == enclosingBlock(b.deepEquivalent().containerNode());
 }
 
-bool isStartOfBlock(const VisiblePosition &pos)
+bool isStartOfBlock(const VisiblePositionpos)
 {
     return pos.isNotNull() && pos == startOfBlock(pos, CanCrossEditingBoundary);
 }
 
-bool isEndOfBlock(const VisiblePosition &pos)
+bool isEndOfBlock(const VisiblePositionpos)
 {
     return pos.isNotNull() && pos == endOfBlock(pos, CanCrossEditingBoundary);
 }
@@ -1350,7 +1361,7 @@ VisiblePosition startOfDocument(const Node* node)
     // The canonicalization of the position at (documentElement, 0) can turn the visible
     // position to null, even when there's a valid candidate to be had, because the root HTML element
     // is not content editable.  So we construct directly from the valid candidate.
-    // FIXME: Merge this to Open Source. https://bugs.webkit.org/show_bug.cgi?id=56437
+    // FIXME: Do this for non-iOS platforms too. https://bugs.webkit.org/show_bug.cgi?id=56437
     Position firstCandidate = nextCandidate(createLegacyEditingPosition(node->document().documentElement(), 0));
     if (firstCandidate.isNull())
         return VisiblePosition();
@@ -1360,7 +1371,7 @@ VisiblePosition startOfDocument(const Node* node)
 #endif
 }
 
-VisiblePosition startOfDocument(const VisiblePosition &c)
+VisiblePosition startOfDocument(const VisiblePositionc)
 {
     return startOfDocument(c.deepEquivalent().deprecatedNode());
 }
@@ -1374,25 +1385,23 @@ VisiblePosition endOfDocument(const Node* node)
     // (As above, in startOfDocument.)  The canonicalization can reject valid visible positions
     // when descending from the root element, so we construct the visible position directly from a
     // valid candidate.
-    // FIXME: Merge this to Open Source. https://bugs.webkit.org/show_bug.cgi?id=56437
-#endif
-    Element* doc = node->document().documentElement();
-#if PLATFORM(IOS)
-    Position lastPosition = createLegacyEditingPosition(node->document().documentElement(), doc->childNodeCount());
+    // FIXME: Do this for non-iOS platforms too. https://bugs.webkit.org/show_bug.cgi?id=56437
+    Position lastPosition = createLegacyEditingPosition(node->document().documentElement(), node->document().documentElement()->childNodeCount());
     Position lastCandidate = previousCandidate(lastPosition);
     if (lastCandidate.isNull())
         return VisiblePosition();
     return VisiblePosition(lastCandidate);
+#else
+    return VisiblePosition(lastPositionInNode(node->document().documentElement()), DOWNSTREAM);
 #endif
-    return VisiblePosition(lastPositionInNode(doc), DOWNSTREAM);
 }
 
-VisiblePosition endOfDocument(const VisiblePosition &c)
+VisiblePosition endOfDocument(const VisiblePositionc)
 {
     return endOfDocument(c.deepEquivalent().deprecatedNode());
 }
 
-bool inSameDocument(const VisiblePosition &a, const VisiblePosition &b)
+bool inSameDocument(const VisiblePosition& a, const VisiblePosition& b)
 {
     Position ap = a.deepEquivalent();
     Node* an = ap.deprecatedNode();
@@ -1406,12 +1415,12 @@ bool inSameDocument(const VisiblePosition &a, const VisiblePosition &b)
     return &an->document() == &bn->document();
 }
 
-bool isStartOfDocument(const VisiblePosition &p)
+bool isStartOfDocument(const VisiblePositionp)
 {
     return p.isNotNull() && p.previous(CanCrossEditingBoundary).isNull();
 }
 
-bool isEndOfDocument(const VisiblePosition &p)
+bool isEndOfDocument(const VisiblePositionp)
 {
     return p.isNotNull() && p.next(CanCrossEditingBoundary).isNull();
 }
@@ -1436,7 +1445,7 @@ VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition)
     return lastPositionInNode(highestRoot);
 }
 
-bool isEndOfEditableOrNonEditableContent(const VisiblePosition &p)
+bool isEndOfEditableOrNonEditableContent(const VisiblePositionp)
 {
     return p.isNotNull() && p.next().isNull();
 }
@@ -1452,6 +1461,7 @@ VisiblePosition rightBoundaryOfLine(const VisiblePosition& c, TextDirection dire
 }
 
 #if PLATFORM(IOS)
+
 static bool directionIsDownstream(SelectionDirection direction)
 {
     if (direction == DirectionBackward)
index 5b6173b..f8a7739 100644 (file)
@@ -53,7 +53,6 @@
 #include "Range.h"
 #include "RenderBlock.h"
 #include "StyleProperties.h"
-#include "TextIterator.h"
 #include "VisibleSelection.h"
 #include "VisibleUnits.h"
 #include "htmlediting.h"
index 308bb6c..cd2b350 100644 (file)
@@ -56,7 +56,6 @@
 #include "StyleProperties.h"
 #include "SubframeLoader.h"
 #include "Text.h"
-#include "TextIterator.h"
 #include "XMLNames.h"
 #include "markup.h"
 #include <wtf/NeverDestroyed.h>
index d40d4e8..b465d10 100644 (file)
@@ -47,7 +47,6 @@
 #include "Text.h"
 #include "TextBreakIterator.h"
 #include "TextControlInnerElements.h"
-#include "TextIterator.h"
 #include "TextNodeTraversal.h"
 #include <wtf/Ref.h>
 #include <wtf/StdLibExtras.h>
index bdd0dc2..6c559cb 100644 (file)
@@ -403,9 +403,9 @@ public:
     virtual bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const override { return true; }
     virtual void ignoreWordInSpellDocument(const String&) override { }
     virtual void learnWord(const String&) override { }
-    virtual void checkSpellingOfString(const UChar*, int, int*, int*) override { }
+    virtual void checkSpellingOfString(StringView, int*, int*) override { }
     virtual String getAutoCorrectSuggestionForMisspelledWord(const String&) override { return String(); }
-    virtual void checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*) override { }
+    virtual void checkGrammarOfString(StringView, Vector<GrammarDetail>&, int*, int*) override { }
 
 #if USE(UNIFIED_TEXT_CHECKING)
     virtual Vector<TextCheckingResult> checkTextOfParagraph(StringView, TextCheckingTypeMask) override { return Vector<TextCheckingResult>(); }
index 0e80f9c..38a6ca8 100644 (file)
@@ -91,7 +91,6 @@
 #include "ScrollingCoordinator.h"
 #include "Settings.h"
 #include "StyleProperties.h"
-#include "TextIterator.h"
 #include "TextNodeTraversal.h"
 #include "TextResourceDecoder.h"
 #include "UserContentController.h"
index 05d3160..6b61fb4 100644 (file)
@@ -2472,6 +2472,7 @@ static NSInteger _colCompare(id block1, id block2, void *)
 }
 
 #if !PLATFORM(IOS)
+
 // This function uses TextIterator, which makes offsets in its result compatible with HTML editing.
 + (NSAttributedString *)editingAttributedStringFromRange:(Range*)range
 {
@@ -2523,18 +2524,20 @@ static NSInteger _colCompare(id block1, id block2, void *)
         else
             [attrs.get() removeObjectForKey:NSBackgroundColorAttributeName];
 
-        RetainPtr<NSString> substring = adoptNS([[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(it.characters()) length:currentTextLength freeWhenDone:NO]);
-        [string replaceCharactersInRange:NSMakeRange(stringLength, 0) withString:substring.get()];
+        [string replaceCharactersInRange:NSMakeRange(stringLength, 0) withString:it.text().createNSStringWithoutCopying().get()];
         [string setAttributes:attrs.get() range:NSMakeRange(stringLength, currentTextLength)];
         stringLength += currentTextLength;
     }
 
     return [string autorelease];
 }
+
 #endif
+
 @end
 
 #if !PLATFORM(IOS)
+
 static NSFileWrapper *fileWrapperForURL(DocumentLoader *dataSource, NSURL *URL)
 {
     if ([URL isFileURL])
@@ -2585,4 +2588,5 @@ static NSFileWrapper *fileWrapperForElement(Element* element)
 
     return wrapper;
 }
+
 #endif
index 2bcdc57..da51f71 100644 (file)
 
 namespace WebCore {
 
-int endOfFirstWordBoundaryContext(const UChar* characters, int length)
+unsigned endOfFirstWordBoundaryContext(StringView text)
 {
-    for (int i = 0; i < length; ) {
-        int first = i;
+    unsigned length = text.length();
+    for (unsigned i = 0; i < length; ) {
+        unsigned first = i;
         UChar32 ch;
-        U16_NEXT(characters, i, length, ch);
+        U16_NEXT(text, i, length, ch);
         if (!requiresContextForWordBoundary(ch))
             return first;
     }
     return length;
 }
 
-int startOfLastWordBoundaryContext(const UChar* characters, int length)
+unsigned startOfLastWordBoundaryContext(StringView text)
 {
-    for (int i = length; i > 0; ) {
-        int last = i;
+    unsigned length = text.length();
+    for (unsigned i = length; i > 0; ) {
+        unsigned last = i;
         UChar32 ch;
-        U16_PREV(characters, 0, i, ch);
+        U16_PREV(text, 0, i, ch);
         if (!requiresContextForWordBoundary(ch))
             return last;
     }
@@ -58,26 +60,26 @@ int startOfLastWordBoundaryContext(const UChar* characters, int length)
 
 #if !PLATFORM(COCOA)
 
-int findNextWordFromIndex(const UChar* chars, int len, int position, bool forward)
+int findNextWordFromIndex(StringView text, int position, bool forward)
 {
-    TextBreakIterator* it = wordBreakIterator(StringView(chars, len));
+    TextBreakIterator* it = wordBreakIterator(text);
 
     if (forward) {
         position = textBreakFollowing(it, position);
         while (position != TextBreakDone) {
             // We stop searching when the character preceeding the break is alphanumeric.
-            if (position < len && u_isalnum(chars[position - 1]))
+            if (static_cast<unsigned>(position) < text.length() && u_isalnum(text[position - 1]))
                 return position;
 
             position = textBreakFollowing(it, position);
         }
 
-        return len;
+        return text.length();
     } else {
         position = textBreakPreceding(it, position);
         while (position != TextBreakDone) {
             // We stop searching when the character following the break is alphanumeric.
-            if (position > 0 && u_isalnum(chars[position]))
+            if (position && u_isalnum(text[position]))
                 return position;
 
             position = textBreakPreceding(it, position);
@@ -87,18 +89,18 @@ int findNextWordFromIndex(const UChar* chars, int len, int position, bool forwar
     }
 }
 
-void findWordBoundary(const UChar* chars, int len, int position, int* start, int* end)
+void findWordBoundary(StringView text, int position, int* start, int* end)
 {
-    TextBreakIterator* it = wordBreakIterator(StringView(chars, len));
+    TextBreakIterator* it = wordBreakIterator(text);
     *end = textBreakFollowing(it, position);
     if (*end < 0)
         *end = textBreakLast(it);
     *start = textBreakPrevious(it);
 }
 
-void findEndWordBoundary(const UChar* chars, int len, int position, int* end)
+void findEndWordBoundary(StringView text, int position, int* end)
 {
-    TextBreakIterator* it = wordBreakIterator(StringView(chars, len));
+    TextBreakIterator* it = wordBreakIterator(text);
     *end = textBreakFollowing(it, position);
     if (*end < 0)
         *end = textBreakLast(it);
index 25a6c41..da2c4f9 100644 (file)
@@ -27,6 +27,7 @@
 #define TextBoundaries_h
 
 #include <unicode/uchar.h>
+#include <wtf/Forward.h>
 
 namespace WebCore {
 
@@ -41,12 +42,12 @@ namespace WebCore {
         return lineBreak == U_LB_COMPLEX_CONTEXT || lineBreak == WK_U_LB_CONDITIONAL_JAPANESE_STARTER || lineBreak == U_LB_IDEOGRAPHIC;
     }
 
-    int endOfFirstWordBoundaryContext(const UChar* characters, int length);
-    int startOfLastWordBoundaryContext(const UChar* characters, int length);
+    unsigned endOfFirstWordBoundaryContext(StringView);
+    unsigned startOfLastWordBoundaryContext(StringView);
 
-    void findWordBoundary(const UChar*, int len, int position, int* start, int* end);
-    void findEndWordBoundary(const UChar*, int len, int position, int* end);
-    int findNextWordFromIndex(const UChar*, int len, int position, bool forward);
+    void findWordBoundary(StringView, int position, int* start, int* end);
+    void findEndWordBoundary(StringView, int position, int* end);
+    int findNextWordFromIndex(StringView, int position, bool forward);
 
 }
 
index 054fb11..1d3d8b5 100644 (file)
@@ -44,9 +44,9 @@ public:
     virtual bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const = 0;
     virtual void ignoreWordInSpellDocument(const String&) = 0;
     virtual void learnWord(const String&) = 0;
-    virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0;
+    virtual void checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength) = 0;
     virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) = 0;
-    virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0;
+    virtual void checkGrammarOfString(StringView, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0;
 
 #if USE(UNIFIED_TEXT_CHECKING)
     virtual Vector<TextCheckingResult> checkTextOfParagraph(StringView, TextCheckingTypeMask checkingTypes) = 0;
index 77743d2..f9213b5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004, 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2004, 2006, 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
 #import "config.h"
 #import "TextBoundaries.h"
 
-#if PLATFORM(IOS)
+#import "TextBreakIterator.h"
 #import "TextBreakIteratorInternalICU.h"
 #import <CoreFoundation/CFStringTokenizer.h>
 #import <Foundation/Foundation.h>
 #import <unicode/uchar.h>
 #import <unicode/ustring.h>
 #import <unicode/utypes.h>
-#import <wtf/unicode/CharacterNames.h>
 #import <wtf/RetainPtr.h>
-#endif
+#import <wtf/text/StringView.h>
+#import <wtf/unicode/CharacterNames.h>
 
 namespace WebCore {
 
-#if PLATFORM(IOS)
+#if !USE(APPKIT)
 
 static bool isSkipCharacter(UChar32 c)
 {
-    return c == 0xA0 || 
-        c == '\n' || 
-        c == '.' || 
-        c == ',' || 
-        c == '!'  || 
-        c == '?' || 
-        c == ';' || 
-        c == ':' || 
-        u_isspace(c);
+    return c == 0xA0 || c == '\n' || c == '.' || c == ',' || c == '!'  || c == '?' || c == ';' || c == ':' || u_isspace(c);
 }
 
 static bool isWhitespaceCharacter(UChar32 c)
 {
-    return c == 0xA0 || 
-        c == '\n' || 
-        u_isspace(c);
+    return c == 0xA0 || c == '\n' || u_isspace(c);
 }
 
 static bool isWordDelimitingCharacter(UChar32 c)
 {
-    CFCharacterSetRef set = CFCharacterSetGetPredefined(kCFCharacterSetAlphaNumeric);
     // Ampersand is an exception added to treat AT&T as a single word (see <rdar://problem/5022264>).
-    return !CFCharacterSetIsLongCharacterMember(set, c) && c != '&';
+    return !CFCharacterSetIsLongCharacterMember(CFCharacterSetGetPredefined(kCFCharacterSetAlphaNumeric), c) && c != '&';
 }
 
 static bool isSymbolCharacter(UChar32 c)
 {
-    CFCharacterSetRef set = CFCharacterSetGetPredefined(kCFCharacterSetSymbol);
-    return CFCharacterSetIsLongCharacterMember(set, c);
+    return CFCharacterSetIsLongCharacterMember(CFCharacterSetGetPredefined(kCFCharacterSetSymbol), c);
 }
 
 static bool isAmbiguousBoundaryCharacter(UChar32 character)
@@ -83,39 +71,36 @@ static bool isAmbiguousBoundaryCharacter(UChar32 character)
 
 static CFStringTokenizerRef tokenizerForString(CFStringRef str)
 {
-    static CFStringTokenizerRef tokenizer = nullptr;
     static CFLocaleRef locale = nullptr;
-
     if (!locale) {
         const char* temp = currentTextBreakLocaleID();
-        RetainPtr<CFStringRef> currentLocaleID = adoptCF(CFStringCreateWithBytesNoCopy(nullptr, reinterpret_cast<const UInt8*>(temp), strlen(temp),  kCFStringEncodingASCII, false, kCFAllocatorNull));
-        locale = CFLocaleCreate(nullptr, currentLocaleID.get());
+        RetainPtr<CFStringRef> currentLocaleID = adoptCF(CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(temp), strlen(temp), kCFStringEncodingASCII, false, kCFAllocatorNull));
+        locale = CFLocaleCreate(kCFAllocatorDefault, currentLocaleID.get());
         if (!locale)
             return nullptr;
     }
 
     CFRange entireRange = CFRangeMake(0, CFStringGetLength(str));    
 
+    static CFStringTokenizerRef tokenizer = nullptr;
     if (!tokenizer)
-        tokenizer = CFStringTokenizerCreate(nullptr, str, entireRange, kCFStringTokenizerUnitWordBoundary, locale);
+        tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, str, entireRange, kCFStringTokenizerUnitWordBoundary, locale);
     else
         CFStringTokenizerSetString(tokenizer, str, entireRange);
     return tokenizer;
 }
 
-
-// Simple case: a word is a stream of characters
-// delimited by a special set of word-delimiting characters.
-static void findSimpleWordBoundary(const UChar* chars, int len, int position, int* start, int* end)
+// Simple case: A word is a stream of characters delimited by a special set of word-delimiting characters.
+static void findSimpleWordBoundary(StringView text, int position, int* start, int* end)
 {
     ASSERT(position >= 0);
-    ASSERT(position < len);
+    ASSERT(static_cast<unsigned>(position) < text.length());
 
-    int startPos = position;
+    unsigned startPos = position;
     while (startPos > 0) {
         int i = startPos;
         UChar32 characterBeforeStartPos;
-        U16_PREV(chars, 0, i, characterBeforeStartPos);
+        U16_PREV(text, 0, i, characterBeforeStartPos);
         if (isWordDelimitingCharacter(characterBeforeStartPos)) {
             ASSERT(i >= 0);
             if (!i)
@@ -125,40 +110,40 @@ static void findSimpleWordBoundary(const UChar* chars, int len, int position, in
                 break;
 
             UChar32 characterBeforeBeforeStartPos;
-            U16_PREV(chars, 0, i, characterBeforeBeforeStartPos);
+            U16_PREV(text, 0, i, characterBeforeBeforeStartPos);
             if (isWordDelimitingCharacter(characterBeforeBeforeStartPos))
                 break;
         }
-        U16_BACK_1(chars, 0, startPos);
+        U16_BACK_1(text, 0, startPos);
     }
     
-    int endPos = position;
-    while (endPos < len) {
+    unsigned endPos = position;
+    while (endPos < text.length()) {
         UChar32 character;
-        U16_GET(chars, 0, endPos, len, character);
+        U16_GET(text, 0, endPos, text.length(), character);
         if (isWordDelimitingCharacter(character)) {
-            int i = endPos;
-            U16_FWD_1(chars, i, len);
-            ASSERT(i <= len);
-            if (i == len)
+            unsigned i = endPos;
+            U16_FWD_1(text, i, text.length());
+            ASSERT(i <= text.length());
+            if (i == text.length())
                 break;
             UChar32 characterAfterEndPos;
-            U16_NEXT(chars, i, len, characterAfterEndPos);
+            U16_NEXT(text, i, text.length(), characterAfterEndPos);
             if (!isAmbiguousBoundaryCharacter(character))
                 break;
             if (isWordDelimitingCharacter(characterAfterEndPos))
                 break;
         }
-        U16_FWD_1(chars, endPos, len);
+        U16_FWD_1(text, endPos, text.length());
     }
 
     // The text may consist of all delimiter characters (e.g. "++++++++" or a series of emoji), and returning an empty range
     // makes no sense (and doesn't match findComplexWordBoundary() behavior).
-    if (startPos == endPos && endPos < len) {
+    if (startPos == endPos && endPos < text.length()) {
         UChar32 character;
-        U16_GET(chars, 0, endPos, len, character);
+        U16_GET(text, 0, endPos, text.length(), character);
         if (isSymbolCharacter(character))
-            U16_FWD_1(chars, endPos, len);
+            U16_FWD_1(text, endPos, text.length());
     }
 
     *start = startPos;
@@ -166,143 +151,115 @@ static void findSimpleWordBoundary(const UChar* chars, int len, int position, in
 }
 
 // Complex case: use CFStringTokenizer to find word boundary.
-static void findComplexWordBoundary(const UChar* chars, int len, int position, int* start, int* end)
+static void findComplexWordBoundary(StringView text, int position, int* start, int* end)
 {
-    CFStringRef charString = CFStringCreateWithCharactersNoCopy(NULL, chars, len, kCFAllocatorNull);
-    ASSERT(charString);
-    
-    CFStringTokenizerRef tokenizer = tokenizerForString(charString);
-    if (tokenizer) {        
-        CFStringTokenizerTokenType  token = CFStringTokenizerGoToTokenAtIndex(tokenizer, position);
-        CFRange result;
-        if (token != kCFStringTokenizerTokenNone) {
-            result = CFStringTokenizerGetCurrentTokenRange(tokenizer);
-        } else {
-            // if no token found: select entire block
-            // NB: I never hit this section in all my testing...
-            result.location = 0;
-            result.length = len;
-        }
-        
-        *start = result.location;
-        *end = result.location + result.length;
-    } else {    // error creating tokenizer
-        findSimpleWordBoundary(chars, len, position, start, end);
+    RetainPtr<CFStringRef> charString = text.createCFStringWithoutCopying();
+
+    CFStringTokenizerRef tokenizer = tokenizerForString(charString.get());
+    if (!tokenizer) {
+        // Error creating tokenizer, so just use simple function.
+        findSimpleWordBoundary(text, position, start, end);
+        return;
     }
 
-    CFRelease(charString);
+    CFStringTokenizerTokenType  token = CFStringTokenizerGoToTokenAtIndex(tokenizer, position);
+    if (token == kCFStringTokenizerTokenNone) {
+        // No token found: select entire block.
+        // NB: I never hit this section in all my testing.
+        *start = 0;
+        *end = text.length();
+        return;
+    }
+
+    CFRange result = CFStringTokenizerGetCurrentTokenRange(tokenizer);
+    *start = result.location;
+    *end = result.location + result.length;
 }
+
 #endif
 
-void findWordBoundary(const UChar* chars, int len, int position, int* start, int* end)
+void findWordBoundary(StringView text, int position, int* start, int* end)
 {
-#if !PLATFORM(IOS)
-    NSString* string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(chars)
-        length:len freeWhenDone:NO];
-    NSAttributedString* attr = [[NSAttributedString alloc] initWithString:string];
-    NSRange range = [attr doubleClickAtIndex:(position >= len) ? len - 1 : position];
-    [attr release];
-    [string release];
+#if USE(APPKIT)
+    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text.createNSStringWithoutCopying().get()];
+    NSRange range = [attributedString doubleClickAtIndex:std::min<unsigned>(position, text.length() - 1)];
+    [attributedString release];
     *start = range.location;
     *end = range.location + range.length;
 #else
-    int pos = position;
-    if ( position == len && position != 0)
-        pos--;
-    
+    unsigned pos = position;
+    if (pos == text.length() && pos)
+        --pos;
+
     // For complex text (Thai, Japanese, Chinese), visible_units will pass the text in as a 
     // single contiguous run of characters, providing as much context as is possible.
     // We only need one character to determine if the text is complex.
     UChar32 ch;
-    int i = pos;
-    U16_NEXT(chars,i,len,ch);
+    unsigned i = pos;
+    U16_NEXT(text, i, text.length(), ch);
     bool isComplex = requiresContextForWordBoundary(ch);
-    
+
     // FIXME: This check improves our word boundary behavior, but doesn't actually go far enough.
     // See <rdar://problem/8853951> Take complex word boundary finding path when necessary
     if (!isComplex) {
         // Check again for complex text, at the start of the run.
         i = 0;
-        U16_NEXT(chars, i, len, ch);
+        U16_NEXT(text, i, text.length(), ch);
         isComplex = requiresContextForWordBoundary(ch);
     }
-    
-    if (isComplex) {
-        findComplexWordBoundary(chars,len, position, start, end);
-    } else {
-        findSimpleWordBoundary(chars,len, position, start, end);
-    }
+
+    if (isComplex)
+        findComplexWordBoundary(text, position, start, end);
+    else
+        findSimpleWordBoundary(text, position, start, end);
 
 #define LOG_WORD_BREAK 0
 #if LOG_WORD_BREAK
-    CFStringRef uniString = CFStringCreateWithCharacters(NULL, chars, len);
-    CFStringRef foundWord = CFStringCreateWithCharacters(NULL, (const UniChar *) chars + *start, *end - *start);        
-    NSLog(@"%s_BREAK '%@' (%d,%d) in '%@' (%p) at %d, length=%d", isComplex ? "COMPLEX" : "SIMPLE", foundWord, *start, *end, uniString, uniString, position, len);
-    CFRelease(foundWord);
-    CFRelease(uniString);
+    auto uniString = text.createCFStringWithoutCopying();
+    auto foundWord = text.substring(*start, *end - *start).createCFStringWithoutCopying();
+    NSLog(@"%s_BREAK '%@' (%d,%d) in '%@' (%p) at %d, length=%d", isComplex ? "COMPLEX" : "SIMPLE", foundWord.get(), *start, *end, uniString.get(), uniString.get(), position, text.length());
 #endif
     
 #endif
 }
 
-void findEndWordBoundary(const UChar* chars, int len, int position, int* end)
+void findEndWordBoundary(StringView text, int position, int* end)
 {
-#if !PLATFORM(IOS)
-    NSString* string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(chars)
-        length:len freeWhenDone:NO];
-    NSAttributedString* attr = [[NSAttributedString alloc] initWithString:string];
-    NSRange range = [attr doubleClickAtIndex:(position >= len) ? len - 1 : position];
-    [attr release];
-    [string release];
-    *end = range.location + range.length;
-#else
-    // FIXME: Bug 126830: [iOS] Implement WebCore::findEndWordBoundary()
-    UNUSED_PARAM(chars);
-    UNUSED_PARAM(len);
-    UNUSED_PARAM(position);
-    UNUSED_PARAM(end);
-#endif
+    int start;
+    findWordBoundary(text, position, &start, end);
 }
 
-int findNextWordFromIndex(const UChar* chars, int len, int position, bool forward)
+int findNextWordFromIndex(StringView text, int position, bool forward)
 {   
-#if !PLATFORM(IOS)
-    NSString* string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(chars)
-        length:len freeWhenDone:NO];
-    NSAttributedString* attr = [[NSAttributedString alloc] initWithString:string];
-    int result = [attr nextWordFromIndex:position forward:forward];
-    [attr release];
-    [string release];
+#if USE(APPKIT)
+    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text.createNSStringWithoutCopying().get()];
+    int result = [attributedString nextWordFromIndex:position forward:forward];
+    [attributedString release];
     return result;
 #else
     // This very likely won't behave exactly like the non-iPhone version, but it works
     // for the contexts in which it is used on iPhone, and in the future will be
     // tuned to improve the iPhone-specific behavior for the keyboard and text editing.
     int pos = position;
-    UErrorCode status = U_ZERO_ERROR;
-    UBreakIterator *boundary = ubrk_open(UBRK_WORD, currentTextBreakLocaleID(), const_cast<unichar *>(reinterpret_cast<const unichar *>(chars)), len, &status);
-
-    if (boundary && U_SUCCESS(status)) {
+    TextBreakIterator* boundary = wordBreakIterator(text);
+    if (boundary) {
         if (forward) {
             do {
-                pos = ubrk_following(boundary, pos);    
-                if (pos == UBRK_DONE) {
-                    pos = len;
-                }
-            } while (pos < len && (pos == 0 || !isSkipCharacter(chars[pos-1])) && isSkipCharacter(chars[pos]));
+                pos = textBreakFollowing(boundary, pos);
+                if (pos == UBRK_DONE)
+                    pos = text.length();
+            } while (static_cast<unsigned>(pos) < text.length() && (pos == 0 || !isSkipCharacter(text[pos - 1])) && isSkipCharacter(text[pos]));
         }
         else {
             do {
-                pos = ubrk_preceding(boundary, pos);
-                if (pos == UBRK_DONE) {
+                pos = textBreakPreceding(boundary, pos);
+                if (pos == UBRK_DONE)
                     pos = 0;
-                }
-            } while (pos > 0 && isSkipCharacter(chars[pos]) && !isWhitespaceCharacter(chars[pos-1]));
+            } while (pos > 0 && isSkipCharacter(text[pos]) && !isWhitespaceCharacter(text[pos - 1]));
         }
-        ubrk_close(boundary);
     }
     return pos;
-#endif // !PLATFORM(IOS)
+#endif
 }
 
 }
index eb568a2..f9f59db 100644 (file)
@@ -30,7 +30,6 @@
 #include "ScrollbarTheme.h"
 #include "StyleInheritedData.h"
 #include "TextControlInnerElements.h"
-#include "TextIterator.h"
 #include "VisiblePosition.h"
 #include <wtf/unicode/CharacterNames.h>
 
index 54f631f..83ba0a8 100644 (file)
@@ -1,3 +1,15 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/EditorClientEfl.cpp:
+        (WebCore::EditorClientEfl::checkSpellingOfString): Use StringView.
+        (WebCore::EditorClientEfl::checkGrammarOfString): Ditto.
+        * WebCoreSupport/EditorClientEfl.h: Ditto.
+
 2014-02-07  Gavin Barraclough  <barraclough@apple.com>
 
         Remove isInitialState flag from Page::setViewState
index 99f0975..b980126 100644 (file)
@@ -409,7 +409,7 @@ void EditorClientEfl::learnWord(const String&)
     notImplemented();
 }
 
-void EditorClientEfl::checkSpellingOfString(const UChar*, int, int*, int*)
+void EditorClientEfl::checkSpellingOfString(StringView, int*, int*)
 {
     notImplemented();
 }
@@ -420,7 +420,7 @@ String EditorClientEfl::getAutoCorrectSuggestionForMisspelledWord(const String&)
     return String();
 }
 
-void EditorClientEfl::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
+void EditorClientEfl::checkGrammarOfString(StringView, Vector<GrammarDetail>&, int*, int*)
 {
     notImplemented();
 }
index bd92cd1..e09616d 100644 (file)
@@ -136,9 +136,9 @@ public:
     virtual bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const;
     virtual void ignoreWordInSpellDocument(const String&);
     virtual void learnWord(const String&);
-    virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength);
+    virtual void checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength);
     virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord);
-    virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength);
+    virtual void checkGrammarOfString(StringView, WTF::Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength);
     virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&);
     virtual void updateSpellingUIWithMisspelledWord(const String&);
     virtual void showSpellingUI(bool show);
index 7bfe169..98856d4 100644 (file)
@@ -1,3 +1,15 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/TextCheckerClientGtk.cpp:
+        (WebKit::TextCheckerClientGtk::checkSpellingOfString): Use StringView.
+        (WebKit::TextCheckerClientGtk::checkGrammarOfString): Ditto.
+        * WebCoreSupport/TextCheckerClientGtk.h: Ditto.
+
 2014-02-07  Gavin Barraclough  <barraclough@apple.com>
 
         Remove isInitialState flag from Page::setViewState
index 23238f4..bc2ae8a 100644 (file)
@@ -30,6 +30,7 @@
 #include <glib.h>
 #include <wtf/gobject/GOwnPtr.h>
 #include <wtf/text/CString.h>
+#include <wtf/text/StringView.h>
 
 using namespace WebCore;
 
@@ -59,10 +60,9 @@ void TextCheckerClientGtk::learnWord(const String& text)
     webkit_spell_checker_learn_word(m_spellChecker.get(), text.utf8().data());
 }
 
-void TextCheckerClientGtk::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
+void TextCheckerClientGtk::checkSpellingOfString(StringView text, int* misspellingLocation, int* misspellingLength)
 {
-    String textAsString(text, length);
-    webkit_spell_checker_check_spelling_of_string(m_spellChecker.get(), textAsString.utf8().data(), misspellingLocation, misspellingLength);
+    webkit_spell_checker_check_spelling_of_string(m_spellChecker.get(), text.toStringWithoutCopying().utf8().data(), misspellingLocation, misspellingLength);
 }
 
 String TextCheckerClientGtk::getAutoCorrectSuggestionForMisspelledWord(const String& inputWord)
@@ -70,7 +70,7 @@ String TextCheckerClientGtk::getAutoCorrectSuggestionForMisspelledWord(const Str
     return webkit_spell_checker_get_autocorrect_suggestions_for_misspelled_word(m_spellChecker.get(), inputWord.utf8().data());
 }
 
-void TextCheckerClientGtk::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
+void TextCheckerClientGtk::checkGrammarOfString(StringView, Vector<GrammarDetail>&, int*, int*)
 {
     notImplemented();
 }
index b4861df..aab55dc 100644 (file)
@@ -42,14 +42,14 @@ class TextCheckerClientGtk : public WebCore::TextCheckerClient {
     public:
         TextCheckerClientGtk(WebKitSpellChecker*);
         ~TextCheckerClientGtk();
-        virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const;
-        virtual void ignoreWordInSpellDocument(const WTF::String&);
-        virtual void learnWord(const WTF::String&);
-        virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength);
-        virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&);
-        virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength);
-        virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses);
-    virtual void requestCheckingOfString(WTF::PassRefPtr<WebCore::TextCheckingRequest>) { }
+        virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const override;
+        virtual void ignoreWordInSpellDocument(const WTF::String&) override;
+        virtual void learnWord(const WTF::String&) override;
+        virtual void checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength) override;
+        virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&) override;
+        virtual void checkGrammarOfString(StringView, WTF::Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override;
+        virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses) override;
+        virtual void requestCheckingOfString(WTF::PassRefPtr<WebCore::TextCheckingRequest>) override { }
 
         void updateSpellCheckingLanguage(const char*);
     private:
index 1cfee0d..8db3024 100644 (file)
@@ -1,3 +1,26 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/WebEditorClient.h: Made most data members private. Moved inlines
+        for iOS out of the class definition. Fixed formatting. Added missing virtual keyword.
+        Changed interfaces to use StringView.
+
+        * WebCoreSupport/WebEditorClient.mm:
+        (WebEditorClient::checkTextOfParagraph): Use the new StringView::createNSStringWithoutCopying
+        function instead of a similar function that was local in this file.
+        (WebEditorClient::ignoreWordInSpellDocument): Tweaked formatting.
+        (WebEditorClient::checkSpellingOfString): Changed to take a StringView.
+        (WebEditorClient::checkGrammarOfString): Ditto.
+
+        * WebView/WebTextIterator.mm:
+        (-[WebTextIterator currentTextPointer]): Call TextIterator::deprecatedTextIteratorCharacters.
+        (-[WebTextIterator currentText]): Convert a the text to an NSString with TextIterator::text
+        instead of with TextIterator::characters/length.
+
 2014-02-07  Gavin Barraclough  <barraclough@apple.com>
 
         Remove isInitialState flag from Page::setViewState
index 80cf012..335601b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,22 +40,17 @@ class WebEditorClient : public WebCore::EditorClient, public WebCore::TextChecke
 public:
     WebEditorClient(WebView *);
     virtual ~WebEditorClient();
+
+    void didCheckSucceed(int sequence, NSArray *results);
+
+private:
     virtual void pageDestroyed() override;
 
-#if !PLATFORM(IOS)
     virtual bool isGrammarCheckingEnabled() override;
     virtual void toggleGrammarChecking() override;
     virtual bool isContinuousSpellCheckingEnabled() override;
     virtual void toggleContinuousSpellChecking() override;
     virtual int spellCheckerDocumentTag() override;
-#else
-    virtual bool isGrammarCheckingEnabled() override { return false; }
-    virtual void toggleGrammarChecking() override { }
-    // Note: isContinuousSpellCheckingEnabled() is implemented.
-    virtual bool isContinuousSpellCheckingEnabled() override;
-    virtual void toggleContinuousSpellChecking() override { }
-    virtual int spellCheckerDocumentTag() override { return 0; }
-#endif
 
     virtual bool smartInsertDeleteEnabled() override;
     virtual bool isSelectTrailingWhitespaceEnabled() override;
@@ -65,7 +60,7 @@ public:
     virtual bool shouldBeginEditing(WebCore::Range*) override;
     virtual bool shouldEndEditing(WebCore::Range*) override;
     virtual bool shouldInsertNode(WebCore::Node*, WebCore::Range*, WebCore::EditorInsertAction) override;
-    virtual bool shouldInsertText(const WTF::String&, WebCore::Range*, WebCore::EditorInsertAction) override;
+    virtual bool shouldInsertText(const String&, WebCore::Range*, WebCore::EditorInsertAction) override;
     virtual bool shouldChangeSelectedRange(WebCore::Range* fromRange, WebCore::Range* toRange, WebCore::EAffinity, bool stillSelecting) override;
 
     virtual bool shouldApplyStyle(WebCore::StyleProperties*, WebCore::Range*) override;
@@ -78,11 +73,11 @@ public:
     virtual void didWriteSelectionToPasteboard() override;
     virtual void getClientPasteboardDataForRange(WebCore::Range*, Vector<String>& pasteboardTypes, Vector<RefPtr<WebCore::SharedBuffer>>& pasteboardData) override;
 
-    virtual NSStringuserVisibleString(NSURL *) override;
+    virtual NSString *userVisibleString(NSURL *) override;
     virtual WebCore::DocumentFragment* documentFragmentFromAttributedString(NSAttributedString *, Vector< RefPtr<WebCore::ArchiveResource>>&) override;
     virtual void setInsertionPasteboard(const String&) override;
-    virtual NSURL* canonicalizeURL(NSURL*) override;
-    virtual NSURL* canonicalizeURLString(NSString*) override;
+    virtual NSURL *canonicalizeURL(NSURL *) override;
+    virtual NSURL *canonicalizeURLString(NSString *) override;
     
 #if USE(APPKIT)
     virtual void uppercaseWord() override;
@@ -110,7 +105,7 @@ public:
     virtual bool shouldShowDeleteInterface(WebCore::HTMLElement*) override;
 #endif
 
-    TextCheckerClient* textChecker() override { return this; }
+    virtual TextCheckerClient* textChecker() override { return this; }
 
     virtual void respondToChangedContents() override;
     virtual void respondToChangedSelection(WebCore::Frame*) override;
@@ -152,42 +147,24 @@ public:
     virtual int pasteboardChangeCount() override;
 #endif
     
-#if !PLATFORM(IOS)
     virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const override;
-    virtual void ignoreWordInSpellDocument(const WTF::String&) override;
-    virtual void learnWord(const WTF::String&) override;
-    virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) override;
-    virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&) override;
-    virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override;
+    virtual void ignoreWordInSpellDocument(const String&) override;
+    virtual void learnWord(const String&) override;
+    virtual void checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength) override;
+    virtual String getAutoCorrectSuggestionForMisspelledWord(const String&) override;
+    virtual void checkGrammarOfString(StringView, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override;
     virtual Vector<WebCore::TextCheckingResult> checkTextOfParagraph(StringView, WebCore::TextCheckingTypeMask checkingTypes) override;
-    virtual void updateSpellingUIWithGrammarString(const WTF::String&, const WebCore::GrammarDetail&) override;
-    virtual void updateSpellingUIWithMisspelledWord(const WTF::String&) override;
+    virtual void updateSpellingUIWithGrammarString(const String&, const WebCore::GrammarDetail&) override;
+    virtual void updateSpellingUIWithMisspelledWord(const String&) override;
     virtual void showSpellingUI(bool show) override;
     virtual bool spellingUIIsShowing() override;
-    virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses) override;
-#else
-    virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const override { return true; }
-    virtual void ignoreWordInSpellDocument(const WTF::String&) override { }
-    virtual void learnWord(const WTF::String&) override { }
-    virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) override { }
-    virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&) override { return ""; }
-    virtual void checkGrammarOfString(const UChar*, int length, WTF::Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override { }
-    virtual Vector<WebCore::TextCheckingResult> checkTextOfParagraph(StringView, WebCore::TextCheckingTypeMask checkingTypes) override;
-    virtual void updateSpellingUIWithGrammarString(const WTF::String&, const WebCore::GrammarDetail&) override { }
-    virtual void updateSpellingUIWithMisspelledWord(const WTF::String&) override { }
-    virtual void showSpellingUI(bool show) override { }
-    virtual bool spellingUIIsShowing() override { return false; }
-    virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses) override { }
-#endif // PLATFORM(IOS)
+    virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) override;
+
     virtual void willSetInputMethodState() override;
     virtual void setInputMethodState(bool enabled) override;
     virtual void requestCheckingOfString(PassRefPtr<WebCore::TextCheckingRequest>) override;
 
-    void didCheckSucceed(int sequence, NSArray* results);
-
-private:
     void registerUndoOrRedoStep(PassRefPtr<WebCore::UndoStep>, bool isRedo);
-    WebEditorClient();
 
     WebView *m_webView;
     RetainPtr<WebEditorUndoTarget> m_undoTarget;
@@ -199,3 +176,72 @@ private:
     bool m_hasDelayedContentChangeNotification;
 #endif
 };
+
+#if PLATFORM(IOS)
+
+inline bool WebEditorClient::isGrammarCheckingEnabled()
+{
+    return false;
+}
+
+inline void WebEditorClient::toggleGrammarChecking()
+{
+}
+
+inline void WebEditorClient::toggleContinuousSpellChecking()
+{
+}
+
+inline int WebEditorClient::spellCheckerDocumentTag()
+{
+    return 0;
+}
+
+inline bool WebEditorClient::shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const
+{
+    return true;
+}
+
+inline void WebEditorClient::ignoreWordInSpellDocument(const String&)
+{
+}
+
+inline void WebEditorClient::learnWord(const String&)
+{
+}
+
+inline void WebEditorClient::checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength)
+{
+}
+
+inline String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&)
+{
+    return "";
+}
+
+inline void WebEditorClient::checkGrammarOfString(StringView, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength)
+{
+}
+
+inline void WebEditorClient::updateSpellingUIWithGrammarString(const String&, const WebCore::GrammarDetail&)
+{
+}
+
+inline void WebEditorClient::updateSpellingUIWithMisspelledWord(const String&)
+{
+}
+
+inline void WebEditorClient::showSpellingUI(bool show)
+{
+}
+
+inline bool WebEditorClient::spellingUIIsShowing()
+{
+    return false;
+}
+
+inline void WebEditorClient::getGuessesForWord(const String&, const String&, Vector<String>&)
+{
+}
+
+#endif
index bbf428e..3285a28 100644 (file)
@@ -797,15 +797,8 @@ void WebEditorClient::textDidChangeInTextArea(Element* element)
     CallFormDelegate(m_webView, @selector(textDidChangeInTextArea:inFrame:), textAreaElement, kit(element->document().frame()));
 }
 
-static RetainPtr<NSString> nsStringWithoutCopying(StringView stringView)
-{
-    if (stringView.is8Bit())
-        return adoptNS([[NSString alloc] initWithBytesNoCopy:const_cast<LChar*>(stringView.characters8()) length:stringView.length() encoding:NSISOLatin1StringEncoding freeWhenDone:NO]);
-
-    return adoptNS([[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(stringView.characters16()) length:stringView.length() freeWhenDone:NO]);
-}
-
 #if PLATFORM(IOS)
+
 void WebEditorClient::suppressSelectionNotifications() 
 {
     m_selectionNotificationSuppressions++;
@@ -889,8 +882,7 @@ Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView stri
 
     Vector<TextCheckingResult> results;
 
-    auto textString = nsStringWithoutCopying(string);
-    NSArray *incomingResults = [[m_webView _UIKitDelegateForwarder] checkSpellingOfString:textString.get()];
+    NSArray *incomingResults = [[m_webView _UIKitDelegateForwarder] checkSpellingOfString:string.createNSStringWithoutCopying().get()];
     for (NSValue *incomingResult in incomingResults) {
         NSRange resultRange = [incomingResult rangeValue];
         ASSERT(resultRange.location != NSNotFound && resultRange.length > 0);
@@ -903,9 +895,11 @@ Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView stri
 
     return results;
 }
+
 #endif // PLATFORM(IOS)
 
 #if !PLATFORM(IOS)
+
 bool WebEditorClient::shouldEraseMarkersAfterChangeSelection(TextCheckingType type) const
 {
     // This prevents erasing spelling markers on OS X Lion or later to match AppKit on these Mac OS X versions.
@@ -914,8 +908,7 @@ bool WebEditorClient::shouldEraseMarkersAfterChangeSelection(TextCheckingType ty
 
 void WebEditorClient::ignoreWordInSpellDocument(const String& text)
 {
-    [[NSSpellChecker sharedSpellChecker] ignoreWord:text 
-                             inSpellDocumentWithTag:spellCheckerDocumentTag()];
+    [[NSSpellChecker sharedSpellChecker] ignoreWord:text inSpellDocumentWithTag:spellCheckerDocumentTag()];
 }
 
 void WebEditorClient::learnWord(const String& text)
@@ -923,11 +916,10 @@ void WebEditorClient::learnWord(const String& text)
     [[NSSpellChecker sharedSpellChecker] learnWord:text];
 }
 
-void WebEditorClient::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
+void WebEditorClient::checkSpellingOfString(StringView text, int* misspellingLocation, int* misspellingLength)
 {
-    NSString* textString = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(text) length:length freeWhenDone:NO];
-    NSRange range = [[NSSpellChecker sharedSpellChecker] checkSpellingOfString:textString startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:spellCheckerDocumentTag() wordCount:NULL];
-    [textString release];
+    NSRange range = [[NSSpellChecker sharedSpellChecker] checkSpellingOfString:text.createNSStringWithoutCopying().get() startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:spellCheckerDocumentTag() wordCount:NULL];
+
     if (misspellingLocation) {
         // WebCore expects -1 to represent "not found"
         if (range.location == NSNotFound)
@@ -947,12 +939,10 @@ String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&
     return String();
 }
 
-void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength)
+void WebEditorClient::checkGrammarOfString(StringView text, Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength)
 {
     NSArray *grammarDetails;
-    NSString* textString = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(text) length:length freeWhenDone:NO];
-    NSRange range = [[NSSpellChecker sharedSpellChecker] checkGrammarOfString:textString startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:spellCheckerDocumentTag() details:&grammarDetails];
-    [textString release];
+    NSRange range = [[NSSpellChecker sharedSpellChecker] checkGrammarOfString:text.createNSStringWithoutCopying().get() startingAt:0 language:nil wrap:NO inSpellDocumentWithTag:spellCheckerDocumentTag() details:&grammarDetails];
     if (badGrammarLocation)
         // WebCore expects -1 to represent "not found"
         *badGrammarLocation = (range.location == NSNotFound) ? -1 : static_cast<int>(range.location);
@@ -1057,11 +1047,7 @@ static Vector<TextCheckingResult> core(NSArray *incomingResults, TextCheckingTyp
 
 Vector<TextCheckingResult> WebEditorClient::checkTextOfParagraph(StringView string, TextCheckingTypeMask checkingTypes)
 {
-    auto textString = nsStringWithoutCopying(string);
-
-    NSArray *incomingResults = [[NSSpellChecker sharedSpellChecker] checkString:textString.get() range:NSMakeRange(0, [textString length]) types:(checkingTypes|NSTextCheckingTypeOrthography) options:nil inSpellDocumentWithTag:spellCheckerDocumentTag() orthography:NULL wordCount:NULL];
-
-    return core(incomingResults, checkingTypes);
+    return core([[NSSpellChecker sharedSpellChecker] checkString:string.createNSStringWithoutCopying().get() range:NSMakeRange(0, string.length()) types:(checkingTypes | NSTextCheckingTypeOrthography) options:nil inSpellDocumentWithTag:spellCheckerDocumentTag() orthography:NULL wordCount:NULL], checkingTypes);
 }
 
 void WebEditorClient::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
@@ -1116,6 +1102,7 @@ void WebEditorClient::getGuessesForWord(const String& word, const String& contex
             guesses.append(string);
     }
 }
+
 #endif // !PLATFORM(IOS)
 
 void WebEditorClient::willSetInputMethodState()
index 0eae15a..8471f4e 100644 (file)
@@ -94,7 +94,7 @@ using namespace WebCore;
 
 - (const unichar *)currentTextPointer
 {
-    return _private->_textIterator->characters();
+    return _private->_textIterator->deprecatedTextIteratorCharacters();
 }
 
 - (NSUInteger)currentTextLength
@@ -113,7 +113,7 @@ using namespace WebCore;
 
 - (NSString *)currentText
 {
-    return [NSString stringWithCharacters:_private->_textIterator->characters() length:_private->_textIterator->length()];
+    return [[_private->_textIterator->text().createNSString().get() retain] autorelease];
 }
 
 @end
index bcdc701..47bd524 100644 (file)
@@ -1,3 +1,15 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/WebEditorClient.cpp:
+        (WebEditorClient::checkSpellingOfString): Use StringView.
+        (WebEditorClient::checkGrammarOfString): Ditto.
+        * WebCoreSupport/WebEditorClient.h: Ditto.
+
 2014-02-06  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Add Console support to JSContext Inspection
index 43b3c15..01b23c8 100644 (file)
@@ -657,7 +657,7 @@ void WebEditorClient::learnWord(const String& word)
     ed->learnWord(BString(word));
 }
 
-void WebEditorClient::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
+void WebEditorClient::checkSpellingOfString(StringView text, int* misspellingLocation, int* misspellingLength)
 {
     *misspellingLocation = -1;
     *misspellingLength = 0;
@@ -667,7 +667,7 @@ void WebEditorClient::checkSpellingOfString(const UChar* text, int length, int*
         return;
 
     initViewSpecificSpelling(m_webView);
-    ed->checkSpellingOfString(m_webView, text, length, misspellingLocation, misspellingLength);
+    ed->checkSpellingOfString(m_webView, text.toStringWithoutCopying().deprecatedCharacters(), text.length(), misspellingLocation, misspellingLength);
 }
 
 String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String& inputWord)
@@ -677,7 +677,7 @@ String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&
     return String();
 }
 
-void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength)
+void WebEditorClient::checkGrammarOfString(StringView text, Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength)
 {
     details.clear();
     *badGrammarLocation = -1;
@@ -689,7 +689,7 @@ void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector
 
     initViewSpecificSpelling(m_webView);
     COMPtr<IEnumWebGrammarDetails> enumDetailsObj;
-    if (FAILED(ed->checkGrammarOfString(m_webView, text, length, &enumDetailsObj, badGrammarLocation, badGrammarLength)))
+    if (FAILED(ed->checkGrammarOfString(m_webView, text.toStringWithoutCopying().deprecatedCharacters(), text.length(), &enumDetailsObj, badGrammarLocation, badGrammarLength)))
         return;
 
     while (true) {
index 5eae04d..f317eea 100644 (file)
@@ -86,34 +86,34 @@ public:
     void undo();
     void redo();    
     
-    virtual bool shouldChangeSelectedRange(WebCore::Range* fromRange, WebCore::Range* toRange, WebCore::EAffinity, bool stillSelecting);
-    virtual void textFieldDidBeginEditing(WebCore::Element*);
-    virtual void textFieldDidEndEditing(WebCore::Element*);
-    virtual void textDidChangeInTextField(WebCore::Element*);
-    virtual bool doTextFieldCommandFromEvent(WebCore::Element*, WebCore::KeyboardEvent*);
-    virtual void textWillBeDeletedInTextField(WebCore::Element* input);
-    virtual void textDidChangeInTextArea(WebCore::Element*);
+    virtual bool shouldChangeSelectedRange(WebCore::Range* fromRange, WebCore::Range* toRange, WebCore::EAffinity, bool stillSelecting) override;
+    virtual void textFieldDidBeginEditing(WebCore::Element*) override;
+    virtual void textFieldDidEndEditing(WebCore::Element*) override;
+    virtual void textDidChangeInTextField(WebCore::Element*) override;
+    virtual bool doTextFieldCommandFromEvent(WebCore::Element*, WebCore::KeyboardEvent*) override;
+    virtual void textWillBeDeletedInTextField(WebCore::Element* input) override;
+    virtual void textDidChangeInTextArea(WebCore::Element*) override;
 
     void handleKeyboardEvent(WebCore::KeyboardEvent*);
     void handleInputMethodKeydown(WebCore::KeyboardEvent*);
 
-    virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const;
-    virtual void ignoreWordInSpellDocument(const WTF::String&);
-    virtual void learnWord(const WTF::String&);
-    virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength);
-    virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&);
-    virtual void checkGrammarOfString(const UChar*, int length, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength);
-    virtual void updateSpellingUIWithGrammarString(const WTF::String&, const WebCore::GrammarDetail& detail);
-    virtual void updateSpellingUIWithMisspelledWord(const WTF::String&);
-    virtual void showSpellingUI(bool show);
-    virtual bool spellingUIIsShowing();
-    virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses);
-
-    virtual void willSetInputMethodState();
-    virtual void setInputMethodState(bool);
-    virtual void requestCheckingOfString(WTF::PassRefPtr<WebCore::TextCheckingRequest>) { }
-
-    virtual WebCore::TextCheckerClient* textChecker() { return this; }
+    virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const override;
+    virtual void ignoreWordInSpellDocument(const WTF::String&) override;
+    virtual void learnWord(const WTF::String&) override;
+    virtual void checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength) override;
+    virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&) override;
+    virtual void checkGrammarOfString(StringView, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override;
+    virtual void updateSpellingUIWithGrammarString(const WTF::String&, const WebCore::GrammarDetail&) override;
+    virtual void updateSpellingUIWithMisspelledWord(const WTF::String&) override;
+    virtual void showSpellingUI(bool show) override;
+    virtual bool spellingUIIsShowing() override;
+    virtual void getGuessesForWord(const WTF::String& word, const WTF::String& context, WTF::Vector<WTF::String>& guesses) override;
+
+    virtual void willSetInputMethodState() override;
+    virtual void setInputMethodState(bool) override;
+    virtual void requestCheckingOfString(WTF::PassRefPtr<WebCore::TextCheckingRequest>) override { }
+
+    virtual WebCore::TextCheckerClient* textChecker() override { return this; }
 
 private:
     WebView* m_webView;
index b454fec..4d55818 100644 (file)
@@ -1,3 +1,15 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * WebCoreSupport/EditorClientWinCE.cpp:
+        (WebKit::EditorClientWinCE::checkSpellingOfString): Use StringView.
+        (WebKit::EditorClientWinCE::checkGrammarOfString): Ditto.
+        * WebCoreSupport/EditorClientWinCE.h: Ditto.
+
 2014-02-06  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Add Console support to JSContext Inspection
index 619bf97..7ebc82d 100644 (file)
@@ -466,7 +466,7 @@ void EditorClientWinCE::learnWord(const String& text)
     notImplemented();
 }
 
-void EditorClientWinCE::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
+void EditorClientWinCE::checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength)
 {
     notImplemented();
 }
@@ -478,7 +478,7 @@ String EditorClientWinCE::getAutoCorrectSuggestionForMisspelledWord(const String
     return String();
 }
 
-void EditorClientWinCE::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
+void EditorClientWinCE::checkGrammarOfString(StringVIew, Vector<GrammarDetail>&, int*, int*)
 {
     notImplemented();
 }
index 8ff760d..ed184d3 100644 (file)
@@ -90,9 +90,9 @@ public:
     virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const override;
     virtual void ignoreWordInSpellDocument(const WTF::String&) override;
     virtual void learnWord(const WTF::String&) override;
-    virtual void checkSpellingOfString(const UChar*, int, int*, int*) override;
+    virtual void checkSpellingOfString(StringView, int*, int*) override;
     virtual WTF::String getAutoCorrectSuggestionForMisspelledWord(const WTF::String&) override;
-    virtual void checkGrammarOfString(const UChar*, int, WTF::Vector<WebCore::GrammarDetail>&, int*, int*) override;
+    virtual void checkGrammarOfString(StringView, WTF::Vector<WebCore::GrammarDetail>&, int*, int*) override;
     virtual void updateSpellingUIWithGrammarString(const WTF::String&, const WebCore::GrammarDetail&) override;
     virtual void updateSpellingUIWithMisspelledWord(const WTF::String&) override;
     virtual void showSpellingUI(bool) override;
index 5995e53..e398b21 100644 (file)
@@ -1,3 +1,18 @@
+2014-02-08  Darin Adler  <darin@apple.com>
+
+        Change TextIterator to use StringView, preparing to wean it from deprecatedCharacters
+        https://bugs.webkit.org/show_bug.cgi?id=128233
+
+        Reviewed by Anders Carlsson.
+
+        * WebProcess/InjectedBundle/API/mac/WKDOMTextIterator.mm:
+        (-[WKDOMTextIterator currentTextPointer]): Call TextIterator::deprecatedTextIteratorCharacters.
+
+        * WebProcess/WebCoreSupport/WebEditorClient.cpp:
+        (WebKit::WebEditorClient::checkSpellingOfString): Use StringView.
+        (WebKit::WebEditorClient::checkGrammarOfString): Ditto.
+        * WebProcess/WebCoreSupport/WebEditorClient.h: Ditto.
+
 2014-02-08  Piotr Grad  <p.grad@samsung.com>
 
         [GTK] Build break in WebKitWebViewBase.cpp::webkitWebViewBaseCreateWebPage
index 83bfe6f..9c06af8 100644 (file)
@@ -69,7 +69,7 @@
 
 - (const unichar *)currentTextPointer
 {
-    return _textIterator->characters();
+    return _textIterator->deprecatedTextIteratorCharacters();
 }
 
 - (NSUInteger)currentTextLength
index 9059f1e..a4e1a74 100644 (file)
@@ -414,12 +414,11 @@ void WebEditorClient::learnWord(const String& word)
     m_page->send(Messages::WebPageProxy::LearnWord(word));
 }
 
-void WebEditorClient::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
+void WebEditorClient::checkSpellingOfString(StringView text, int* misspellingLocation, int* misspellingLength)
 {
     int32_t resultLocation = -1;
     int32_t resultLength = 0;
-    // FIXME: It would be nice if we wouldn't have to copy the text here.
-    m_page->sendSync(Messages::WebPageProxy::CheckSpellingOfString(String(text, length)),
+    m_page->sendSync(Messages::WebPageProxy::CheckSpellingOfString(text.toStringWithoutCopying()),
         Messages::WebPageProxy::CheckSpellingOfString::Reply(resultLocation, resultLength));
     *misspellingLocation = resultLocation;
     *misspellingLength = resultLength;
@@ -431,12 +430,11 @@ String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&)
     return String();
 }
 
-void WebEditorClient::checkGrammarOfString(const UChar* text, int length, Vector<WebCore::GrammarDetail>& grammarDetails, int* badGrammarLocation, int* badGrammarLength)
+void WebEditorClient::checkGrammarOfString(StringView text, Vector<WebCore::GrammarDetail>& grammarDetails, int* badGrammarLocation, int* badGrammarLength)
 {
     int32_t resultLocation = -1;
     int32_t resultLength = 0;
-    // FIXME: It would be nice if we wouldn't have to copy the text here.
-    m_page->sendSync(Messages::WebPageProxy::CheckGrammarOfString(String(text, length)),
+    m_page->sendSync(Messages::WebPageProxy::CheckGrammarOfString(text.toStringWithoutCopying()),
         Messages::WebPageProxy::CheckGrammarOfString::Reply(grammarDetails, resultLocation, resultLength));
     *badGrammarLocation = resultLocation;
     *badGrammarLength = resultLength;
index e816dff..c20f66f 100644 (file)
@@ -135,9 +135,9 @@ private:
     virtual bool shouldEraseMarkersAfterChangeSelection(WebCore::TextCheckingType) const override;
     virtual void ignoreWordInSpellDocument(const String&) override;
     virtual void learnWord(const String&) override;
-    virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) override;
+    virtual void checkSpellingOfString(StringView, int* misspellingLocation, int* misspellingLength) override;
     virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) override;
-    virtual void checkGrammarOfString(const UChar*, int length, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override;
+    virtual void checkGrammarOfString(StringView, Vector<WebCore::GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) override;
 #if USE(UNIFIED_TEXT_CHECKING)
     virtual Vector<WebCore::TextCheckingResult> checkTextOfParagraph(StringView, WebCore::TextCheckingTypeMask checkingTypes) override;
 #endif