Skip to content

Commit

Permalink
[Unified Text Replacement] Move UnifiedTextReplacementController fr…
Browse files Browse the repository at this point in the history
…om WebKit to WebCore

https://bugs.webkit.org/show_bug.cgi?id=275289
rdar://129438122

Reviewed by Aditya Keerthi.

* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/dom/DocumentMarker.h:
* Source/WebCore/page/ChromeClient.h:
(WebCore::ChromeClient::textReplacementSessionShowInformationForReplacementWithIDRelativeToRect):
(WebCore::ChromeClient::textReplacementSessionUpdateStateForReplacementWithID):
(WebCore::ChromeClient::removeTextIndicatorStyleForID):
(WebCore::ChromeClient::cleanUpTextStylesForSessionID):
(WebCore::ChromeClient::addSourceTextIndicatorStyle):
(WebCore::ChromeClient::addDestinationTextIndicatorStyle):
* Source/WebCore/page/Page.cpp:
(WebCore::m_unifiedTextReplacementController):
(WebCore::Page::willBeginTextReplacementSession):
(WebCore::Page::didBeginTextReplacementSession):
(WebCore::Page::textReplacementSessionDidReceiveReplacements):
(WebCore::Page::textReplacementSessionDidUpdateStateForReplacement):
(WebCore::Page::didEndTextReplacementSession):
(WebCore::Page::textReplacementSessionDidReceiveTextWithReplacementRange):
(WebCore::Page::updateStateForSelectedReplacementIfNeeded):
(WebCore::Page::textReplacementSessionDidReceiveEditAction):
(WebCore::m_historyItemClient): Deleted.
* Source/WebCore/page/Page.h:
(WebCore::Page::unifiedTextReplacementController const):
* Source/WebCore/page/unified-text-replacement/UnifiedTextReplacementController.h: Added.
* Source/WebCore/page/unified-text-replacement/UnifiedTextReplacementController.mm: Added.
(WebCore::UnifiedTextReplacementController::characterRange):
(WebCore::UnifiedTextReplacementController::characterCount):
(WebCore::UnifiedTextReplacementController::resolveCharacterRange):
(WebCore::UnifiedTextReplacementController::plainText):
(WebCore::UnifiedTextReplacementController::UnifiedTextReplacementController):
(WebCore::contextRangeForDocument):
(WebCore::UnifiedTextReplacementController::willBeginTextReplacementSession):
(WebCore::UnifiedTextReplacementController::didBeginTextReplacementSession):
(WebCore::UnifiedTextReplacementController::textReplacementSessionDidReceiveReplacements):
(WebCore::UnifiedTextReplacementController::textReplacementSessionDidUpdateStateForReplacement):
(WebCore::UnifiedTextReplacementController::didEndTextReplacementSession<UnifiedTextReplacement::Session::ReplacementType::PlainText>):
(WebCore::UnifiedTextReplacementController::didEndTextReplacementSession<UnifiedTextReplacement::Session::ReplacementType::RichText>):
(WebCore::UnifiedTextReplacementController::didEndTextReplacementSession):
(WebCore::UnifiedTextReplacementController::textReplacementSessionDidReceiveTextWithReplacementRange):
(WebCore::UnifiedTextReplacementController::textReplacementSessionDidReceiveEditAction):
(WebCore::UnifiedTextReplacementController::textReplacementSessionPerformEditActionForPlainText):
(WebCore::UnifiedTextReplacementController::textReplacementSessionPerformEditActionForRichText):
(WebCore::UnifiedTextReplacementController::updateStateForSelectedReplacementIfNeeded):
(WebCore::UnifiedTextReplacementController::contextRangeForSessionWithID const):
(WebCore::UnifiedTextReplacementController::document const):
(WebCore::UnifiedTextReplacementController::findReplacementMarkerByID const):
(WebCore::UnifiedTextReplacementController::findReplacementMarkerContainingRange const):
(WebCore::UnifiedTextReplacementController::replaceContentsOfRangeInSessionInternal):
(WebCore::UnifiedTextReplacementController::replaceContentsOfRangeInSession):
* Source/WebCore/page/unified-text-replacement/UnifiedTextReplacementTypes.h: Renamed from Source/WebKit/Shared/WebUnifiedTextReplacementSessionData.h.
* Source/WebCore/platform/Logging.h:
* Source/WebKit/DerivedSources-input.xcfilelist:
* Source/WebKit/DerivedSources.make:
* Source/WebKit/Platform/Logging.h:
* Source/WebKit/Scripts/webkit/messages.py:
(headers_for_type):
* Source/WebKit/Shared/TextIndicatorStyle.serialization.in: Renamed from Source/WebKit/Shared/UnifiedTextReplacement.serialization.in.
* Source/WebKit/Shared/WebCoreArgumentCoders.serialization.in:
* Source/WebKit/Shared/WebTextReplacementData.h: Removed.
* Source/WebKit/Shared/WebUnifiedTextReplacementContextData.h: Removed.
* Source/WebKit/SourcesCocoa.txt:
* Source/WebKit/UIProcess/API/APIPageConfiguration.h:
(API::PageConfiguration::unifiedTextReplacementBehavior const):
(API::PageConfiguration::setUnifiedTextReplacementBehavior):
* Source/WebKit/UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(convertToPlatform):
(convertToWeb):
(-[WKWebViewConfiguration _setUnifiedTextReplacementBehavior:]):
(-[WKWebViewConfiguration _unifiedTextReplacementBehavior]):
(convertToPlatformBehavior): Deleted.
(convertToWebBehavior): Deleted.
* Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h:
* Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm:
* Source/WebKit/UIProcess/API/mac/WKWebViewMac.mm:
* Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h:
* Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm:
(WebKit::PageClientImplCocoa::textReplacementSessionShowInformationForReplacementWithIDRelativeToRect):
(WebKit::PageClientImplCocoa::textReplacementSessionUpdateStateForReplacementWithID):
(WebKit::PageClientImplCocoa::textReplacementSessionShowInformationForReplacementWithUUIDRelativeToRect): Deleted.
(WebKit::PageClientImplCocoa::textReplacementSessionUpdateStateForReplacementWithUUID): Deleted.
* Source/WebKit/UIProcess/Cocoa/WebPageProxyCocoa.mm:
(WebKit::WebPageProxy::willBeginTextReplacementSession):
(WebKit::WebPageProxy::didBeginTextReplacementSession):
(WebKit::WebPageProxy::textReplacementSessionDidReceiveReplacements):
(WebKit::WebPageProxy::textReplacementSessionDidUpdateStateForReplacement):
(WebKit::WebPageProxy::didEndTextReplacementSession):
(WebKit::WebPageProxy::textReplacementSessionDidReceiveTextWithReplacementRange):
(WebKit::WebPageProxy::textReplacementSessionDidReceiveEditAction):
(WebKit::WebPageProxy::textReplacementSessionShowInformationForReplacementWithIDRelativeToRect):
(WebKit::WebPageProxy::textReplacementSessionUpdateStateForReplacementWithID):
(WebKit::WebPageProxy::textReplacementSessionShowInformationForReplacementWithUUIDRelativeToRect): Deleted.
(WebKit::WebPageProxy::textReplacementSessionUpdateStateForReplacementWithUUID): Deleted.
* Source/WebKit/UIProcess/PageClient.h:
* Source/WebKit/UIProcess/WebPageProxy.h:
* Source/WebKit/UIProcess/WebPageProxy.messages.in:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView canPerformActionForWebView:withSender:]):
(-[WKContentView unifiedTextReplacementBehavior]):
* Source/WebKit/UIProcess/mac/WebViewImpl.h:
* Source/WebKit/UIProcess/mac/WebViewImpl.mm:
(WebKit::WebViewImpl::unifiedTextReplacementBehavior const):
(WebKit::WebViewImpl::canHandleSwapCharacters const):
* Source/WebKit/WebKit.xcodeproj/project.pbxproj:
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::textReplacementSessionShowInformationForReplacementWithIDRelativeToRect):
(WebKit::WebChromeClient::textReplacementSessionUpdateStateForReplacementWithID):
(WebKit::WebChromeClient::removeTextIndicatorStyleForID):
(WebKit::WebChromeClient::cleanUpTextStylesForSessionID):
(WebKit::WebChromeClient::addSourceTextIndicatorStyle):
(WebKit::WebChromeClient::addDestinationTextIndicatorStyle):
* Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h:
* Source/WebKit/WebProcess/WebPage/Cocoa/TextIndicatorStyleController.mm:
(WebKit::TextIndicatorStyleController::contextRangeForSessionWithID const):
(WebKit::TextIndicatorStyleController::contextRangeForTextIndicatorStyle const):
(WebKit::TextIndicatorStyleController::addSourceTextIndicatorStyle):
(WebKit::TextIndicatorStyleController::addDestinationTextIndicatorStyle):
(WebKit::TextIndicatorStyleController::createTextIndicatorForRange):
* Source/WebKit/WebProcess/WebPage/Cocoa/UnifiedTextReplacementController.mm: Removed.
* Source/WebKit/WebProcess/WebPage/Cocoa/WebPageCocoa.mm:
(WebKit::WebPage::updateTextIndicatorStyleVisibilityForID):
(WebKit::WebPage::willBeginTextReplacementSession):
(WebKit::WebPage::didBeginTextReplacementSession):
(WebKit::WebPage::textReplacementSessionDidReceiveReplacements):
(WebKit::WebPage::textReplacementSessionDidUpdateStateForReplacement):
(WebKit::WebPage::didEndTextReplacementSession):
(WebKit::WebPage::textReplacementSessionDidReceiveTextWithReplacementRange):
(WebKit::WebPage::textReplacementSessionDidReceiveEditAction):
(WebKit::WebPage::textReplacementSessionShowInformationForReplacementWithIDRelativeToRect):
(WebKit::WebPage::textReplacementSessionUpdateStateForReplacementWithID):
(WebKit::WebPage::textReplacementSessionShowInformationForReplacementWithUUIDRelativeToRect): Deleted.
(WebKit::WebPage::textReplacementSessionUpdateStateForReplacementWithUUID): Deleted.
* Source/WebKit/WebProcess/WebPage/TextIndicatorStyleController.h:
* Source/WebKit/WebProcess/WebPage/UnifiedTextReplacementController.h: Removed.
* Source/WebKit/WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::didChangeSelection):
(WebKit::WebPage::cleanUpTextStylesForSessionID):
(WebKit::WebPage::addSourceTextIndicatorStyle):
(WebKit::WebPage::addDestinationTextIndicatorStyle):
* Source/WebKit/WebProcess/WebPage/WebPage.h:
(WebKit::WebPage::textIndicatorStyleController): Deleted.
(WebKit::WebPage::unifiedTextReplacementController): Deleted.
* Source/WebKit/WebProcess/WebPage/WebPage.messages.in:

