Diff
Modified: trunk/Source/WebCore/ChangeLog (278541 => 278542)
--- trunk/Source/WebCore/ChangeLog 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/ChangeLog 2021-06-07 04:11:09 UTC (rev 278542)
@@ -1,3 +1,107 @@
+2021-06-06 Wenson Hsieh <[email protected]>
+
+ Turn TextIteratorBehaviorFlag into an enum class and wrap it in OptionSet
+ https://bugs.webkit.org/show_bug.cgi?id=226691
+
+ Reviewed by Darin Adler.
+
+ Modernize some editing code by turning `TextIteratorBehaviorFlag` into an enum class, `TextIteratorBehavior`,
+ with an explicit width of 16 bits. Additionally, since this is a bitmask, refactor various codepaths to use
+ `OptionSet<TextIteratorBehavior>` instead of the underlying type.
+
+ This gives us improved type safety when using this enum, and also narrows the width of this enum to 16 bits
+ (from 32). No change in behavior.
+
+ * accessibility/AXObjectCache.cpp:
+ (WebCore::AXObjectCache::traverseToOffsetInRange):
+ (WebCore::AXObjectCache::rangeMatchesTextNearRange):
+ (WebCore::AXObjectCache::nextBoundary):
+ * accessibility/AccessibilityObject.cpp:
+ (WebCore::AccessibilityObject::textIteratorBehaviorForTextRange const):
+ * accessibility/AccessibilityObject.h:
+ * accessibility/AccessibilityObjectInterface.h:
+ * accessibility/atk/WebKitAccessibleHyperlink.cpp:
+ (rangeLengthForObject):
+ * accessibility/atk/WebKitAccessibleInterfaceText.cpp:
+ (getSelectionOffsetsForObject):
+ * accessibility/atk/WebKitAccessibleUtil.cpp:
+ (objectFocusedAndCaretOffsetUnignored):
+ * accessibility/isolatedtree/AXIsolatedObject.cpp:
+ (WebCore::AXIsolatedObject::textIteratorBehaviorForTextRange const):
+
+ Fix this method to return the empty (default) option set instead of `false` (which was previously implicitly
+ converted to `TextIteratorDefaultBehavior`).
+
+ * accessibility/isolatedtree/AXIsolatedObject.h:
+ * editing/ApplyStyleCommand.cpp:
+ (WebCore::ApplyStyleCommand::applyBlockStyle):
+ * editing/CompositeEditCommand.cpp:
+ (WebCore::CompositeEditCommand::moveParagraphs):
+ * editing/Editing.cpp:
+ (WebCore::indexForVisiblePosition):
+ (WebCore::visiblePositionForIndex):
+ * editing/Editor.cpp:
+ (WebCore::Editor::selectedText const):
+ (WebCore::Editor::selectedTextForDataTransfer const):
+ * editing/Editor.h:
+ * editing/ReplaceSelectionCommand.cpp:
+ (WebCore::ReplacementFragment::ReplacementFragment):
+ * editing/TextIterator.cpp:
+ (WebCore::isClippedByFrameAncestor):
+ (WebCore::TextIterator::TextIterator):
+ (WebCore::TextIterator::init):
+ (WebCore::firstChild):
+ (WebCore::nextSibling):
+ (WebCore::nextNode):
+ (WebCore::isDescendantOf):
+ (WebCore::parentNodeOrShadowHost):
+ (WebCore::TextIterator::advance):
+ (WebCore::TextIterator::handleTextNode):
+ (WebCore::TextIterator::handleTextRun):
+ (WebCore::TextIterator::handleTextNodeFirstLetter):
+ (WebCore::TextIterator::handleReplacedElement):
+ (WebCore::TextIterator::shouldRepresentNodeOffsetZero):
+ (WebCore::TextIterator::shouldEmitSpaceBeforeAndAfterNode):
+ (WebCore::TextIterator::handleNonTextNode):
+ (WebCore::TextIterator::exitNode):
+ (WebCore::TextIterator::emitText):
+ (WebCore::SimplifiedBackwardsTextIterator::handleNonTextNode):
+ (WebCore::SimplifiedBackwardsTextIterator::exitNode):
+ (WebCore::CharacterIterator::CharacterIterator):
+ (WebCore::characterCount):
+ (WebCore::resolveCharacterRange):
+ (WebCore::hasAnyPlainText):
+ (WebCore::plainText):
+ (WebCore::plainTextReplacingNoBreakSpace):
+ (WebCore::findIteratorOptions):
+ * editing/TextIterator.h:
+ (WebCore::characterCount):
+ (WebCore::characterRange):
+ (WebCore::resolveCharacterLocation):
+ (WebCore::resolveCharacterRange):
+ (WebCore::plainText):
+ (WebCore::hasAnyPlainText):
+ (WebCore::plainTextReplacingNoBreakSpace):
+ (WebCore::TextIterator::TextIterator):
+ (WebCore::CharacterIterator::CharacterIterator):
+ * editing/TextIteratorBehavior.h:
+
+ Add an alias for `OptionSet<TextIteratorBehavior>`, `TextIteratorBehaviors`, to help with readability when
+ specifying or consulting these flags. Additionally remove the `TextIteratorDefaultBehavior` enum value
+ altogether, since we can now just use the default constructor (`OptionSet<TextIteratorBehavior> { }`) to get a
+ set of empty options.
+
+ * editing/TextManipulationController.cpp:
+ (WebCore::ParagraphContentIterator::ParagraphContentIterator):
+ * editing/VisibleSelection.cpp:
+ (WebCore::VisibleSelection::appendTrailingWhitespace):
+ * editing/VisibleUnits.cpp:
+ (WebCore::nextBoundary):
+ * editing/markup.cpp:
+ (WebCore::StyledMarkupAccumulator::renderedTextRespectingRange):
+ * page/EventHandler.cpp:
+ (WebCore::textDistance):
+
2021-06-06 Chris Dumez <[email protected]>
Flaky assertion hit in AudioSessionRoutingArbitratorProxy::endRoutingArbitration()
Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (278541 => 278542)
--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -1919,7 +1919,10 @@
bool finished = false;
int lastStartOffset = 0;
- TextIterator iterator(range, doNotEnterTextControls ? TextIteratorDefaultBehavior : TextIteratorEntersTextControls);
+ TextIteratorBehaviors behaviors;
+ if (!doNotEnterTextControls)
+ behaviors.add(TextIteratorBehavior::EntersTextControls);
+ TextIterator iterator(range, behaviors);
// When the range has zero length, there might be replaced node or brTag that we need to increment the characterOffset.
if (iterator.atEnd()) {
@@ -2077,7 +2080,7 @@
if (!searchRange || searchRange->collapsed())
return std::nullopt;
- auto targetOffset = characterCount({ searchRange->start, originalRange.start }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ auto targetOffset = characterCount({ searchRange->start, originalRange.start }, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
return findClosestPlainText(*searchRange, matchText, { }, targetOffset);
}
@@ -2715,7 +2718,7 @@
return { };
CharacterOffset end = startOrEndCharacterOffsetForRange(searchRange, false);
- TextIterator it(searchRange, TextIteratorEmitsObjectReplacementCharacters);
+ TextIterator it(searchRange, TextIteratorBehavior::EmitsObjectReplacementCharacters);
unsigned next = forwardSearchForBoundaryWithTextIterator(it, string, prefixLength, searchFunction);
if (it.atEnd() && next == string.size())
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.cpp (278541 => 278542)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -3182,17 +3182,17 @@
return !getAttribute(aria_pressedAttr).isEmpty();
}
-TextIteratorBehavior AccessibilityObject::textIteratorBehaviorForTextRange() const
+TextIteratorBehaviors AccessibilityObject::textIteratorBehaviorForTextRange() const
{
- TextIteratorBehavior behavior = TextIteratorIgnoresStyleVisibility;
+ TextIteratorBehaviors behaviors { TextIteratorBehavior::IgnoresStyleVisibility };
#if USE(ATK)
// We need to emit replaced elements for GTK, and present
// them with the 'object replacement character' (0xFFFC).
- behavior = static_cast<TextIteratorBehavior>(behavior | TextIteratorEmitsObjectReplacementCharacters);
+ behaviors.add(TextIteratorBehavior::EmitsObjectReplacementCharacters);
#endif
- return behavior;
+ return behaviors;
}
AccessibilityRole AccessibilityObject::buttonRoleType() const
Modified: trunk/Source/WebCore/accessibility/AccessibilityObject.h (278541 => 278542)
--- trunk/Source/WebCore/accessibility/AccessibilityObject.h 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/AccessibilityObject.h 2021-06-07 04:11:09 UTC (rev 278542)
@@ -430,7 +430,7 @@
Path elementPath() const override { return Path(); }
bool supportsPath() const override { return false; }
- TextIteratorBehavior textIteratorBehaviorForTextRange() const override;
+ TextIteratorBehaviors textIteratorBehaviorForTextRange() const override;
PlainTextRange selectedTextRange() const override { return { }; }
int insertionPointLineNumber() const override { return -1; }
Modified: trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h (278541 => 278542)
--- trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/AccessibilityObjectInterface.h 2021-06-07 04:11:09 UTC (rev 278542)
@@ -1172,7 +1172,7 @@
virtual Path elementPath() const = 0;
virtual bool supportsPath() const = 0;
- virtual TextIteratorBehavior textIteratorBehaviorForTextRange() const = 0;
+ virtual TextIteratorBehaviors textIteratorBehaviorForTextRange() const = 0;
virtual PlainTextRange selectedTextRange() const = 0;
virtual int insertionPointLineNumber() const = 0;
Modified: trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp (278541 => 278542)
--- trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/atk/WebKitAccessibleHyperlink.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -157,7 +157,7 @@
return 0;
// This is going to be the actual length in most of the cases
- int baseLength = characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ int baseLength = characterCount(*range, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
// Check whether the current hyperlink belongs to a list item.
// If so, we need to consider the length of the item's marker
Modified: trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp (278541 => 278542)
--- trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/atk/WebKitAccessibleInterfaceText.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -407,9 +407,9 @@
// Set values for start offsets and calculate initial range length.
// These values might be adjusted later to cover special cases.
- startOffset = webCoreOffsetToAtkOffset(coreObject, characterCount(rangeInParent, TextIteratorEmitsCharactersBetweenAllVisiblePositions));
+ startOffset = webCoreOffsetToAtkOffset(coreObject, characterCount(rangeInParent, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions));
auto nodeRange = *makeSimpleRange(nodeRangeStart, nodeRangeEnd);
- int rangeLength = characterCount(nodeRange, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ int rangeLength = characterCount(nodeRange, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
// Special cases that are only relevant when working with *_END boundaries.
if (selection.affinity() == Affinity::Upstream) {
Modified: trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp (278541 => 278542)
--- trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/atk/WebKitAccessibleUtil.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -230,10 +230,10 @@
offset = 0;
else if (!isStartOfLine(endPosition)) {
auto range = makeSimpleRange(startPosition, endPosition.previous());
- offset = (range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0) + 1;
+ offset = (range ? characterCount(*range, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions) : 0) + 1;
} else {
auto range = makeSimpleRange(startPosition, endPosition);
- offset = range ? characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions) : 0;
+ offset = range ? characterCount(*range, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions) : 0;
}
return firstUnignoredParent;
Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (278541 => 278542)
--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -2020,10 +2020,10 @@
return nullptr;
}
-TextIteratorBehavior AXIsolatedObject::textIteratorBehaviorForTextRange() const
+TextIteratorBehaviors AXIsolatedObject::textIteratorBehaviorForTextRange() const
{
ASSERT_NOT_REACHED();
- return false;
+ return { };
}
Widget* AXIsolatedObject::widget() const
Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (278541 => 278542)
--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h 2021-06-07 04:11:09 UTC (rev 278542)
@@ -568,7 +568,7 @@
Element* actionElement() const override;
Path elementPath() const override { return pathAttributeValue(AXPropertyName::Path); };
bool supportsPath() const override { return boolAttributeValue(AXPropertyName::SupportsPath); }
- TextIteratorBehavior textIteratorBehaviorForTextRange() const override;
+ TextIteratorBehaviors textIteratorBehaviorForTextRange() const override;
Widget* widget() const override;
PlatformWidget platformWidget() const override;
Modified: trunk/Source/WebCore/editing/ApplyStyleCommand.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/ApplyStyleCommand.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -248,8 +248,8 @@
auto scope = makeRangeSelectingNodeContents(*scopeRoot);
auto range = *makeSimpleRange(visibleStart, visibleEnd);
- auto startIndex = characterCount({ scope.start, range.start }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
- auto endIndex = characterCount({ scope.start, range.end }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ auto startIndex = characterCount({ scope.start, range.start }, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
+ auto endIndex = characterCount({ scope.start, range.end }, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
VisiblePosition paragraphStart(startOfParagraph(visibleStart));
VisiblePosition nextParagraphStart(endOfParagraph(paragraphStart).next());
@@ -280,8 +280,8 @@
nextParagraphStart = endOfParagraph(paragraphStart).next();
}
- auto startPosition = makeDeprecatedLegacyPosition(resolveCharacterLocation(scope, startIndex, TextIteratorEmitsCharactersBetweenAllVisiblePositions));
- auto endPosition = makeDeprecatedLegacyPosition(resolveCharacterLocation(scope, endIndex, TextIteratorEmitsCharactersBetweenAllVisiblePositions));
+ auto startPosition = makeDeprecatedLegacyPosition(resolveCharacterLocation(scope, startIndex, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions));
+ auto endPosition = makeDeprecatedLegacyPosition(resolveCharacterLocation(scope, endIndex, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions));
updateStartEnd(startPosition, endPosition);
}
Modified: trunk/Source/WebCore/editing/CompositeEditCommand.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/CompositeEditCommand.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -1443,12 +1443,12 @@
startIndex = 0;
if (visibleStart >= startOfParagraphToMove) {
if (auto rangeToSelectionStart = makeSimpleRange(startOfParagraphToMove, visibleStart))
- startIndex = characterCount(*rangeToSelectionStart, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ startIndex = characterCount(*rangeToSelectionStart, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
}
endIndex = 0;
if (visibleEnd <= endOfParagraphToMove) {
if (auto rangeToSelectionEnd = makeSimpleRange(startOfParagraphToMove, visibleEnd))
- endIndex = characterCount(*rangeToSelectionEnd, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ endIndex = characterCount(*rangeToSelectionEnd, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
}
}
}
@@ -1517,7 +1517,7 @@
if (!editableRoot)
editableRoot = &document();
- auto destinationIndex = characterCount({ { *editableRoot, 0 }, *makeBoundaryPoint(destination) }, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ auto destinationIndex = characterCount({ { *editableRoot, 0 }, *makeBoundaryPoint(destination) }, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
setEndingSelection(VisibleSelection(destination, originalIsDirectional));
ASSERT(endingSelection().isCaretOrRange());
@@ -1539,8 +1539,8 @@
// causes spaces to be collapsed during the move operation. This results
// in a call to rangeFromLocationAndLength with a location past the end
// of the document (which will return null).
- auto start = makeDeprecatedLegacyPosition(resolveCharacterLocation(makeRangeSelectingNodeContents(*editableRoot), destinationIndex + *startIndex, TextIteratorEmitsCharactersBetweenAllVisiblePositions));
- auto end = makeDeprecatedLegacyPosition(resolveCharacterLocation(makeRangeSelectingNodeContents(*editableRoot), destinationIndex + *endIndex, TextIteratorEmitsCharactersBetweenAllVisiblePositions));
+ auto start = makeDeprecatedLegacyPosition(resolveCharacterLocation(makeRangeSelectingNodeContents(*editableRoot), destinationIndex + *startIndex, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions));
+ auto end = makeDeprecatedLegacyPosition(resolveCharacterLocation(makeRangeSelectingNodeContents(*editableRoot), destinationIndex + *endIndex, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions));
setEndingSelection({ start, end, Affinity::Downstream, originalIsDirectional });
}
}
Modified: trunk/Source/WebCore/editing/Editing.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/Editing.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/Editing.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -964,10 +964,10 @@
return newSelection;
}
-// FIXME: indexForVisiblePosition and visiblePositionForIndex use TextIterators to convert between
-// VisiblePositions and indices. But TextIterator iteration using TextIteratorEmitsCharactersBetweenAllVisiblePositions
-// does not exactly match VisiblePosition iteration, so using them to preserve a selection during an editing
-// opertion is unreliable. TextIterator's TextIteratorEmitsCharactersBetweenAllVisiblePositions mode needs to be fixed,
+// FIXME: indexForVisiblePosition and visiblePositionForIndex use TextIterators to convert between
+// VisiblePositions and indices. But TextIterator iteration using TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions
+// does not exactly match VisiblePosition iteration, so using them to preserve a selection during an editing
+// opertion is unreliable. TextIterator's TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions mode needs to be fixed,
// or these functions need to be changed to iterate using actual VisiblePositions.
// FIXME: Deploy these functions everywhere that TextIterators are used to convert between VisiblePositions and indices.
int indexForVisiblePosition(const VisiblePosition& visiblePosition, RefPtr<ContainerNode>& scope)
@@ -989,7 +989,7 @@
}
auto range = *makeSimpleRange(makeBoundaryPointBeforeNodeContents(*scope), position);
- return characterCount(range, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ return characterCount(range, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
}
// FIXME: Merge this function with the one above.
@@ -996,7 +996,10 @@
int indexForVisiblePosition(Node& node, const VisiblePosition& visiblePosition, bool forSelectionPreservation)
{
auto range = makeSimpleRange(makeBoundaryPointBeforeNodeContents(node), visiblePosition);
- return range ? characterCount(*range, forSelectionPreservation ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior) : 0;
+ TextIteratorBehaviors behaviors;
+ if (forSelectionPreservation)
+ behaviors.add(TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
+ return range ? characterCount(*range, behaviors) : 0;
}
VisiblePosition visiblePositionForPositionWithOffset(const VisiblePosition& position, int offset)
@@ -1013,7 +1016,7 @@
{
if (!scope)
return { };
- return { makeDeprecatedLegacyPosition(resolveCharacterLocation(makeRangeSelectingNodeContents(*scope), index, TextIteratorEmitsCharactersBetweenAllVisiblePositions)) };
+ return { makeDeprecatedLegacyPosition(resolveCharacterLocation(makeRangeSelectingNodeContents(*scope), index, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions)) };
}
VisiblePosition visiblePositionForIndexUsingCharacterIterator(Node& node, int index)
Modified: trunk/Source/WebCore/editing/Editor.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/Editor.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/Editor.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -3280,25 +3280,25 @@
String Editor::selectedText() const
{
- TextIteratorBehavior behavior = TextIteratorDefaultBehavior;
+ TextIteratorBehaviors behaviors;
if (m_document.settings().selectionAcrossShadowBoundariesEnabled())
- behavior |= TextIteratorTraversesFlatTree;
- return selectedText(behavior);
+ behaviors.add(TextIteratorBehavior::TraversesFlatTree);
+ return selectedText(behaviors);
}
String Editor::selectedTextForDataTransfer() const
{
- TextIteratorBehavior behavior = TextIteratorEmitsImageAltText;
+ TextIteratorBehaviors behaviors { TextIteratorBehavior::EmitsImageAltText };
if (m_document.settings().selectionAcrossShadowBoundariesEnabled())
- behavior |= TextIteratorTraversesFlatTree;
- return selectedText(behavior);
+ behaviors.add(TextIteratorBehavior::TraversesFlatTree);
+ return selectedText(behaviors);
}
-String Editor::selectedText(TextIteratorBehavior behavior) const
+String Editor::selectedText(TextIteratorBehaviors behaviors) const
{
// We remove '\0' characters because they are not visibly rendered to the user.
auto range = m_document.selection().selection().firstRange();
- return range ? plainText(*range, behavior).replaceWithLiteral('\0', "") : emptyString();
+ return range ? plainText(*range, behaviors).replaceWithLiteral('\0', "") : emptyString();
}
RefPtr<TextPlaceholderElement> Editor::insertTextPlaceholder(const IntSize& size)
Modified: trunk/Source/WebCore/editing/Editor.h (278541 => 278542)
--- trunk/Source/WebCore/editing/Editor.h 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/Editor.h 2021-06-07 04:11:09 UTC (rev 278542)
@@ -596,7 +596,7 @@
std::optional<SimpleRange> markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling);
OptionSet<TextCheckingType> resolveTextCheckingTypeMask(const Node& rootEditableElement, OptionSet<TextCheckingType>);
- WEBCORE_EXPORT String selectedText(TextIteratorBehavior) const;
+ WEBCORE_EXPORT String selectedText(TextIteratorBehaviors) const;
void selectComposition();
enum SetCompositionMode { ConfirmComposition, CancelComposition };
Modified: trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -193,7 +193,7 @@
}
auto range = VisibleSelection::selectionFromContentsOfNode(holder.get()).toNormalizedRange();
- String text = range ? plainText(*range, static_cast<TextIteratorBehavior>(TextIteratorEmitsOriginalText | TextIteratorIgnoresStyleVisibility)) : emptyString();
+ String text = range ? plainText(*range, { TextIteratorBehavior::EmitsOriginalText, TextIteratorBehavior::IgnoresStyleVisibility }) : emptyString();
removeInterchangeNodes(holder.get());
removeUnrenderedNodes(holder.get());
Modified: trunk/Source/WebCore/editing/TextIterator.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/TextIterator.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/TextIterator.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -241,9 +241,9 @@
pushFullyClippedState(stack, node);
}
-static bool isClippedByFrameAncestor(const Document& document, TextIteratorBehavior behavior)
+static bool isClippedByFrameAncestor(const Document& document, TextIteratorBehaviors behaviors)
{
- if (!(behavior & TextIteratorClipsToFrameAncestors))
+ if (!behaviors.contains(TextIteratorBehavior::ClipsToFrameAncestors))
return false;
for (auto* owner = document.ownerElement(); owner; owner = owner->document().ownerElement()) {
@@ -339,8 +339,8 @@
return NodeTraversal::nextSkippingChildren(point.container);
}
-TextIterator::TextIterator(const SimpleRange& range, TextIteratorBehavior behavior)
- : m_behavior(behavior)
+TextIterator::TextIterator(const SimpleRange& range, TextIteratorBehaviors behaviors)
+ : m_behaviors(behaviors)
{
range.start.document().updateLayoutIgnorePendingStylesheets();
@@ -358,7 +358,7 @@
void TextIterator::init()
{
- if (isClippedByFrameAncestor(m_node->document(), m_behavior))
+ if (isClippedByFrameAncestor(m_node->document(), m_behaviors))
return;
setUpFullyClippedStack(m_fullyClippedStack, *m_node);
@@ -375,37 +375,37 @@
TextIterator::~TextIterator() = default;
// FIXME: Use ComposedTreeIterator instead. These functions are more expensive because they might do O(n) work.
-static inline Node* firstChild(TextIteratorBehavior options, Node& node)
+static inline Node* firstChild(TextIteratorBehaviors options, Node& node)
{
- if (UNLIKELY(options & TextIteratorTraversesFlatTree))
+ if (UNLIKELY(options.contains(TextIteratorBehavior::TraversesFlatTree)))
return firstChildInComposedTreeIgnoringUserAgentShadow(node);
return node.firstChild();
}
-static inline Node* nextSibling(TextIteratorBehavior options, Node& node)
+static inline Node* nextSibling(TextIteratorBehaviors options, Node& node)
{
- if (UNLIKELY(options & TextIteratorTraversesFlatTree))
+ if (UNLIKELY(options.contains(TextIteratorBehavior::TraversesFlatTree)))
return nextSiblingInComposedTreeIgnoringUserAgentShadow(node);
return node.nextSibling();
}
-static inline Node* nextNode(TextIteratorBehavior options, Node& node)
+static inline Node* nextNode(TextIteratorBehaviors options, Node& node)
{
- if (UNLIKELY(options & TextIteratorTraversesFlatTree))
+ if (UNLIKELY(options.contains(TextIteratorBehavior::TraversesFlatTree)))
return nextInComposedTreeIgnoringUserAgentShadow(node);
return NodeTraversal::next(node);
}
-static inline bool isDescendantOf(TextIteratorBehavior options, Node& node, Node& possibleAncestor)
+static inline bool isDescendantOf(TextIteratorBehaviors options, Node& node, Node& possibleAncestor)
{
- if (UNLIKELY(options & TextIteratorTraversesFlatTree))
+ if (UNLIKELY(options.contains(TextIteratorBehavior::TraversesFlatTree)))
return node.isDescendantOrShadowDescendantOf(&possibleAncestor);
return node.isDescendantOf(&possibleAncestor);
}
-static inline Node* parentNodeOrShadowHost(TextIteratorBehavior options, Node& node)
+static inline Node* parentNodeOrShadowHost(TextIteratorBehaviors options, Node& node)
{
- if (UNLIKELY(options & TextIteratorTraversesFlatTree))
+ if (UNLIKELY(options.contains(TextIteratorBehavior::TraversesFlatTree)))
return node.parentInComposedTree();
return node.parentOrShadowHostNode();
}
@@ -481,21 +481,21 @@
// find a new current node to handle in depth-first manner,
// calling exitNode() as we come back thru a parent node
- Node* next = m_handledChildren ? nullptr : firstChild(m_behavior, *m_node);
+ Node* next = m_handledChildren ? nullptr : firstChild(m_behaviors, *m_node);
m_offset = 0;
if (!next) {
- next = nextSibling(m_behavior, *m_node);
+ next = nextSibling(m_behaviors, *m_node);
if (!next) {
- bool pastEnd = nextNode(m_behavior, *m_node) == m_pastEndNode;
- Node* parentNode = parentNodeOrShadowHost(m_behavior, *m_node);
+ bool pastEnd = nextNode(m_behaviors, *m_node) == m_pastEndNode;
+ Node* parentNode = parentNodeOrShadowHost(m_behaviors, *m_node);
while (!next && parentNode) {
- if ((pastEnd && parentNode == m_endContainer) || isDescendantOf(m_behavior, *m_endContainer, *parentNode))
+ if ((pastEnd && parentNode == m_endContainer) || isDescendantOf(m_behaviors, *m_endContainer, *parentNode))
return;
bool haveRenderer = m_node->renderer();
Node* exitedNode = m_node;
m_node = parentNode;
m_fullyClippedStack.pop();
- parentNode = parentNodeOrShadowHost(m_behavior, *m_node);
+ parentNode = parentNodeOrShadowHost(m_behaviors, *m_node);
if (haveRenderer)
exitNode(exitedNode);
if (m_positionNode) {
@@ -503,7 +503,7 @@
m_handledChildren = true;
return;
}
- next = nextSibling(m_behavior, *m_node);
+ next = nextSibling(m_behaviors, *m_node);
if (next && m_node->renderer())
exitNode(m_node);
}
@@ -543,7 +543,7 @@
{
Text& textNode = downcast<Text>(*m_node);
- if (m_fullyClippedStack.top() && !(m_behavior & TextIteratorIgnoresStyleVisibility))
+ if (m_fullyClippedStack.top() && !m_behaviors.contains(TextIteratorBehavior::IgnoresStyleVisibility))
return false;
auto& renderer = *textNode.renderer();
@@ -567,7 +567,7 @@
return false;
}
}
- if (renderer.style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility))
+ if (renderer.style().visibility() != Visibility::Visible && !m_behaviors.contains(TextIteratorBehavior::IgnoresStyleVisibility))
return false;
int rendererTextLength = rendererText.length();
int end = (&textNode == m_endContainer) ? m_endOffset : INT_MAX;
@@ -587,7 +587,7 @@
handleTextNodeFirstLetter(downcast<RenderTextFragment>(renderer));
if (!m_textRun && rendererText.length() && !shouldHandleFirstLetter) {
- if (renderer.style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility))
+ if (renderer.style().visibility() != Visibility::Visible && !m_behaviors.contains(TextIteratorBehavior::IgnoresStyleVisibility))
return false;
m_lastTextNodeEndedWithCollapsedSpace = true; // entire block is collapsed space
return true;
@@ -602,7 +602,7 @@
Text& textNode = downcast<Text>(*m_node);
auto& renderer = m_firstLetterText ? *m_firstLetterText : *textNode.renderer();
- if (renderer.style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility)) {
+ if (renderer.style().visibility() != Visibility::Visible && !m_behaviors.contains(TextIteratorBehavior::IgnoresStyleVisibility)) {
m_textRun = { };
return;
}
@@ -651,7 +651,7 @@
if (isNewlineOrTab(rendererText[subrunEnd]))
break;
}
- if (subrunEnd == runEnd && (m_behavior & TextIteratorBehavesAsIfNodesFollowing)) {
+ if (subrunEnd == runEnd && m_behaviors.contains(TextIteratorBehavior::BehavesAsIfNodesFollowing)) {
bool lastSpaceCollapsedByNextNonTextRun = !nextTextRun && rendererText.length() > subrunEnd && rendererText[subrunEnd] == ' ';
if (lastSpaceCollapsedByNextNonTextRun)
++subrunEnd; // runEnd stopped before last space. Increment by one to restore the space.
@@ -696,7 +696,7 @@
void TextIterator::handleTextNodeFirstLetter(RenderTextFragment& renderer)
{
if (auto* firstLetter = renderer.firstLetter()) {
- if (firstLetter->style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility))
+ if (firstLetter->style().visibility() != Visibility::Visible && !m_behaviors.contains(TextIteratorBehavior::IgnoresStyleVisibility))
return;
if (auto* firstLetterText = firstRenderTextInFirstLetter(firstLetter)) {
m_handledFirstLetter = true;
@@ -714,7 +714,7 @@
return false;
auto& renderer = *m_node->renderer();
- if (renderer.style().visibility() != Visibility::Visible && !(m_behavior & TextIteratorIgnoresStyleVisibility))
+ if (renderer.style().visibility() != Visibility::Visible && !m_behaviors.contains(TextIteratorBehavior::IgnoresStyleVisibility))
return false;
if (m_lastTextNodeEndedWithCollapsedSpace) {
@@ -722,7 +722,7 @@
return false;
}
- if ((m_behavior & TextIteratorEntersTextControls) && is<RenderTextControl>(renderer)) {
+ if (m_behaviors.contains(TextIteratorBehavior::EntersTextControls) && is<RenderTextControl>(renderer)) {
if (auto innerTextElement = downcast<RenderTextControl>(renderer).textFormControlElement().innerTextElement()) {
m_node = innerTextElement->containingShadowRoot();
pushFullyClippedState(m_fullyClippedStack, *m_node);
@@ -733,7 +733,7 @@
m_hasEmitted = true;
- if ((m_behavior & TextIteratorEmitsObjectReplacementCharacters) && renderer.isReplaced()) {
+ if (m_behaviors.contains(TextIteratorBehavior::EmitsObjectReplacementCharacters) && renderer.isReplaced()) {
emitCharacter(objectReplacementCharacter, *m_node->parentNode(), m_node, 0, 1);
// Don't process subtrees for embedded objects. If the text there is required,
// it must be explicitly asked by specifying a range falling inside its boundaries.
@@ -741,7 +741,7 @@
return true;
}
- if (m_behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions) {
+ if (m_behaviors.contains(TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions)) {
// We want replaced elements to behave like punctuation for boundary
// finding, and to simply take up space for the selection preservation
// code in moveParagraphs, so we use a comma.
@@ -754,7 +754,7 @@
m_positionStartOffset = 0;
m_positionEndOffset = 1;
- if ((m_behavior & TextIteratorEmitsImageAltText) && is<RenderImage>(renderer)) {
+ if (m_behaviors.contains(TextIteratorBehavior::EmitsImageAltText) && is<RenderImage>(renderer)) {
String altText = downcast<RenderImage>(renderer).altText();
if (unsigned length = altText.length()) {
m_lastCharacter = altText[length - 1];
@@ -931,9 +931,11 @@
// Whether or not we should emit a character as we enter m_node (if it's a container) or as we hit it (if it's atomic).
bool TextIterator::shouldRepresentNodeOffsetZero()
{
- if ((m_behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions) && m_node->renderer() && m_node->renderer()->isTable())
- return true;
-
+ if (m_behaviors.contains(TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions)) {
+ if (auto* renderer = m_node->renderer(); renderer && renderer->isTable())
+ return true;
+ }
+
// Leave element positioned flush with start of a paragraph
// (e.g. do not insert tab before a table cell at the start of a paragraph)
if (m_lastCharacter == '\n')
@@ -987,7 +989,7 @@
bool TextIterator::shouldEmitSpaceBeforeAndAfterNode(Node& node)
{
- return node.renderer() && node.renderer()->isTable() && (node.renderer()->isInline() || (m_behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions));
+ return node.renderer() && node.renderer()->isTable() && (node.renderer()->isInline() || m_behaviors.contains(TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions));
}
void TextIterator::representNodeOffsetZero()
@@ -1015,9 +1017,9 @@
bool TextIterator::handleNonTextNode()
{
- if (shouldEmitNewlineForNode(m_node, m_behavior & TextIteratorEmitsOriginalText))
+ if (shouldEmitNewlineForNode(m_node, m_behaviors.contains(TextIteratorBehavior::EmitsOriginalText)))
emitCharacter('\n', *m_node->parentNode(), m_node, 0, 1);
- else if ((m_behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions) && m_node->renderer() && m_node->renderer()->isHR())
+ else if (m_behaviors.contains(TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions) && m_node->renderer() && m_node->renderer()->isHR())
emitCharacter(' ', *m_node->parentNode(), m_node, 0, 1);
else
representNodeOffsetZero();
@@ -1042,7 +1044,7 @@
// the logic in _web_attributedStringFromRange match. We'll get that for free when we switch to use
// TextIterator in _web_attributedStringFromRange.
// See <rdar://problem/5428427> for an example of how this mismatch will cause problems.
- if (m_lastTextNode && shouldEmitNewlineAfterNode(*m_node, m_behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions)) {
+ if (m_lastTextNode && shouldEmitNewlineAfterNode(*m_node, m_behaviors.contains(TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions))) {
// use extra newline to represent margin bottom, as needed
bool addNewline = shouldEmitExtraNewlineForNode(*m_node);
@@ -1088,8 +1090,8 @@
ASSERT(textStartOffset <= textEndOffset);
// FIXME: This probably yields the wrong offsets when text-transform: lowercase turns a single character into two characters.
- String string = (m_behavior & TextIteratorEmitsOriginalText) ? renderer.originalText()
- : ((m_behavior & TextIteratorEmitsTextsWithoutTranscoding) ? renderer.textWithoutConvertingBackslashToYenSymbol() : renderer.text());
+ String string = m_behaviors.contains(TextIteratorBehavior::EmitsOriginalText) ? renderer.originalText()
+ : (m_behaviors.contains(TextIteratorBehavior::EmitsTextsWithoutTranscoding) ? renderer.textWithoutConvertingBackslashToYenSymbol() : renderer.text());
ASSERT(string.length() >= static_cast<unsigned>(textEndOffset));
@@ -1329,7 +1331,7 @@
{
// We can use a linefeed in place of a tab because this simple iterator is only used to
// find boundaries, not actual content. A linefeed breaks words, sentences, and paragraphs.
- if (shouldEmitNewlineForNode(m_node, m_behavior & TextIteratorEmitsOriginalText) || shouldEmitNewlineAfterNode(*m_node) || shouldEmitTabBeforeNode(*m_node)) {
+ if (shouldEmitNewlineForNode(m_node, m_behaviors.contains(TextIteratorBehavior::EmitsOriginalText)) || shouldEmitNewlineAfterNode(*m_node) || shouldEmitTabBeforeNode(*m_node)) {
if (m_lastCharacter != '\n') {
// Corresponds to the same check in TextIterator::exitNode.
unsigned index = m_node->computeNodeIndex();
@@ -1343,7 +1345,7 @@
void SimplifiedBackwardsTextIterator::exitNode()
{
- if (shouldEmitNewlineForNode(m_node, m_behavior & TextIteratorEmitsOriginalText) || shouldEmitNewlineBeforeNode(*m_node) || shouldEmitTabBeforeNode(*m_node)) {
+ if (shouldEmitNewlineForNode(m_node, m_behaviors.contains(TextIteratorBehavior::EmitsOriginalText)) || shouldEmitNewlineBeforeNode(*m_node) || shouldEmitTabBeforeNode(*m_node)) {
// The start of this emitted range is wrong. Ensuring correctness would require
// VisiblePositions and so would be slow. previousBoundary expects this.
emitCharacter('\n', *m_node, 0, 0);
@@ -1380,8 +1382,8 @@
// --------
-CharacterIterator::CharacterIterator(const SimpleRange& range, TextIteratorBehavior behavior)
- : m_underlyingIterator(range, behavior)
+CharacterIterator::CharacterIterator(const SimpleRange& range, TextIteratorBehaviors behaviors)
+ : m_underlyingIterator(range, behaviors)
{
while (!atEnd() && !m_underlyingIterator.text().length())
m_underlyingIterator.advance();
@@ -2328,7 +2330,7 @@
// --------
-uint64_t characterCount(const SimpleRange& range, TextIteratorBehavior behavior)
+uint64_t characterCount(const SimpleRange& range, TextIteratorBehaviors behaviors)
{
auto adjustedRange = range;
auto ordering = treeOrder<ComposedTree>(range.start, range.end);
@@ -2337,7 +2339,7 @@
else if (!is_lt(ordering))
return 0;
uint64_t length = 0;
- for (TextIterator it(adjustedRange, behavior); !it.atEnd(); it.advance())
+ for (TextIterator it(adjustedRange, behaviors); !it.atEnd(); it.advance())
length += it.text().length();
return length;
}
@@ -2356,12 +2358,12 @@
return sum >= a ? sum : std::numeric_limits<uint64_t>::max();
}
-SimpleRange resolveCharacterRange(const SimpleRange& scope, CharacterRange range, TextIteratorBehavior behavior)
+SimpleRange resolveCharacterRange(const SimpleRange& scope, CharacterRange range, TextIteratorBehaviors behaviors)
{
auto resultRange = SimpleRange { range.location ? scope.end : scope.start, (range.location || range.length) ? scope.end : scope.start };
auto rangeEnd = clampedAdd(range.location, range.length);
uint64_t location = 0;
- for (TextIterator it(scope, behavior); !it.atEnd(); it.advance()) {
+ for (TextIterator it(scope, behaviors); !it.atEnd(); it.advance()) {
unsigned length = it.text().length();
auto textRunRange = it.range();
@@ -2408,9 +2410,9 @@
// --------
-bool hasAnyPlainText(const SimpleRange& range, TextIteratorBehavior behavior)
+bool hasAnyPlainText(const SimpleRange& range, TextIteratorBehaviors behaviors)
{
- for (TextIterator iterator { range, behavior }; !iterator.atEnd(); iterator.advance()) {
+ for (TextIterator iterator { range, behaviors }; !iterator.atEnd(); iterator.advance()) {
if (!iterator.text().isEmpty())
return true;
}
@@ -2417,7 +2419,7 @@
return false;
}
-String plainText(const SimpleRange& range, TextIteratorBehavior defaultBehavior, bool isDisplayString)
+String plainText(const SimpleRange& range, TextIteratorBehaviors defaultBehavior, bool isDisplayString)
{
// The initial buffer size can be critical for performance: https://bugs.webkit.org/show_bug.cgi?id=81192
constexpr unsigned initialCapacity = 1 << 15;
@@ -2427,11 +2429,11 @@
unsigned bufferLength = 0;
StringBuilder builder;
builder.reserveCapacity(initialCapacity);
- TextIteratorBehavior behavior = defaultBehavior;
+ TextIteratorBehaviors behaviors = defaultBehavior;
if (!isDisplayString)
- behavior = static_cast<TextIteratorBehavior>(behavior | TextIteratorEmitsTextsWithoutTranscoding);
+ behaviors.add(TextIteratorBehavior::EmitsTextsWithoutTranscoding);
- for (TextIterator it(range, behavior); !it.atEnd(); it.advance()) {
+ for (TextIterator it(range, behaviors); !it.atEnd(); it.advance()) {
it.appendTextToStringBuilder(builder);
bufferLength += it.text().length();
}
@@ -2447,16 +2449,16 @@
return result;
}
-String plainTextReplacingNoBreakSpace(const SimpleRange& range, TextIteratorBehavior defaultBehavior, bool isDisplayString)
+String plainTextReplacingNoBreakSpace(const SimpleRange& range, TextIteratorBehaviors defaultBehaviors, bool isDisplayString)
{
- return plainText(range, defaultBehavior, isDisplayString).replace(noBreakSpace, ' ');
+ return plainText(range, defaultBehaviors, isDisplayString).replace(noBreakSpace, ' ');
}
-static TextIteratorBehavior findIteratorOptions(FindOptions options)
+static TextIteratorBehaviors findIteratorOptions(FindOptions options)
{
- TextIteratorBehavior iteratorOptions = TextIteratorEntersTextControls | TextIteratorClipsToFrameAncestors;
+ TextIteratorBehaviors iteratorOptions { TextIteratorBehavior::EntersTextControls, TextIteratorBehavior::ClipsToFrameAncestors };
if (!options.contains(DoNotTraverseFlatTree))
- iteratorOptions |= TextIteratorTraversesFlatTree;
+ iteratorOptions.add(TextIteratorBehavior::TraversesFlatTree);
return iteratorOptions;
}
Modified: trunk/Source/WebCore/editing/TextIterator.h (278541 => 278542)
--- trunk/Source/WebCore/editing/TextIterator.h 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/TextIterator.h 2021-06-07 04:11:09 UTC (rev 278542)
@@ -37,16 +37,16 @@
class RenderTextFragment;
// Character ranges based on characters from the text iterator.
-WEBCORE_EXPORT uint64_t characterCount(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
-CharacterRange characterRange(const BoundaryPoint& start, const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
-CharacterRange characterRange(const SimpleRange& scope, const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
-BoundaryPoint resolveCharacterLocation(const SimpleRange& scope, uint64_t, TextIteratorBehavior = TextIteratorDefaultBehavior);
-WEBCORE_EXPORT SimpleRange resolveCharacterRange(const SimpleRange& scope, CharacterRange, TextIteratorBehavior = TextIteratorDefaultBehavior);
+WEBCORE_EXPORT uint64_t characterCount(const SimpleRange&, TextIteratorBehaviors = { });
+CharacterRange characterRange(const BoundaryPoint& start, const SimpleRange&, TextIteratorBehaviors = { });
+CharacterRange characterRange(const SimpleRange& scope, const SimpleRange&, TextIteratorBehaviors = { });
+BoundaryPoint resolveCharacterLocation(const SimpleRange& scope, uint64_t, TextIteratorBehaviors = { });
+WEBCORE_EXPORT SimpleRange resolveCharacterRange(const SimpleRange& scope, CharacterRange, TextIteratorBehaviors = { });
// Text from the text iterator.
-WEBCORE_EXPORT String plainText(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
-WEBCORE_EXPORT bool hasAnyPlainText(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
-WEBCORE_EXPORT String plainTextReplacingNoBreakSpace(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior, bool isDisplayString = false);
+WEBCORE_EXPORT String plainText(const SimpleRange&, TextIteratorBehaviors = { }, bool isDisplayString = false);
+WEBCORE_EXPORT bool hasAnyPlainText(const SimpleRange&, TextIteratorBehaviors = { });
+WEBCORE_EXPORT String plainTextReplacingNoBreakSpace(const SimpleRange&, TextIteratorBehaviors = { }, bool isDisplayString = false);
// Find within the document, based on the text from the text iterator.
SimpleRange findPlainText(const SimpleRange&, const String&, FindOptions);
@@ -94,7 +94,7 @@
class TextIterator {
WTF_MAKE_FAST_ALLOCATED;
public:
- WEBCORE_EXPORT explicit TextIterator(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
+ WEBCORE_EXPORT explicit TextIterator(const SimpleRange&, TextIteratorBehaviors = { });
WEBCORE_EXPORT ~TextIterator();
bool atEnd() const { return !m_positionNode; }
@@ -123,7 +123,7 @@
Node* baseNodeForEmittingNewLine() const;
- const TextIteratorBehavior m_behavior { TextIteratorDefaultBehavior };
+ const TextIteratorBehaviors m_behaviors;
// Current position, not necessarily of the text being returned, but position as we walk through the DOM tree.
Node* m_node { nullptr };
@@ -192,7 +192,7 @@
void emitCharacter(UChar, Node&, int startOffset, int endOffset);
bool advanceRespectingRange(Node*);
- const TextIteratorBehavior m_behavior { TextIteratorDefaultBehavior };
+ const TextIteratorBehaviors m_behaviors;
// Current position, not necessarily of the text being returned, but position as we walk through the DOM tree.
Node* m_node { nullptr };
@@ -229,7 +229,7 @@
// character at a time, or faster, as needed. Useful for searching.
class CharacterIterator {
public:
- WEBCORE_EXPORT explicit CharacterIterator(const SimpleRange&, TextIteratorBehavior = TextIteratorDefaultBehavior);
+ WEBCORE_EXPORT explicit CharacterIterator(const SimpleRange&, TextIteratorBehaviors = { });
bool atEnd() const { return m_underlyingIterator.atEnd(); }
WEBCORE_EXPORT void advance(int numCharacters);
@@ -289,19 +289,19 @@
bool m_didLookAhead { true };
};
-inline CharacterRange characterRange(const BoundaryPoint& start, const SimpleRange& range, TextIteratorBehavior behavior)
+inline CharacterRange characterRange(const BoundaryPoint& start, const SimpleRange& range, TextIteratorBehaviors behaviors)
{
- return { characterCount({ start, range.start }, behavior), characterCount(range, behavior) };
+ return { characterCount({ start, range.start }, behaviors), characterCount(range, behaviors) };
}
-inline CharacterRange characterRange(const SimpleRange& scope, const SimpleRange& range, TextIteratorBehavior behavior)
+inline CharacterRange characterRange(const SimpleRange& scope, const SimpleRange& range, TextIteratorBehaviors behaviors)
{
- return characterRange(scope.start, range, behavior);
+ return characterRange(scope.start, range, behaviors);
}
-inline BoundaryPoint resolveCharacterLocation(const SimpleRange& scope, uint64_t location, TextIteratorBehavior behavior)
+inline BoundaryPoint resolveCharacterLocation(const SimpleRange& scope, uint64_t location, TextIteratorBehaviors behaviors)
{
- return resolveCharacterRange(scope, { location, 0 }, behavior).start;
+ return resolveCharacterRange(scope, { location, 0 }, behaviors).start;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/TextIteratorBehavior.h (278541 => 278542)
--- trunk/Source/WebCore/editing/TextIteratorBehavior.h 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/TextIteratorBehavior.h 2021-06-07 04:11:09 UTC (rev 278542)
@@ -25,42 +25,42 @@
#pragma once
+#include <wtf/OptionSet.h>
+
namespace WebCore {
-enum TextIteratorBehaviorFlag {
- TextIteratorDefaultBehavior = 0,
-
+enum class TextIteratorBehavior : uint16_t {
// Used by selection preservation code. There should be one character emitted between every VisiblePosition
// in the Range used to create the TextIterator.
// FIXME <rdar://problem/6028818>: This functionality should eventually be phased out when we rewrite
// moveParagraphs to not clone/destroy moved content.
- TextIteratorEmitsCharactersBetweenAllVisiblePositions = 1 << 0,
+ EmitsCharactersBetweenAllVisiblePositions = 1 << 0,
- TextIteratorEntersTextControls = 1 << 1,
+ EntersTextControls = 1 << 1,
// Used when we want text for copying, pasting, and transposing.
- TextIteratorEmitsTextsWithoutTranscoding = 1 << 2,
+ EmitsTextsWithoutTranscoding = 1 << 2,
// Used when the visibility of the style should not affect text gathering.
- TextIteratorIgnoresStyleVisibility = 1 << 3,
+ IgnoresStyleVisibility = 1 << 3,
// Used when emitting the special 0xFFFC character is required. Children for replaced objects will be ignored.
- TextIteratorEmitsObjectReplacementCharacters = 1 << 4,
+ EmitsObjectReplacementCharacters = 1 << 4,
// Used when pasting inside password field.
- TextIteratorEmitsOriginalText = 1 << 5,
+ EmitsOriginalText = 1 << 5,
- TextIteratorEmitsImageAltText = 1 << 6,
+ EmitsImageAltText = 1 << 6,
- TextIteratorBehavesAsIfNodesFollowing = 1 << 7,
+ BehavesAsIfNodesFollowing = 1 << 7,
// Makes visiblity test take into account the visibility of the frame.
- // FIXME: This should probably be always on unless TextIteratorIgnoresStyleVisibility is set.
- TextIteratorClipsToFrameAncestors = 1 << 8,
+ // FIXME: This should probably be always on unless TextIteratorBehavior::IgnoresStyleVisibility is set.
+ ClipsToFrameAncestors = 1 << 8,
- TextIteratorTraversesFlatTree = 1 << 9,
+ TraversesFlatTree = 1 << 9,
};
-typedef unsigned short TextIteratorBehavior;
+using TextIteratorBehaviors = OptionSet<TextIteratorBehavior>;
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/TextManipulationController.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/TextManipulationController.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/TextManipulationController.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -155,7 +155,7 @@
class ParagraphContentIterator {
public:
ParagraphContentIterator(const Position& start, const Position& end)
- : m_iterator(*makeSimpleRange(start, end), TextIteratorIgnoresStyleVisibility)
+ : m_iterator(*makeSimpleRange(start, end), TextIteratorBehavior::IgnoresStyleVisibility)
, m_node(start.firstNode())
, m_pastEndNode(end.firstNode())
{
Modified: trunk/Source/WebCore/editing/VisibleSelection.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/VisibleSelection.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/VisibleSelection.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -233,7 +233,7 @@
if (!scope)
return;
- CharacterIterator charIt(*makeSimpleRange(m_end, makeBoundaryPointAfterNodeContents(*scope)), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ CharacterIterator charIt(*makeSimpleRange(m_end, makeBoundaryPointAfterNodeContents(*scope)), TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
for (; !charIt.atEnd() && charIt.text().length(); charIt.advance(1)) {
UChar c = charIt.text()[0];
if ((!isSpaceOrNewline(c) && c != noBreakSpace) || c == '\n')
Modified: trunk/Source/WebCore/editing/VisibleUnits.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/VisibleUnits.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/VisibleUnits.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -601,7 +601,7 @@
if (!searchRange)
return { };
- TextIterator it(*searchRange, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ TextIterator it(*searchRange, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
unsigned next = forwardSearchForBoundaryWithTextIterator(it, string, prefixLength, searchFunction);
if (it.atEnd() && next == string.size())
@@ -608,7 +608,7 @@
pos = makeDeprecatedLegacyPosition(searchRange->end);
else if (next > prefixLength) {
// Use the character iterator to translate the next value into a DOM position.
- CharacterIterator charIt(*searchRange, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ CharacterIterator charIt(*searchRange, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
charIt.advance(next - prefixLength - 1);
if (charIt.atEnd())
return { };
Modified: trunk/Source/WebCore/editing/markup.cpp (278541 => 278542)
--- trunk/Source/WebCore/editing/markup.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/editing/markup.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -455,7 +455,7 @@
String StyledMarkupAccumulator::renderedTextRespectingRange(const Text& text)
{
- TextIteratorBehavior behavior = TextIteratorDefaultBehavior;
+ TextIteratorBehaviors behaviors;
Position start = &text == m_start.containerNode() ? m_start : firstPositionInNode(const_cast<Text*>(&text));
Position end;
if (&text == m_end.containerNode())
@@ -463,11 +463,11 @@
else {
end = lastPositionInNode(const_cast<Text*>(&text));
if (!m_end.isNull())
- behavior = TextIteratorBehavesAsIfNodesFollowing;
+ behaviors.add(TextIteratorBehavior::BehavesAsIfNodesFollowing);
}
auto range = makeSimpleRange(start, end);
- return range ? plainText(*range, behavior) : emptyString();
+ return range ? plainText(*range, behaviors) : emptyString();
}
String StyledMarkupAccumulator::textContentRespectingRange(const Text& text)
Modified: trunk/Source/WebCore/page/EventHandler.cpp (278541 => 278542)
--- trunk/Source/WebCore/page/EventHandler.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -615,7 +615,7 @@
auto range = makeSimpleRange(start, end);
if (!range)
return 0;
- return characterCount(*range, TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ return characterCount(*range, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions);
}
bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
Modified: trunk/Source/WebKit/ChangeLog (278541 => 278542)
--- trunk/Source/WebKit/ChangeLog 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebKit/ChangeLog 2021-06-07 04:11:09 UTC (rev 278542)
@@ -1,3 +1,18 @@
+2021-06-06 Wenson Hsieh <[email protected]>
+
+ Turn TextIteratorBehaviorFlag into an enum class and wrap it in OptionSet
+ https://bugs.webkit.org/show_bug.cgi?id=226691
+
+ Reviewed by Darin Adler.
+
+ See WebCore/ChangeLog for more information.
+
+ * WebProcess/WebPage/ViewGestureGeometryCollector.cpp:
+ (WebKit::ViewGestureGeometryCollector::computeTextLegibilityScales):
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::plainTextForDisplay):
+ (WebKit::rangeNearPositionMatchesText):
+
2021-06-06 Jean-Yves Avenard <[email protected]>
[GPUP][MSE] QuotaExceededError Exception not thrown even if the sum of totalTrackBufferSize and appendBuffer size exceeds maximumBufferSize
Modified: trunk/Source/WebKit/WebProcess/WebPage/ViewGestureGeometryCollector.cpp (278541 => 278542)
--- trunk/Source/WebKit/WebProcess/WebPage/ViewGestureGeometryCollector.cpp 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebKit/WebProcess/WebPage/ViewGestureGeometryCollector.cpp 2021-06-07 04:11:09 UTC (rev 278542)
@@ -161,7 +161,7 @@
unsigned numberOfIterations = 0;
unsigned totalSampledTextLength = 0;
- for (TextIterator documentTextIterator { makeRangeSelectingNodeContents(*document), TextIteratorEntersTextControls }; !documentTextIterator.atEnd(); documentTextIterator.advance()) {
+ for (TextIterator documentTextIterator { makeRangeSelectingNodeContents(*document), TextIteratorBehavior::EntersTextControls }; !documentTextIterator.atEnd(); documentTextIterator.advance()) {
if (++numberOfIterations >= maximumNumberOfTextRunsToConsider)
break;
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (278541 => 278542)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2021-06-07 04:11:09 UTC (rev 278542)
@@ -174,7 +174,7 @@
static String plainTextForDisplay(const SimpleRange& range)
{
- return WebCore::plainTextReplacingNoBreakSpace(range, TextIteratorDefaultBehavior, true);
+ return WebCore::plainTextReplacingNoBreakSpace(range, { }, true);
}
static String plainTextForDisplay(const std::optional<SimpleRange>& range)
@@ -2079,7 +2079,7 @@
auto boundaryPoint = makeBoundaryPoint(position);
if (!boundaryPoint)
return std::nullopt;
- return findClosestPlainText(range, matchText, { }, characterCount({ range.start, *boundaryPoint }, TextIteratorEmitsCharactersBetweenAllVisiblePositions));
+ return findClosestPlainText(range, matchText, { }, characterCount({ range.start, *boundaryPoint }, TextIteratorBehavior::EmitsCharactersBetweenAllVisiblePositions));
}
void WebPage::getRectsAtSelectionOffsetWithText(int32_t offset, const String& text, CompletionHandler<void(const Vector<WebCore::SelectionGeometry>&)>&& completionHandler)
Modified: trunk/Source/WebKitLegacy/mac/ChangeLog (278541 => 278542)
--- trunk/Source/WebKitLegacy/mac/ChangeLog 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebKitLegacy/mac/ChangeLog 2021-06-07 04:11:09 UTC (rev 278542)
@@ -1,3 +1,15 @@
+2021-06-06 Wenson Hsieh <[email protected]>
+
+ Turn TextIteratorBehaviorFlag into an enum class and wrap it in OptionSet
+ https://bugs.webkit.org/show_bug.cgi?id=226691
+
+ Reviewed by Darin Adler.
+
+ See WebCore/ChangeLog for more information.
+
+ * WebView/WebFrame.mm:
+ (-[WebFrame _stringForRange:]):
+
2021-06-05 Wenson Hsieh <[email protected]>
[macOS] Move DataDetectors softlinking in DataDetectorsSPI.h out into a separate PAL header
Modified: trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm (278541 => 278542)
--- trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm 2021-06-07 03:53:19 UTC (rev 278541)
+++ trunk/Source/WebKitLegacy/mac/WebView/WebFrame.mm 2021-06-07 04:11:09 UTC (rev 278542)
@@ -572,7 +572,7 @@
{
if (!range)
return @"";
- return plainText(makeSimpleRange(*core(range)), WebCore::TextIteratorDefaultBehavior, true);
+ return plainText(makeSimpleRange(*core(range)), { }, true);
}
- (OptionSet<WebCore::PaintBehavior>)_paintBehaviorForDestinationContext:(CGContextRef)context