UIWKDocumentRequestSpatialAndCurrentSelection should limit context to the editable root of the current selection
https://bugs.webkit.org/show_bug.cgi?id=235595
rdar://87835602

Reviewed by Aditya Keerthi.

Source/WebKit:

Adjust the behavior of document editing context requests in the case where the `SpatialAndCurrentSelection` flag
is specified, but no explicit `textInputContext` has been given. Instead of using the hit-tested corners of the
spatial request as-is, clamp to the visible start and end positions of the current editable root (only if it
exists).

This adjustment makes this particular request configuration useful for text input clients that just want to
request text input context information for the current editable element in a given rect, but don't already have
a text input element identifier.

Test: DocumentEditingContext.SpatialAndCurrentSelectionRequest_LimitContextToEditableRoot

* Platform/spi/ios/UIKitSPI.h:

Drive-by fix: also clean up a couple of old staging declarations.

* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::requestDocumentEditingContext):

Tools:

Add a new API test to exercise the change.

* TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm:
(TEST):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@288575 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 6396180..cd9916a 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,29 @@
+2022-01-25  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        UIWKDocumentRequestSpatialAndCurrentSelection should limit context to the editable root of the current selection
+        https://bugs.webkit.org/show_bug.cgi?id=235595
+        rdar://87835602
+
+        Reviewed by Aditya Keerthi.
+
+        Adjust the behavior of document editing context requests in the case where the `SpatialAndCurrentSelection` flag
+        is specified, but no explicit `textInputContext` has been given. Instead of using the hit-tested corners of the
+        spatial request as-is, clamp to the visible start and end positions of the current editable root (only if it
+        exists).
+
+        This adjustment makes this particular request configuration useful for text input clients that just want to
+        request text input context information for the current editable element in a given rect, but don't already have
+        a text input element identifier.
+
+        Test: DocumentEditingContext.SpatialAndCurrentSelectionRequest_LimitContextToEditableRoot
+
+        * Platform/spi/ios/UIKitSPI.h:
+
+        Drive-by fix: also clean up a couple of old staging declarations.
+
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::requestDocumentEditingContext):
+
 2022-01-25  Sihui Liu  <sihui_liu@apple.com>
 
         Regression (r235236): NetworkStorageManager sends messages to wrong StorageAreaMap
diff --git a/Source/WebKit/Platform/spi/ios/UIKitSPI.h b/Source/WebKit/Platform/spi/ios/UIKitSPI.h
index bf7ff20..8522d9c 100644
--- a/Source/WebKit/Platform/spi/ios/UIKitSPI.h
+++ b/Source/WebKit/Platform/spi/ios/UIKitSPI.h
@@ -1259,6 +1259,8 @@
     UIWKDocumentRequestRects = 1 << 2,
     UIWKDocumentRequestSpatial = 1 << 3,
     UIWKDocumentRequestAnnotation = 1 << 4,
+    UIWKDocumentRequestMarkedTextRects =  1 << 5,
+    UIWKDocumentRequestSpatialAndCurrentSelection =  1 << 6,
 };
 
 @interface UIWKDocumentRequest : NSObject
@@ -1341,9 +1343,6 @@
 
 #endif // USE(APPLE_INTERNAL_SDK)
 
-#define UIWKDocumentRequestMarkedTextRects (1 << 5)
-#define UIWKDocumentRequestSpatialAndCurrentSelection (1 << 6)
-
 #if HAVE(PASTEBOARD_DATA_OWNER)
 
 @interface UIResponder (Staging_73852335)
diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
index 61f51b3..422f9de 100644
--- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
+++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
@@ -4490,6 +4490,16 @@
         // FIXME: We might need to be a bit more careful that we get something useful (test the other corners?).
         rangeOfInterest.start = visiblePositionForPointInRootViewCoordinates(frame.get(), request.rect.minXMinYCorner());
         rangeOfInterest.end = visiblePositionForPointInRootViewCoordinates(frame.get(), request.rect.maxXMaxYCorner());
+        if (request.options.contains(DocumentEditingContextRequest::Options::SpatialAndCurrentSelection)) {
+            if (RefPtr rootEditableElement = selection.rootEditableElement()) {
+                VisiblePosition startOfEditableRoot { firstPositionInOrBeforeNode(rootEditableElement.get()) };
+                VisiblePosition endOfEditableRoot { lastPositionInOrAfterNode(rootEditableElement.get()) };
+                if (rangeOfInterest.start < startOfEditableRoot)
+                    rangeOfInterest.start = WTFMove(startOfEditableRoot);
+                if (rangeOfInterest.end > endOfEditableRoot)
+                    rangeOfInterest.end = WTFMove(endOfEditableRoot);
+            }
+        }
     } else if (!selection.isNone())
         rangeOfInterest = selectionRange;
 
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index d74e978..f6984e4 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,16 @@
+2022-01-25  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        UIWKDocumentRequestSpatialAndCurrentSelection should limit context to the editable root of the current selection
+        https://bugs.webkit.org/show_bug.cgi?id=235595
+        rdar://87835602
+
+        Reviewed by Aditya Keerthi.
+
+        Add a new API test to exercise the change.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm:
+        (TEST):
+
 2022-01-25  Jonathan Bedard  <jbedard@apple.com>
 
         [git-webkit] Use cwd as default path
diff --git a/Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm b/Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm
index ad4e710..6235408 100644
--- a/Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm
+++ b/Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm
@@ -784,6 +784,19 @@
     EXPECT_NSSTRING_EQ(" the lazy dog.", context.contextAfter);
 }
 
+TEST(DocumentEditingContext, SpatialAndCurrentSelectionRequest_LimitContextToEditableRoot)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 980, 600)]);
+
+    [webView synchronouslyLoadHTMLString:applyAhemStyle(@"hello world <textarea>foo bar baz</textarea> this is a test")];
+    [webView stringByEvaluatingJavaScript:@"document.querySelector('textarea').select()"];
+
+    UIWKDocumentContext *context = [webView synchronouslyRequestDocumentContext:makeRequest(UIWKDocumentRequestText | UIWKDocumentRequestSpatialAndCurrentSelection, UITextGranularityWord, 200, CGRectMake(0, 0, 980, 600))];
+    EXPECT_NULL(context.contextBefore);
+    EXPECT_NSSTRING_EQ("foo bar baz", context.selectedText);
+    EXPECT_NULL(context.contextAfter);
+}
+
 TEST(DocumentEditingContext, RequestRectsInTextAreaAcrossWordWrappedLine)
 {
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);