Canonical link: https://commits.webkit.org/279890@main
  • Loading branch information
rr-codes authored and pxlcoder committed Jun 10, 2024
1 parent ab4ce44 commit e4bbed4
Show file tree
Hide file tree
Showing 45 changed files with 1,424 additions and 1,263 deletions.
2 changes: 2 additions & 0 deletions Source/WebCore/Headers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,8 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
page/text-extraction/TextExtraction.h
page/text-extraction/TextExtractionTypes.h

page/unified-text-replacement/UnifiedTextReplacementTypes.h

platform/AbortableTaskQueue.h
platform/AudioSampleFormat.h
platform/CaretAnimator.h
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/SourcesCocoa.txt
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ page/scrolling/mac/ScrollingTreeMac.mm
page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm
page/scrolling/mac/ScrollingTreePluginScrollingNodeMac.mm
page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm
page/unified-text-replacement/UnifiedTextReplacementController.mm
platform/VideoFrame.mm
platform/animation/AcceleratedEffectStack.mm @no-unify
platform/audio/AudioSession.cpp
Expand Down
18 changes: 18 additions & 0 deletions Source/WebCore/WebCore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@
07D637401BB0B11300256CE9 /* WebAudioSourceProviderCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6373E1BB0B11300256CE9 /* WebAudioSourceProviderCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; };
07D6A4F41BED5F8800174146 /* MockRealtimeAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6A4F21BED5F8800174146 /* MockRealtimeAudioSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
07D6A4F81BF2307D00174146 /* AudioTrackPrivateMediaStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 07D6A4F61BF2307D00174146 /* AudioTrackPrivateMediaStream.h */; };
07E2C0732C1396FE00BE6743 /* UnifiedTextReplacementTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 07E2C0722C1396F600BE6743 /* UnifiedTextReplacementTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
07E2C0772C13A9D100BE6743 /* UnifiedTextReplacementController.h in Headers */ = {isa = PBXBuildFile; fileRef = 07E2C0742C13A9D100BE6743 /* UnifiedTextReplacementController.h */; settings = {ATTRIBUTES = (Private, ); }; };
07E3DFD11A9E786500764CA8 /* MediaPlaybackTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = 07E3DFD01A9E786500764CA8 /* MediaPlaybackTarget.h */; settings = {ATTRIBUTES = (Private, ); }; };
07E4BDBF2A3A5FAB000D5509 /* DictationCaretAnimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07E4BDBD2A3A5FAB000D5509 /* DictationCaretAnimator.cpp */; };
07E4BDC02A3A5FAB000D5509 /* DictationCaretAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 07E4BDBE2A3A5FAB000D5509 /* DictationCaretAnimator.h */; };
Expand Down Expand Up @@ -7006,6 +7008,9 @@
07DB47062BC27E0A00B5A958 /* WritingSuggestionData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WritingSuggestionData.h; sourceTree = "<group>"; };
07E117061489EBEB00EC5ACE /* JSTextTrackCueCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTextTrackCueCustom.cpp; sourceTree = "<group>"; };
07E223CA2A784D1A00C9EDF3 /* vision-volume-container.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = "vision-volume-container.js"; sourceTree = "<group>"; };
07E2C0722C1396F600BE6743 /* UnifiedTextReplacementTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UnifiedTextReplacementTypes.h; sourceTree = "<group>"; };
07E2C0742C13A9D100BE6743 /* UnifiedTextReplacementController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UnifiedTextReplacementController.h; sourceTree = "<group>"; };
07E2C0752C13A9D100BE6743 /* UnifiedTextReplacementController.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UnifiedTextReplacementController.mm; sourceTree = "<group>"; };
07E3DFD01A9E786500764CA8 /* MediaPlaybackTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaPlaybackTarget.h; sourceTree = "<group>"; };
07E4BDBD2A3A5FAB000D5509 /* DictationCaretAnimator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DictationCaretAnimator.cpp; sourceTree = "<group>"; };
07E4BDBE2A3A5FAB000D5509 /* DictationCaretAnimator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DictationCaretAnimator.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -21497,6 +21502,16 @@
name = MediaStream;
sourceTree = "<group>";
};
07E2C0702C13962800BE6743 /* unified-text-replacement */ = {
isa = PBXGroup;
children = (
07E2C0742C13A9D100BE6743 /* UnifiedTextReplacementController.h */,
07E2C0752C13A9D100BE6743 /* UnifiedTextReplacementController.mm */,
07E2C0722C1396F600BE6743 /* UnifiedTextReplacementTypes.h */,
);
path = "unified-text-replacement";
sourceTree = "<group>";
};
081CDFBD126ECFE800D215CA /* properties */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -27484,6 +27499,7 @@
93C09A820B064F05005ABD4D /* mac */,
1AF62EE114DA22A70041556C /* scrolling */,
F4C7E85A2B5F1D50001B8C9C /* text-extraction */,
07E2C0702C13962800BE6743 /* unified-text-replacement */,
0F70495D211B524200369968 /* ActivityState.cpp */,
724EE54E1DC7F25B00A91FFB /* ActivityState.h */,
F4C574742A8432040024A071 /* ActivityState.serialization.in */,
Expand Down Expand Up @@ -42983,6 +42999,8 @@
2ECDBAD121D8903400F00ECD /* UndoManager.h in Headers */,
9B2D8A7914997CCF00ECEF3E /* UndoStep.h in Headers */,
A863E2011343412000274926 /* UnicodeBidi.h in Headers */,
07E2C0772C13A9D100BE6743 /* UnifiedTextReplacementController.h in Headers */,
07E2C0732C1396FE00BE6743 /* UnifiedTextReplacementTypes.h in Headers */,
518864E11BBAF57400E540C9 /* UniqueIDBDatabase.h in Headers */,
5198F7A51BBDB79300E2CC5F /* UniqueIDBDatabaseConnection.h in Headers */,
93B631E227ABA1E600443A44 /* UniqueIDBDatabaseManager.h in Headers */,
Expand Down
10 changes: 8 additions & 2 deletions Source/WebCore/dom/DocumentMarker.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,14 @@

