haikuwebkit/Source/WebCore/editing/CharacterRange.h

97 lines
2.7 KiB
C
Raw Permalink Normal View History

Move TextIterator::rangeFromLocationAndLength off of live ranges https://bugs.webkit.org/show_bug.cgi?id=209408 Source/WebCore: Reviewed by Antti Koivisto. - Put CharacterRange into a header, CharacterRange.h. - Replaced CharacterOffset with direct uses of uint64_t. Because this can be a single offset into an entire document, use a 64-bit integer so we don't limit an entire document to 2^32 characters; in theory this makes it so we can support a document with tons of text nodes that add up to more than 2^32. - Because CharacterRange uses 64-bit integers we can now convert more easily to and from NSRange and CFRange on Cocoa platforms. * Headers.cmake: Added CharacterRange.h. * WebCore.xcodeproj/project.pbxproj: Ditto. * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm: (-[WebAccessibilityObjectWrapper _convertToDOMRange:]): Use CharacterRange, resolveCharacterLocation/Range. * accessibility/mac/WebAccessibilityObjectWrapperMac.mm: (AXAttributeStringSetSpelling): Ditto. (-[WebAccessibilityObjectWrapper _textMarkerForIndex:]): Ditto. * dom/DocumentMarkerController.cpp: (WebCore::DocumentMarkerController::collectTextRanges): Take SimpleRange. (WebCore::DocumentMarkerController::addMarker): Ditto. (WebCore::DocumentMarkerController::addDictationResultMarker): Ditto. (WebCore::DocumentMarkerController::addPlatformTextCheckingMarker): Ditto. * dom/DocumentMarkerController.h: Updated for above changes. * dom/Position.h: Export createLegacyEditingPosition so it can be used outside of WebCore. * dom/SimpleRange.cpp: (WebCore::fastIsCharacterData): Added. Could be moved to the Node class. (WebCore::length): Added. Could be moved to the Node class. (WebCore::makeRangeSelectingNodeContents): Added. Analogous to the Range::selectNodeContents function. * dom/SimpleRange.h: Updated for the above. * editing/AlternativeTextController.cpp: (WebCore::AlternativeTextController::applyAlternativeTextToRange): Use CharacterRange, resolveCharacterLocation/Range. * editing/ApplyStyleCommand.cpp: (WebCore::ApplyStyleCommand::applyBlockStyle): Ditto. * editing/CharacterRange.h: Added. * editing/CompositeEditCommand.cpp: (WebCore::CompositeEditCommand::moveParagraphs): Use CharacterRange, resolveCharacterLocation/Range. * editing/Editing.cpp: (WebCore::visiblePositionForIndex): Ditto. * editing/Editor.cpp: (WebCore::Editor::advanceToNextMisspelling): Ditto. (WebCore::correctSpellcheckingPreservingTextCheckingParagraph): Ditto. (WebCore::Editor::markAndReplaceFor): Ditto. (WebCore::Editor::changeBackToReplacedString): Ditto. (WebCore::Editor::scanRangeForTelephoneNumbers): Ditto. (WebCore::Editor::rangeForTextCheckingResult const): Ditto. * editing/TextCheckingHelper.cpp: (WebCore::findGrammaticalErrors): Ditto. (WebCore::findMisspellings): Ditto. (WebCore::TextCheckingParagraph::invalidateParagraphRangeValues): Ditto. (WebCore::TextCheckingParagraph::rangeLength const): Ditto. (WebCore::TextCheckingParagraph::subrange const): Ditto. (WebCore::TextCheckingParagraph::offsetTo const): Ditto. (WebCore::TextCheckingParagraph::text const): Ditto. Also use StringView. (WebCore::TextCheckingParagraph::checkingStart const): Ditto. (WebCore::TextCheckingParagraph::checkingEnd const): Ditto. Also compute this by adding start and length, and don't cache it. (WebCore::TextCheckingParagraph::checkingLength const): Ditto. (WebCore::TextCheckingParagraph::automaticReplacementStart const): Ditto. (WebCore::TextCheckingParagraph::automaticReplacementLength const): Ditto. (WebCore::TextCheckingHelper::findFirstMisspelling): Ditto. (WebCore::TextCheckingHelper::findFirstMisspellingOrBadGrammar): Ditto. (WebCore::TextCheckingHelper::findFirstGrammarDetail const): Ditto. (WebCore::TextCheckingHelper::findFirstBadGrammar const): Ditto. (WebCore::TextCheckingHelper::isUngrammatical const): Ditto. (WebCore::TextCheckingHelper::guessesForMisspelledOrUngrammaticalRange const): Ditto. (WebCore::TextCheckingHelper::markAllMisspellings): Ditto. (WebCore::TextCheckingHelper::markAllBadGrammar): Ditto. (WebCore::checkTextOfParagraph): Ditto. * editing/TextCheckingHelper.h: Updated for the above. Also got rid of m_checkingEnd since it's sufficient to cache the start and the length. Should come back later and use CharacterRange instead of 2x CharacterCount. * editing/TextIterator.cpp: (WebCore::characterCount): Use uint64_t. (WebCore::TextIterator::subrange): Deleted. (WebCore::TextIterator::rangeFromLocationAndLength): Deleted. (WebCore::clampedAdd): Added. Helps implement resolveCharacterRange in a way that can work with any character count without concern about overflow. (WebCore::resolveCharacterRange): Added. Replaces both subrange and rangeFromLocationAndLength, using an algorithm close to the one from the latter function, including workarounds it had. Replaced the boolean "forSelectionPreservation" with the TextIteratorBehavior options, which seems to make good sense at all the call sites. (WebCore::resolveCharacterLocation): Added. Like resolveCharacterRange, but instead of resolving CharacterRange to SimpleRange, resolves a character location to a BoundaryPoint. Made a separate function for this in case we later refactor for efficiency, but for now this simply calls resolveCharacterRange with a zero length range. * editing/TextIterator.h: Moved CharacterCount and CharagerRange into a separate header. Replaced TextIterator::rangeFromLocationAndLength and TextIterator::subrange with resolveCharacterLocation and resolveCharacterRange. * editing/cocoa/DataDetection.mm: (WebCore::detectItemAtPositionWithRange): Use CharacterRange, resolveCharacterLocation/Range. (WebCore::DataDetection::detectContentInRange): Ditto. * editing/cocoa/DictionaryLookup.mm: (WebCore::DictionaryLookup::rangeForSelection): Ditto. (WebCore::DictionaryLookup::rangeAtHitTestResult): Ditto. * editing/ios/DictationCommandIOS.cpp: (WebCore::DictationCommandIOS::doApply): Ditto. * editing/mac/DictionaryLookupLegacy.mm: (WebCore::DictionaryLookup::rangeAtHitTestResult): Ditto. * page/EventHandler.cpp: (WebCore::textDistance): Ditto. * page/Page.cpp: (WebCore::replaceRanges): Ditto. (WebCore::Page::replaceRangesWithText): Ditto. * platform/text/TextChecking.h: Ditto. * testing/Internals.cpp: (WebCore::Internals::rangeFromLocationAndLength): Ditto. (WebCore::Internals::subrange): Ditto. (WebCore::Internals::handleAcceptedCandidate): Ditto. * testing/Internals.h: Made location and length unsigned rather than signed. * testing/Internals.idl: Ditto. Source/WebKit: Reviewed by Antti Koivisto. * Shared/EditingRange.cpp: (WebKit::EditingRange::toRange): Use CharacterRange, resolveCharacterLocation/Range. * Shared/EditingRange.h: Added a FIXME about replacing with CharacterRange. * Shared/WebCoreArgumentCoders.cpp: (IPC::ArgumentCoder<CharacterRange>::encode): Added. (IPC::ArgumentCoder<CharacterRange>::decode): Added. (IPC::ArgumentCoder<GrammarDetail>::encode): Updated to use CharacterRange. (IPC::ArgumentCoder<GrammarDetail>::decode): Ditto. (IPC::ArgumentCoder<TextCheckingResult>::encode): Ditto. (IPC::ArgumentCoder<TextCheckingResult>::decode): Ditto. * Shared/WebCoreArgumentCoders.h: Added CharacterRange. * UIProcess/Cocoa/WebViewImpl.mm: (WebKit::textCheckingResultFromNSTextCheckingResult): Use CharacterRange, resolveCharacterLocation/Range. * UIProcess/WebGrammarDetail.cpp: (WebKit::WebGrammarDetail::WebGrammarDetail): Ditto. * UIProcess/WebGrammarDetail.h: (WebKit::WebGrammarDetail::location const): Ditto. (WebKit::WebGrammarDetail::length const): Ditto. * UIProcess/gtk/TextCheckerGtk.cpp: (WebKit::TextChecker::checkTextOfParagraph): Ditto. * UIProcess/ios/TextCheckerIOS.mm: (WebKit::TextChecker::checkTextOfParagraph): Ditto. * UIProcess/mac/TextCheckerMac.mm: (WebKit::TextChecker::checkTextOfParagraph): Ditto. (WebKit::TextChecker::updateSpellingUIWithGrammarString): Ditto. * WebProcess/WebPage/Cocoa/TextCheckingControllerProxy.mm: (WebKit::TextCheckingControllerProxy::rangeAndOffsetRelativeToSelection): Ditto. (WebKit::TextCheckingControllerProxy::replaceRelativeToSelection): Ditto. (WebKit::TextCheckingControllerProxy::annotatedSubstringBetweenPositions): Ditto. * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::deleteSurrounding): Ditto. * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::getPlatformEditorState const): Small tweak. (WebKit::WebPage::updateSelectionWithDelta): Ditto. (WebKit::WebPage::requestDocumentEditingContext): Ditto. Source/WebKitLegacy/mac: Reviewed by Antti Koivisto. * WebCoreSupport/WebEditorClient.mm: (WebEditorClient::checkTextOfParagraph): Use CharacterRange, resolveCharacterLocation/Range. (WebEditorClient::checkGrammarOfString): Ditto. (core): Ditto. (WebEditorClient::updateSpellingUIWithGrammarString): Ditto. (WebEditorClient::handleAcceptedCandidateWithSoftSpaces): Ditto. * WebView/WebFrame.mm: (-[WebFrame _convertToDOMRange:rangeIsRelativeTo:]): Ditto. * WebView/WebView.mm: (textCheckingResultFromNSTextCheckingResult): Ditto. Source/WebKitLegacy/win: Reviewed by Antti Koivisto. * WebCoreSupport/WebEditorClient.cpp: (WebEditorClient::checkGrammarOfString): Use CharacterRange, resolveCharacterLocation/Range. (WebEditorClient::updateSpellingUIWithGrammarString): Ditto. * WebView.cpp: (WebView::firstRectForCharacterRangeForTesting): Ditto. LayoutTests: Fix Mac-specific firstrectforcharacterrange-styled.html test https://bugs.webkit.org/show_bug.cgi?id=205314 <rdar://problem/57990717> Reviewed by Antti Koivisto. * accessibility/mac/textmarker-for-index-out-of-bounds-crash-expected.txt: * accessibility/mac/textmarker-for-index-out-of-bounds-crash.html: Updated to expect textMarkerForIndex to clamp rather than returning something invalid. * editing/mac/input/firstrectforcharacterrange-plain-expected.txt: * editing/mac/input/firstrectforcharacterrange-plain.html: Updated test output to include what is being tested, not just the test result. Updated test results to expect clamping rather than an empty rectangle, for values that are out of bounds. Also got rid of dumping of eidting callbacks since there is no reason to include them in this test. * editing/mac/input/firstrectforcharacterrange-styled-expected.txt: * editing/mac/input/firstrectforcharacterrange-styled.html: Ditto. * platform/mac-wk1/TestExpectations: Since our oldest supported release is Mojave, deleted all rules with Sierra or HighSierra conditionals since those conditions are always false, and removed any conditionals that said Sierra+, HighSierra+, or Mojave+ because those conditions are always true. One test, firstrectforcharacterrange-styled.html, had results checked in that were correct for Mojave but incorrect for Catalina. For that test, the results are now correct for Catalina, so updated expectations for that. * platform/mac-wk2/TestExpectations: Ditto. Also some tests that claimed ImageOnlyFailure are flaky and sometimes passing, so marked them for either Pass or ImageOnlyFailure. * platform/mac/TestExpectations: Ditto. Also some tests marked Failure were flaky and sometimes passing, so marked them for either Pass or Failure. * platform/mac/editing/mac/input/firstrectforcharacterrange-styled-expected.txt: Removed. This is already a Mac-specific test; it doesn't make sense to have an additional Mac-specific overridden result since the base result is already Mac-specific. * platform/mac/fast/text/attributed-substring-from-range-001-expected.txt: * platform/mac/fast/text/attributed-substring-from-range-001.html: Updated this test to expect the empty string, not "undefined" for an out of range, since we now clamp instead of failing in such cases. * platform/mac/fast/text/attributed-substring-from-range-expected.txt: * platform/mac/fast/text/attributed-substring-from-range.html: Ditto. Canonical link: https://commits.webkit.org/222649@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@259184 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2020-03-30 01:06:28 +00:00
/*
* Copyright (C) 2020 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. ``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
* 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.
*/
#pragma once
#if USE(CF)
#include <CoreFoundation/CoreFoundation.h>
#endif
#if USE(FOUNDATION)
typedef struct _NSRange NSRange;
#endif
namespace WebCore {
struct CharacterRange {
uint64_t location { 0 };
uint64_t length { 0 };
CharacterRange() = default;
constexpr CharacterRange(uint64_t location, uint64_t length);
#if USE(CF)
constexpr CharacterRange(CFRange);
constexpr operator CFRange() const;
#endif
#if USE(FOUNDATION)
constexpr CharacterRange(NSRange);
constexpr operator NSRange() const;
#endif
};
constexpr CharacterRange::CharacterRange(uint64_t location, uint64_t length)
: location(location)
, length(length)
{
}
#if USE(CF)
constexpr CharacterRange::CharacterRange(CFRange range)
: CharacterRange(range.location, range.length)
{
ASSERT(range.location != kCFNotFound);
}
constexpr CharacterRange::operator CFRange() const
{
CFIndex locationCF = location;
CFIndex lengthCF = length;
return { locationCF, lengthCF };
}
#endif
#if USE(FOUNDATION) && defined(__OBJC__)
constexpr CharacterRange::CharacterRange(NSRange range)
: CharacterRange { range.location, range.length }
{
ASSERT(range.location != NSNotFound);
}
constexpr CharacterRange::operator NSRange() const
{
NSUInteger locationNS = location;
NSUInteger lengthNS = length;
return { locationNS, lengthNS };
}
#endif
} // namespace WebCore