Skip to content

Commit

Permalink
Move TextManipulationItem/Token to the new CoreIPC serialization format
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=248535
rdar://102814555

Reviewed by Alex Christensen.

Port the various TextManipulation related types to the new CoreIPC
serialization format. Also continue expanding the WebCore types which have
been ported across. This change includes types:
    - PasteboardCustomData
    - DatabaseDetails
    - DecomposedGlyphs
    - TextIndicatorData
    - MediaConstraints
    - PromisedAttachmentInfo
    - RecentSearch
    - EventTrackingRegions
    - HasInsecureContent
    - TextManipulationItem
    - TextManipulationToken
    - TextManipulationTokenInfo

* Source/WebKit/Shared/Databases/IndexedDB/WebIDBResult.cpp: Removed.

Canonical link: https://commits.webkit.org/257289@main
  • Loading branch information
gavin-apple committed Dec 2, 2022
1 parent 7c7fc84 commit 1746201
Show file tree
Hide file tree
Showing 26 changed files with 273 additions and 488 deletions.
2 changes: 2 additions & 0 deletions Source/WebCore/Headers.cmake
Expand Up @@ -851,6 +851,8 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
editing/TextIterator.h
editing/TextIteratorBehavior.h
editing/TextManipulationController.h
editing/TextManipulationItem.h
editing/TextManipulationToken.h
editing/UndoStep.h
editing/VisiblePosition.h
editing/VisibleSelection.h
Expand Down
8 changes: 8 additions & 0 deletions Source/WebCore/WebCore.xcodeproj/project.pbxproj
Expand Up @@ -2963,6 +2963,8 @@
862F129E18C1576F005C54AF /* CountedUserActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 862F129D18C1572C005C54AF /* CountedUserActivity.h */; settings = {ATTRIBUTES = (Private, ); }; };
86512EDF154A2AEF00A90426 /* PerformanceResourceTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 86512EDC154A2AEF00A90426 /* PerformanceResourceTiming.h */; };
868160D618766A130021E79D /* UserActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 868160D2187669C40021E79D /* UserActivity.h */; settings = {ATTRIBUTES = (Private, ); }; };
86AA52712937ADB50065399E /* TextManipulationItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AA52702937ADB40065399E /* TextManipulationItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
86AA527C2937BD620065399E /* TextManipulationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 86AA527B2937BD610065399E /* TextManipulationToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
86BE340115058CB200CE0FD8 /* PerformanceEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 86BE33FB15058CB200CE0FD8 /* PerformanceEntry.h */; };
86D982F7125C154000AD9E3D /* DocumentEventTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D982F6125C154000AD9E3D /* DocumentEventTiming.h */; settings = {ATTRIBUTES = (Private, ); }; };
898785F5122E1EAC003AABDA /* JSFileReaderSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 898785F3122E1EAC003AABDA /* JSFileReaderSync.h */; };
Expand Down Expand Up @@ -13033,6 +13035,8 @@
868160D1187669C40021E79D /* UserActivity.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UserActivity.cpp; sourceTree = "<group>"; };
868160D2187669C40021E79D /* UserActivity.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserActivity.h; sourceTree = "<group>"; };
868160D3187669E70021E79D /* UserActivityMac.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UserActivityMac.mm; sourceTree = "<group>"; };
86AA52702937ADB40065399E /* TextManipulationItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextManipulationItem.h; sourceTree = "<group>"; };
86AA527B2937BD610065399E /* TextManipulationToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextManipulationToken.h; sourceTree = "<group>"; };
86BA766D166427A8005BE5D1 /* FrameLoadRequest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FrameLoadRequest.cpp; sourceTree = "<group>"; };
86BE33FB15058CB200CE0FD8 /* PerformanceEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceEntry.h; sourceTree = "<group>"; };
86BE33FC15058CB200CE0FD8 /* PerformanceEntry.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PerformanceEntry.idl; sourceTree = "<group>"; };
Expand Down Expand Up @@ -26376,6 +26380,8 @@
9392146818A6D791000EE688 /* TextIteratorBehavior.h */,
9B02E0C4235E76AA004044B2 /* TextManipulationController.cpp */,
9B02E0C3235E76AA004044B2 /* TextManipulationController.h */,
86AA52702937ADB40065399E /* TextManipulationItem.h */,
86AA527B2937BD610065399E /* TextManipulationToken.h */,
93309DCA099E64910056E581 /* TypingCommand.cpp */,
93309DCB099E64910056E581 /* TypingCommand.h */,
9B2D8A7814997CCF00ECEF3E /* UndoStep.h */,
Expand Down Expand Up @@ -39066,6 +39072,8 @@
93309E1C099E64920056E581 /* TextIterator.h in Headers */,
9392146918A6D791000EE688 /* TextIteratorBehavior.h in Headers */,
9B02E0C8235EAD2A004044B2 /* TextManipulationController.h in Headers */,
86AA52712937ADB50065399E /* TextManipulationItem.h in Headers */,
86AA527C2937BD620065399E /* TextManipulationToken.h in Headers */,
BCEF45E90E687767001C1287 /* TextMetrics.h in Headers */,
E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */,
1C18DA59181AF6A500C4EF22 /* TextPainter.h in Headers */,
Expand Down
31 changes: 16 additions & 15 deletions Source/WebCore/editing/TextManipulationController.cpp
Expand Up @@ -25,6 +25,7 @@