namespace WebCore {
class DocumentMarker;

namespace UnifiedTextReplacement {
using ReplacementID = WTF::UUID;
using SessionID = WTF::UUID;
}

} // namespace WebCore

namespace WTF {
template<typename T> struct IsDeprecatedWeakRefSmartPointerException;
template<> struct IsDeprecatedWeakRefSmartPointerException<WebCore::DocumentMarker> : std::true_type { };
Expand Down Expand Up @@ -120,8 +126,8 @@ class DocumentMarker : public CanMakeWeakPtr<DocumentMarker> {
};

String originalText;
WTF::UUID uuid;
WTF::UUID sessionUUID;
UnifiedTextReplacement::ReplacementID replacementID;
UnifiedTextReplacement::SessionID sessionID;
State state { State::Pending };
};
#endif
Expand Down
18 changes: 18 additions & 0 deletions Source/WebCore/page/ChromeClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ enum class RouteSharingPolicy : uint8_t;

enum class DidFilterLinkDecoration : bool { No, Yes };

namespace UnifiedTextReplacement {
using SessionID = WTF::UUID;
}

class ChromeClient {
public:
virtual void chromeDestroyed() = 0;
Expand Down Expand Up @@ -659,6 +663,20 @@ class ChromeClient {

virtual double baseViewportLayoutSizeScaleFactor() const { return 1; }

#if ENABLE(UNIFIED_TEXT_REPLACEMENT)
virtual void textReplacementSessionShowInformationForReplacementWithIDRelativeToRect(const UnifiedTextReplacement::SessionID&, const UnifiedTextReplacement::ReplacementID&, IntRect) { }

virtual void textReplacementSessionUpdateStateForReplacementWithID(const UnifiedTextReplacement::SessionID&, UnifiedTextReplacement::ReplacementState, const UnifiedTextReplacement::ReplacementID&) { }

virtual void removeTextIndicatorStyleForID(const UnifiedTextReplacement::SessionID&) { }

virtual void cleanUpTextStylesForSessionID(const UnifiedTextReplacement::SessionID&) { }

virtual void addSourceTextIndicatorStyle(const UnifiedTextReplacement::SessionID&, const CharacterRange&) { }

virtual void addDestinationTextIndicatorStyle(const UnifiedTextReplacement::SessionID&, const CharacterRange&) { }
#endif

WEBCORE_EXPORT virtual ~ChromeClient();

protected:
Expand Down
49 changes: 49 additions & 0 deletions Source/WebCore/page/Page.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@
#include "AccessibilityRootAtspi.h"
#endif

#if ENABLE(UNIFIED_TEXT_REPLACEMENT)
#include "UnifiedTextReplacementController.h"
#endif

#if ENABLE(WEBXR)
#include "NavigatorWebXR.h"
#include "WebXRSession.h"
Expand Down Expand Up @@ -408,6 +412,9 @@ Page::Page(PageConfiguration&& pageConfiguration)
, m_contentSecurityPolicyModeForExtension(WTFMove(pageConfiguration.contentSecurityPolicyModeForExtension))
, m_badgeClient(WTFMove(pageConfiguration.badgeClient))
, m_historyItemClient(WTFMove(pageConfiguration.historyItemClient))
#if ENABLE(UNIFIED_TEXT_REPLACEMENT)
, m_unifiedTextReplacementController(makeUniqueRef<UnifiedTextReplacementController>(*this))
#endif
{
updateTimerThrottlingState();

Expand Down Expand Up @@ -4851,4 +4858,46 @@ void Page::gamepadsRecentlyAccessed()
}
#endif

#if ENABLE(UNIFIED_TEXT_REPLACEMENT)
void Page::willBeginTextReplacementSession(const std::optional<UnifiedTextReplacement::Session>& session, CompletionHandler<void(const Vector<UnifiedTextReplacement::Context>&)>&& completionHandler)
{
m_unifiedTextReplacementController->willBeginTextReplacementSession(session, WTFMove(completionHandler));
}

void Page::didBeginTextReplacementSession(const UnifiedTextReplacement::Session& session, const Vector<UnifiedTextReplacement::Context>& contexts)
{
m_unifiedTextReplacementController->didBeginTextReplacementSession(session, contexts);
}

void Page::textReplacementSessionDidReceiveReplacements(const UnifiedTextReplacement::Session& session, const Vector<UnifiedTextReplacement::Replacement>& replacements, const UnifiedTextReplacement::Context& context, bool finished)
{
m_unifiedTextReplacementController->textReplacementSessionDidReceiveReplacements(session, replacements, context, finished);
}

void Page::textReplacementSessionDidUpdateStateForReplacement(const UnifiedTextReplacement::Session& session, UnifiedTextReplacement::Replacement::State state, const UnifiedTextReplacement::Replacement& replacement, const UnifiedTextReplacement::Context& context)
{
m_unifiedTextReplacementController->textReplacementSessionDidUpdateStateForReplacement(session, state, replacement, context);
}

void Page::didEndTextReplacementSession(const UnifiedTextReplacement::Session& session, bool accepted)
{
m_unifiedTextReplacementController->didEndTextReplacementSession(session, accepted);
}

void Page::textReplacementSessionDidReceiveTextWithReplacementRange(const UnifiedTextReplacement::Session& session, const AttributedString& attributedText, const CharacterRange& range, const UnifiedTextReplacement::Context& context, bool finished)
{
m_unifiedTextReplacementController->textReplacementSessionDidReceiveTextWithReplacementRange(session, attributedText, range, context, finished);
}

void Page::updateStateForSelectedReplacementIfNeeded()
{
m_unifiedTextReplacementController->updateStateForSelectedReplacementIfNeeded();
}

void Page::textReplacementSessionDidReceiveEditAction(const UnifiedTextReplacement::Session& session, WebCore::UnifiedTextReplacement::EditAction action)
{
m_unifiedTextReplacementController->textReplacementSessionDidReceiveEditAction(session, action);
}
#endif

} // namespace WebCore
42 changes: 42 additions & 0 deletions Source/WebCore/page/Page.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,30 @@ class WheelEventDeltaFilter;
class WheelEventTestMonitor;
class WindowEventLoop;

#if ENABLE(UNIFIED_TEXT_REPLACEMENT)
class UnifiedTextReplacementController;

namespace UnifiedTextReplacement {
enum class EditAction : uint8_t;
enum class ReplacementState : uint8_t;

struct Context;
struct Replacement;
struct Session;

using ReplacementID = WTF::UUID;
using SessionID = WTF::UUID;
}
#endif

#if ENABLE(WEBXR)
class WebXRSession;
#endif

struct AXTreeData;
struct ApplePayAMSUIRequest;
struct AttributedString;
struct CharacterRange;
struct SimpleRange;
struct TextRecognitionResult;

Expand Down Expand Up @@ -1129,6 +1147,26 @@ class Page : public RefCounted<Page>, public Supplementable<Page>, public CanMak
void gamepadsRecentlyAccessed();
#endif

#if ENABLE(UNIFIED_TEXT_REPLACEMENT)
WEBCORE_EXPORT void willBeginTextReplacementSession(const std::optional<UnifiedTextReplacement::Session>&, CompletionHandler<void(const Vector<UnifiedTextReplacement::Context>&)>&&);

WEBCORE_EXPORT void didBeginTextReplacementSession(const UnifiedTextReplacement::Session&, const Vector<UnifiedTextReplacement::Context>&);

WEBCORE_EXPORT void textReplacementSessionDidReceiveReplacements(const UnifiedTextReplacement::Session&, const Vector<UnifiedTextReplacement::Replacement>&, const UnifiedTextReplacement::Context&, bool finished);

WEBCORE_EXPORT void textReplacementSessionDidUpdateStateForReplacement(const UnifiedTextReplacement::Session&, UnifiedTextReplacement::ReplacementState, const UnifiedTextReplacement::Replacement&, const UnifiedTextReplacement::Context&);

WEBCORE_EXPORT void didEndTextReplacementSession(const UnifiedTextReplacement::Session&, bool accepted);

WEBCORE_EXPORT void textReplacementSessionDidReceiveTextWithReplacementRange(const UnifiedTextReplacement::Session&, const AttributedString&, const CharacterRange&, const UnifiedTextReplacement::Context&, bool finished);

WEBCORE_EXPORT void textReplacementSessionDidReceiveEditAction(const UnifiedTextReplacement::Session&, UnifiedTextReplacement::EditAction);

WEBCORE_EXPORT void updateStateForSelectedReplacementIfNeeded();

const UnifiedTextReplacementController& unifiedTextReplacementController() const { return m_unifiedTextReplacementController.get(); }
#endif

private:
explicit Page(PageConfiguration&&);

Expand Down Expand Up @@ -1531,6 +1569,10 @@ class Page : public RefCounted<Page>, public Supplementable<Page>, public CanMak
#if ENABLE(GAMEPAD)
MonotonicTime m_lastAccessNotificationTime;
#endif

#if ENABLE(UNIFIED_TEXT_REPLACEMENT)
UniqueRef<UnifiedTextReplacementController> m_unifiedTextReplacementController;
#endif
}; // class Page

inline Page* Frame::page() const
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#if ENABLE(UNIFIED_TEXT_REPLACEMENT)

#include "UnifiedTextReplacementTypes.h"

namespace WebCore {

class Document;
class DocumentFragment;
class DocumentMarker;
class Editor;
class Node;
class Page;
class Range;

struct SimpleRange;

class UnifiedTextReplacementController final {
WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(UnifiedTextReplacementController);

public:
explicit UnifiedTextReplacementController(Page&);

void willBeginTextReplacementSession(const std::optional<UnifiedTextReplacement::Session>&, CompletionHandler<void(const Vector<UnifiedTextReplacement::Context>&)>&&);

void didBeginTextReplacementSession(const UnifiedTextReplacement::Session&, const Vector<UnifiedTextReplacement::Context>&);

void textReplacementSessionDidReceiveReplacements(const UnifiedTextReplacement::Session&, const Vector<UnifiedTextReplacement::Replacement>&, const UnifiedTextReplacement::Context&, bool finished);

void textReplacementSessionDidUpdateStateForReplacement(const UnifiedTextReplacement::Session&, UnifiedTextReplacement::Replacement::State, const UnifiedTextReplacement::Replacement&, const UnifiedTextReplacement::Context&);

void didEndTextReplacementSession(const UnifiedTextReplacement::Session&, bool accepted);

void textReplacementSessionDidReceiveTextWithReplacementRange(const UnifiedTextReplacement::Session&, const AttributedString&, const CharacterRange&, const UnifiedTextReplacement::Context&, bool finished);

void textReplacementSessionDidReceiveEditAction(const UnifiedTextReplacement::Session&, UnifiedTextReplacement::EditAction);

void updateStateForSelectedReplacementIfNeeded();

WEBCORE_EXPORT std::optional<SimpleRange> contextRangeForSessionWithID(const UnifiedTextReplacement::Session::ID&) const;

private:
enum MatchStyle : bool {
No, Yes
};

static CharacterRange characterRange(const SimpleRange& scope, const SimpleRange&);
static SimpleRange resolveCharacterRange(const SimpleRange& scope, CharacterRange);
static uint64_t characterCount(const SimpleRange&);
static String plainText(const SimpleRange&);

std::optional<std::tuple<Node&, DocumentMarker&>> findReplacementMarkerContainingRange(const SimpleRange&) const;
std::optional<std::tuple<Node&, DocumentMarker&>> findReplacementMarkerByID(const SimpleRange& outerRange, const UnifiedTextReplacement::Replacement::ID&) const;

void replaceContentsOfRangeInSessionInternal(const UnifiedTextReplacement::Session::ID&, const SimpleRange&, WTF::Function<void(Editor&)>&&);
void replaceContentsOfRangeInSession(const UnifiedTextReplacement::Session::ID&, const SimpleRange&, const String&);
void replaceContentsOfRangeInSession(const UnifiedTextReplacement::Session::ID&, const SimpleRange&, DocumentFragment&, MatchStyle = MatchStyle::No);

template<UnifiedTextReplacement::Session::ReplacementType Type>
void textReplacementSessionDidReceiveEditAction(const UnifiedTextReplacement::Session&, UnifiedTextReplacement::EditAction);

template<UnifiedTextReplacement::Session::ReplacementType Type>
void didEndTextReplacementSession(const UnifiedTextReplacement::Session&, bool accepted);

RefPtr<Document> document() const;

SingleThreadWeakPtr<Page> m_page;

// FIXME: Unify these states into a single `State` struct.
HashMap<UnifiedTextReplacement::Session::ID, Ref<Range>> m_contextRanges;
HashMap<UnifiedTextReplacement::Session::ID, int> m_replacementLocationOffsets;
HashMap<UnifiedTextReplacement::Session::ID, Ref<DocumentFragment>> m_originalDocumentNodes;
HashMap<UnifiedTextReplacement::Session::ID, Ref<DocumentFragment>> m_replacedDocumentNodes;
};

} // namespace WebKit

#endif
Loading

0 comments on commit e4bbed4

Please sign in to comment.