#include "config.h"
#include "TextManipulationController.h"
#include "TextManipulationItem.h"

#include "AccessibilityObject.h"
#include "CharacterData.h"
Expand Down Expand Up @@ -289,12 +290,12 @@ static bool areEqualIgnoringLeadingAndTrailingWhitespaces(const String& content,
return content.stripWhiteSpace() == originalContent.stripWhiteSpace();
}

static std::optional<TextManipulationController::ManipulationTokenInfo> tokenInfo(Node* node)
static std::optional<TextManipulationTokenInfo> tokenInfo(Node* node)
{
if (!node)
return std::nullopt;

TextManipulationController::ManipulationTokenInfo result;
TextManipulationTokenInfo result;
result.documentURL = node->document().url();
if (RefPtr element = is<Element>(node) ? downcast<Element>(node) : node->parentElement()) {
result.tagName = element->tagName();
Expand Down Expand Up @@ -397,7 +398,7 @@ void TextManipulationController::parse(ManipulationUnit& unit, const String& tex
if (isTokenDelimiter(character)) {
if (positionOfLastNonHTMLSpace != notFound && startPositionOfCurrentToken <= positionOfLastNonHTMLSpace) {
auto stringForToken = text.substring(startPositionOfCurrentToken, positionOfLastNonHTMLSpace + 1 - startPositionOfCurrentToken);
unit.tokens.append(ManipulationToken { m_tokenIdentifier.generate(), stringForToken, tokenInfo(&textNode), isNodeExcluded });
unit.tokens.append(TextManipulationToken { m_tokenIdentifier.generate(), stringForToken, tokenInfo(&textNode), isNodeExcluded });
startPositionOfCurrentToken = positionOfLastNonHTMLSpace + 1;
}

Expand All @@ -409,7 +410,7 @@ void TextManipulationController::parse(ManipulationUnit& unit, const String& tex
auto stringForToken = text.substring(startPositionOfCurrentToken, index + 1 - startPositionOfCurrentToken);
if (unit.tokens.isEmpty() && !unit.firstTokenContainsDelimiter)
unit.firstTokenContainsDelimiter = true;
unit.tokens.append(ManipulationToken { m_tokenIdentifier.generate(), stringForToken, tokenInfo(&textNode), true });
unit.tokens.append(TextManipulationToken { m_tokenIdentifier.generate(), stringForToken, tokenInfo(&textNode), true });
startPositionOfCurrentToken = index + 1;
unit.lastTokenContainsDelimiter = true;
} else if (isNotSpace(character)) {
Expand All @@ -421,7 +422,7 @@ void TextManipulationController::parse(ManipulationUnit& unit, const String& tex

if (startPositionOfCurrentToken < text.length()) {
auto stringForToken = text.substring(startPositionOfCurrentToken, index + 1 - startPositionOfCurrentToken);
unit.tokens.append(ManipulationToken { m_tokenIdentifier.generate(), stringForToken, tokenInfo(&textNode), isNodeExcluded });
unit.tokens.append(TextManipulationToken { m_tokenIdentifier.generate(), stringForToken, tokenInfo(&textNode), isNodeExcluded });
unit.lastTokenContainsDelimiter = false;
}
}
Expand All @@ -445,7 +446,7 @@ void TextManipulationController::addItemIfPossible(Vector<ManipulationUnit>&& un
ASSERT(end);
auto startPosition = firstPositionInOrBeforeNode(units[index].node.ptr());
auto endPosition = positionAfterNode(units[end - 1].node.ptr());
Vector<ManipulationToken> tokens;
Vector<TextManipulationToken> tokens;
for (; index < end; ++index)
tokens.appendVector(WTFMove(units[index].tokens));

Expand Down Expand Up @@ -484,19 +485,19 @@ void TextManipulationController::observeParagraphs(const Position& start, const
if (is<Element>(*contentNode)) {
auto& currentElement = downcast<Element>(*contentNode);
if (!content.isTextContent && canPerformTextManipulationByReplacingEntireTextContent(currentElement))
addItem(ManipulationItemData { Position(), Position(), currentElement, nullQName(), { ManipulationToken { m_tokenIdentifier.generate(), currentElement.textContent(), tokenInfo(&currentElement) } } });
addItem(ManipulationItemData { Position(), Position(), currentElement, nullQName(), { TextManipulationToken { m_tokenIdentifier.generate(), currentElement.textContent(), tokenInfo(&currentElement) } } });

if (currentElement.hasAttributes()) {
for (auto& attribute : currentElement.attributesIterator()) {
if (isAttributeForTextManipulation(attribute.name()))
addItem(ManipulationItemData { Position(), Position(), currentElement, attribute.name(), { ManipulationToken { m_tokenIdentifier.generate(), attribute.value(), tokenInfo(&currentElement) } } });
addItem(ManipulationItemData { Position(), Position(), currentElement, attribute.name(), { TextManipulationToken { m_tokenIdentifier.generate(), attribute.value(), tokenInfo(&currentElement) } } });
}
}

if (is<HTMLInputElement>(currentElement)) {
auto& input = downcast<HTMLInputElement>(currentElement);
if (shouldExtractValueForTextManipulation(input))
addItem(ManipulationItemData { { }, { }, currentElement, HTMLNames::valueAttr, { ManipulationToken { m_tokenIdentifier.generate(), input.value(), tokenInfo(&currentElement) } } });
addItem(ManipulationItemData { { }, { }, currentElement, HTMLNames::valueAttr, { TextManipulationToken { m_tokenIdentifier.generate(), input.value(), tokenInfo(&currentElement) } } });
}

if (isEnclosingItemBoundaryElement(currentElement)) {
Expand All @@ -507,7 +508,7 @@ void TextManipulationController::observeParagraphs(const Position& start, const

if (content.isReplacedContent) {
if (!unitsInCurrentParagraph.isEmpty())
unitsInCurrentParagraph.append(ManipulationUnit { *contentNode, { ManipulationToken { m_tokenIdentifier.generate(), "[]"_s, tokenInfo(content.node.get()), true } } });
unitsInCurrentParagraph.append(ManipulationUnit { *contentNode, { TextManipulationToken { m_tokenIdentifier.generate(), "[]"_s, tokenInfo(content.node.get()), true } } });
continue;
}

Expand Down Expand Up @@ -630,7 +631,7 @@ void TextManipulationController::addItem(ManipulationItemData&& itemData)
ASSERT(m_document);
ASSERT(!itemData.tokens.isEmpty());
auto newID = m_itemIdentifier.generate();
m_pendingItemsForCallback.append(ManipulationItem {
m_pendingItemsForCallback.append(TextManipulationItem {
newID,
itemData.tokens.map([](auto& token) { return token; })
});
Expand All @@ -649,7 +650,7 @@ void TextManipulationController::flushPendingItemsForCallback()
m_pendingItemsForCallback.clear();
}

auto TextManipulationController::completeManipulation(const Vector<WebCore::TextManipulationController::ManipulationItem>& completionItems) -> Vector<ManipulationFailure>
auto TextManipulationController::completeManipulation(const Vector<WebCore::TextManipulationItem>& completionItems) -> Vector<ManipulationFailure>
{
Vector<ManipulationFailure> failures;
HashSet<Ref<Node>> containersWithoutVisualOverflowBeforeReplacement;
Expand Down Expand Up @@ -749,7 +750,7 @@ void TextManipulationController::updateInsertions(Vector<NodeEntry>& lastTopDown
insertions.append(NodeInsertion { lastTopDownPath.size() ? lastTopDownPath.last().second.ptr() : nullptr, *currentNode });
}

auto TextManipulationController::replace(const ManipulationItemData& item, const Vector<ManipulationToken>& replacementTokens, HashSet<Ref<Node>>& containersWithoutVisualOverflowBeforeReplacement) -> std::optional<ManipulationFailureType>
auto TextManipulationController::replace(const ManipulationItemData& item, const Vector<TextManipulationToken>& replacementTokens, HashSet<Ref<Node>>& containersWithoutVisualOverflowBeforeReplacement) -> std::optional<ManipulationFailureType>
{
if (item.start.isOrphan() || item.end.isOrphan())
return ManipulationFailureType::ContentChanged;
Expand Down Expand Up @@ -782,7 +783,7 @@ auto TextManipulationController::replace(const ManipulationItemData& item, const
}

size_t currentTokenIndex = 0;
HashMap<TokenIdentifier, TokenExchangeData> tokenExchangeMap;
HashMap<TextManipulationTokenIdentifier, TokenExchangeData> tokenExchangeMap;
RefPtr<Node> commonAncestor;
RefPtr<Node> firstContentNode;
RefPtr<Node> lastChildOfCommonAncestorInRange;
Expand All @@ -802,7 +803,7 @@ auto TextManipulationController::replace(const ManipulationItemData& item, const
if (!isReplacedOrTextContent)
continue;

Vector<ManipulationToken> tokensInCurrentNode;
Vector<TextManipulationToken> tokensInCurrentNode;
if (content.isReplacedContent) {
if (currentTokenIndex >= item.tokens.size())
return ManipulationFailureType::ContentChanged;
Expand Down
121 changes: 11 additions & 110 deletions Source/WebCore/editing/TextManipulationController.h
Expand Up @@ -27,6 +27,7 @@

#include "Position.h"
#include "QualifiedName.h"
#include "TextManipulationItem.h"
#include <wtf/CompletionHandler.h>
#include <wtf/EnumTraits.h>
#include <wtf/ObjectIdentifier.h>
Expand All @@ -44,40 +45,6 @@ class TextManipulationController : public CanMakeWeakPtr<TextManipulationControl
public:
TextManipulationController(Document&);

enum TokenIdentifierType { };
using TokenIdentifier = ObjectIdentifier<TokenIdentifierType>;

struct ManipulationTokenInfo {
String tagName;
String roleAttribute;
URL documentURL;
bool isVisible { false };

template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<ManipulationTokenInfo> decode(Decoder&);
};

struct ManipulationToken {
TokenIdentifier identifier;
String content;
std::optional<ManipulationTokenInfo> info;
bool isExcluded { false };

template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<ManipulationToken> decode(Decoder&);
};

enum ItemIdentifierType { };
using ItemIdentifier = ObjectIdentifier<ItemIdentifierType>;

struct ManipulationItem {
ItemIdentifier identifier;
Vector<ManipulationToken> tokens;

template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<ManipulationItem> decode(Decoder&);
};

struct ExclusionRule {
enum class Type : uint8_t { Exclude, Include };

Expand Down Expand Up @@ -112,7 +79,7 @@ class TextManipulationController : public CanMakeWeakPtr<TextManipulationControl
template<class Decoder> static std::optional<ExclusionRule> decode(Decoder&);
};

using ManipulationItemCallback = Function<void(Document&, const Vector<ManipulationItem>&)>;
using ManipulationItemCallback = Function<void(Document&, const Vector<TextManipulationItem>&)>;
WEBCORE_EXPORT void startObservingParagraphs(ManipulationItemCallback&&, Vector<ExclusionRule>&& = { });

void didUpdateContentForNode(Node&);
Expand All @@ -127,15 +94,15 @@ class TextManipulationController : public CanMakeWeakPtr<TextManipulationControl
};

struct ManipulationFailure {
ItemIdentifier identifier;
TextManipulationItemIdentifier identifier;
uint64_t index;
ManipulationFailureType type;

template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<ManipulationFailure> decode(Decoder&);
};

WEBCORE_EXPORT Vector<ManipulationFailure> completeManipulation(const Vector<ManipulationItem>&);
WEBCORE_EXPORT Vector<ManipulationFailure> completeManipulation(const Vector<TextManipulationItem>&);

private:
void observeParagraphs(const Position& start, const Position& end);
Expand All @@ -148,12 +115,12 @@ class TextManipulationController : public CanMakeWeakPtr<TextManipulationControl
WeakPtr<Element, WeakPtrImplWithEventTargetData> element;
QualifiedName attributeName { nullQName() };

Vector<ManipulationToken> tokens;
Vector<TextManipulationToken> tokens;
};

struct ManipulationUnit {
Ref<Node> node;
Vector<ManipulationToken> tokens;
Vector<TextManipulationToken> tokens;
bool areAllTokensExcluded { true };
bool firstTokenContainsDelimiter { false };
bool lastTokenContainsDelimiter { false };
Expand All @@ -176,7 +143,7 @@ class TextManipulationController : public CanMakeWeakPtr<TextManipulationControl
using NodeEntry = std::pair<Ref<Node>, Ref<Node>>;
Vector<Ref<Node>> getPath(Node*, Node*);
void updateInsertions(Vector<NodeEntry>&, const Vector<Ref<Node>>&, Node*, HashSet<Ref<Node>>&, Vector<NodeInsertion>&);
std::optional<ManipulationFailureType> replace(const ManipulationItemData&, const Vector<ManipulationToken>&, HashSet<Ref<Node>>& containersWithoutVisualOverflowBeforeReplacement);
std::optional<ManipulationFailureType> replace(const ManipulationItemData&, const Vector<TextManipulationToken>&, HashSet<Ref<Node>>& containersWithoutVisualOverflowBeforeReplacement);

WeakPtr<Document, WeakPtrImplWithEventTargetData> m_document;
WeakHashSet<Element, WeakPtrImplWithEventTargetData> m_elementsWithNewRenderer;
Expand All @@ -190,80 +157,14 @@ class TextManipulationController : public CanMakeWeakPtr<TextManipulationControl
bool m_didScheduleObservationUpdate { false };

ManipulationItemCallback m_callback;
Vector<ManipulationItem> m_pendingItemsForCallback;
Vector<TextManipulationItem> m_pendingItemsForCallback;

Vector<ExclusionRule> m_exclusionRules;
HashMap<ItemIdentifier, ManipulationItemData> m_items;
ItemIdentifier m_itemIdentifier;
TokenIdentifier m_tokenIdentifier;
HashMap<TextManipulationItemIdentifier, ManipulationItemData> m_items;
TextManipulationItemIdentifier m_itemIdentifier;
TextManipulationTokenIdentifier m_tokenIdentifier;
};

template<class Encoder>
void TextManipulationController::ManipulationTokenInfo::encode(Encoder& encoder) const
{
encoder << tagName;
encoder << roleAttribute;
encoder << documentURL;
encoder << isVisible;
}

template<class Decoder>
std::optional<TextManipulationController::ManipulationTokenInfo> TextManipulationController::ManipulationTokenInfo::decode(Decoder& decoder)
{
ManipulationTokenInfo result;
if (!decoder.decode(result.tagName))
return std::nullopt;

if (!decoder.decode(result.roleAttribute))
return std::nullopt;

if (!decoder.decode(result.documentURL))
return std::nullopt;

if (!decoder.decode(result.isVisible))
return std::nullopt;

return result;
}

template<class Encoder>
void TextManipulationController::ManipulationToken::encode(Encoder& encoder) const
{
encoder << identifier << content << info << isExcluded;
}

template<class Decoder>
std::optional<TextManipulationController::ManipulationToken> TextManipulationController::ManipulationToken::decode(Decoder& decoder)
{
ManipulationToken result;
if (!decoder.decode(result.identifier))
return std::nullopt;
if (!decoder.decode(result.content))
return std::nullopt;
if (!decoder.decode(result.info))
return std::nullopt;
if (!decoder.decode(result.isExcluded))
return std::nullopt;
return result;
}

template<class Encoder>
void TextManipulationController::ManipulationItem::encode(Encoder& encoder) const
{
encoder << identifier << tokens;
}

template<class Decoder>
std::optional<TextManipulationController::ManipulationItem> TextManipulationController::ManipulationItem::decode(Decoder& decoder)
{
ManipulationItem result;
if (!decoder.decode(result.identifier))
return std::nullopt;
if (!decoder.decode(result.tokens))
return std::nullopt;
return result;
}

template<class Encoder>
void TextManipulationController::ExclusionRule::encode(Encoder& encoder) const
{
Expand Down

0 comments on commit 1746201

Please sign in to comment.