Title: [264420] trunk
Revision
264420
Author
drou...@apple.com
Date
2020-07-15 14:15:55 -0700 (Wed, 15 Jul 2020)

Log Message

should represent `TextPlaceholderElement` as an `NSTextAttachmentCharacter` instead of a `\n`
https://bugs.webkit.org/show_bug.cgi?id=214331
<rdar://problem/64779558>

Reviewed by Wenson Hsieh.

Source/WebCore:

* editing/TextIterator.cpp:
(WebCore::shouldEmitReplacementInsteadOfNode): Added.
(WebCore::shouldEmitNewlinesBeforeAndAfterNode):
(WebCore::TextIterator::representNodeOffsetZero):
Placeholders should eventually be removed, so stringifying them as a newline doesn't make
sense as they should be treated as a "slot" in the existing flow of the surrounding content
without changing the characteristics of the content (e.g. a sentence with a placeholder
should remain as a sentence, not suddenly become two paragraphs separated by a placeholder).

Source/WebKit:

* Platform/spi/ios/UIKitSPI.h:
Add missing SPI declarations.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView removeTextPlaceholder:willInsertText:completionHandler:]):
Drive-by: ensure that the `completionHandler` is always called.

Tools:

* TestWebKitAPI/ios/UIKitSPI.h:
Add missing SPI declarations.

* TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm:
(-[TestWKWebView synchronouslyInsertTextPlaceholderWithSize:]): Added.
(-[TestWKWebView synchronouslyRemoveTextPlaceholder:willInsertText:]): Added.
(TEST.DocumentEditingContext.RequestBeforeInlinePlaceholder): Added.
(TEST.DocumentEditingContext.RequestAfterInlinePlaceholder): Added.
(TEST.DocumentEditingContext.RequestBeforeBlockPlaceholder): Added.
(TEST.DocumentEditingContext.RequestAfterBlockPlaceholder): Added.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (264419 => 264420)


--- trunk/Source/WebCore/ChangeLog	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Source/WebCore/ChangeLog	2020-07-15 21:15:55 UTC (rev 264420)
@@ -1,3 +1,20 @@
+2020-07-15  Devin Rousso  <drou...@apple.com>
+
+        should represent `TextPlaceholderElement` as an `NSTextAttachmentCharacter` instead of a `\n`
+        https://bugs.webkit.org/show_bug.cgi?id=214331
+        <rdar://problem/64779558>
+
+        Reviewed by Wenson Hsieh.
+
+        * editing/TextIterator.cpp:
+        (WebCore::shouldEmitReplacementInsteadOfNode): Added.
+        (WebCore::shouldEmitNewlinesBeforeAndAfterNode):
+        (WebCore::TextIterator::representNodeOffsetZero):
+        Placeholders should eventually be removed, so stringifying them as a newline doesn't make
+        sense as they should be treated as a "slot" in the existing flow of the surrounding content
+        without changing the characteristics of the content (e.g. a sentence with a placeholder
+        should remain as a sentence, not suddenly become two paragraphs separated by a placeholder).
+
 2020-07-15  Stephan Szabo  <stephan.sz...@sony.com>
 
         [PlayStation] Build fix after r264213

Modified: trunk/Source/WebCore/editing/TextIterator.cpp (264419 => 264420)


--- trunk/Source/WebCore/editing/TextIterator.cpp	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Source/WebCore/editing/TextIterator.cpp	2020-07-15 21:15:55 UTC (rev 264420)
@@ -58,6 +58,7 @@
 #include "SimpleLineLayoutResolver.h"
 #include "TextBoundaries.h"
 #include "TextControlInnerElements.h"
+#include "TextPlaceholderElement.h"
 #include "VisiblePosition.h"
 #include "VisibleUnits.h"
 #include <unicode/unorm2.h>
@@ -803,6 +804,13 @@
         || element.hasTagName(h6Tag);
 }
 
+static bool shouldEmitReplacementInsteadOfNode(const Node& node)
+{
+    // Placeholders should eventually disappear, so treating them as a line break doesn't make sense
+    // as when they are removed the text after it is combined with the text before it.
+    return is<TextPlaceholderElement>(node);
+}
+
 static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node)
 {
     // Block flow (versus inline flow) is represented by having
@@ -840,7 +848,10 @@
         if (table && !table->isInline())
             return true;
     }
-    
+
+    if (shouldEmitReplacementInsteadOfNode(node))
+        return false;
+
     return !renderer->isInline()
         && is<RenderBlock>(*renderer)
         && !renderer->isFloatingOrOutOfFlowPositioned()
@@ -998,6 +1009,9 @@
     } else if (shouldEmitSpaceBeforeAndAfterNode(*m_node)) {
         if (shouldRepresentNodeOffsetZero())
             emitCharacter(' ', *m_node->parentNode(), m_node, 0, 0);
+    } else if (shouldEmitReplacementInsteadOfNode(*m_node)) {
+        if (shouldRepresentNodeOffsetZero())
+            emitCharacter(0xFFFC, *m_node->parentNode(), m_node, 0, 0);
     }
 }
 

Modified: trunk/Source/WebKit/ChangeLog (264419 => 264420)


--- trunk/Source/WebKit/ChangeLog	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Source/WebKit/ChangeLog	2020-07-15 21:15:55 UTC (rev 264420)
@@ -1,3 +1,18 @@
+2020-07-15  Devin Rousso  <drou...@apple.com>
+
+        should represent `TextPlaceholderElement` as an `NSTextAttachmentCharacter` instead of a `\n`
+        https://bugs.webkit.org/show_bug.cgi?id=214331
+        <rdar://problem/64779558>
+
+        Reviewed by Wenson Hsieh.
+
+        * Platform/spi/ios/UIKitSPI.h:
+        Add missing SPI declarations.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView removeTextPlaceholder:willInsertText:completionHandler:]):
+        Drive-by: ensure that the `completionHandler` is always called.
+
 2020-07-15  Simon Fraser  <simon.fra...@apple.com>
 
         itsnicethat.com page is sometimes non-scrollable

Modified: trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h (264419 => 264420)


--- trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Source/WebKit/Platform/spi/ios/UIKitSPI.h	2020-07-15 21:15:55 UTC (rev 264420)
@@ -724,6 +724,9 @@
 - (void)_cancelLongPressGestureRecognizer;
 
 @optional
+- (void)insertTextPlaceholderWithSize:(CGSize)size completionHandler:(void (^)(UITextPlaceholder *))completionHandler;
+- (void)removeTextPlaceholder:(UITextPlaceholder *)placeholder willInsertText:(BOOL)willInsertText completionHandler:(void (^)(void))completionHandler;
+
 - (void)clearSelection;
 - (void)replaceDictatedText:(NSString *)oldText withText:(NSString *)newText;
 - (void)requestDictationContext:(void (^)(NSString *selectedText, NSString *prefixText, NSString *postfixText))completionHandler;

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (264419 => 264420)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2020-07-15 21:15:55 UTC (rev 264420)
@@ -7938,6 +7938,8 @@
     // FIXME: Implement support for willInsertText. See <https://bugs.webkit.org/show_bug.cgi?id=208747>.
     if (auto* wkTextPlaceholder = dynamic_objc_cast<WKTextPlaceholder>(placeholder))
         _page->removeTextPlaceholder(wkTextPlaceholder.elementContext, makeBlockPtr(completionHandler));
+    else
+        completionHandler();
 }
 
 static Vector<WebCore::IntSize> sizesOfPlaceholderElementsToInsertWhenDroppingItems(NSArray<NSItemProvider *> *itemProviders)

Modified: trunk/Tools/ChangeLog (264419 => 264420)


--- trunk/Tools/ChangeLog	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Tools/ChangeLog	2020-07-15 21:15:55 UTC (rev 264420)
@@ -1,3 +1,22 @@
+2020-07-15  Devin Rousso  <drou...@apple.com>
+
+        should represent `TextPlaceholderElement` as an `NSTextAttachmentCharacter` instead of a `\n`
+        https://bugs.webkit.org/show_bug.cgi?id=214331
+        <rdar://problem/64779558>
+
+        Reviewed by Wenson Hsieh.
+
+        * TestWebKitAPI/ios/UIKitSPI.h:
+        Add missing SPI declarations.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm:
+        (-[TestWKWebView synchronouslyInsertTextPlaceholderWithSize:]): Added.
+        (-[TestWKWebView synchronouslyRemoveTextPlaceholder:willInsertText:]): Added.
+        (TEST.DocumentEditingContext.RequestBeforeInlinePlaceholder): Added.
+        (TEST.DocumentEditingContext.RequestAfterInlinePlaceholder): Added.
+        (TEST.DocumentEditingContext.RequestBeforeBlockPlaceholder): Added.
+        (TEST.DocumentEditingContext.RequestAfterBlockPlaceholder): Added.
+
 2020-07-15  Jonathan Bedard  <jbed...@apple.com>
 
         [run-_javascript_core-tests] nativeArchitecture should never be arm64e

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm (264419 => 264420)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/DocumentEditingContext.mm	2020-07-15 21:15:55 UTC (rev 264420)
@@ -151,6 +151,27 @@
     return result.autorelease();
 }
 
+- (UITextPlaceholder *)synchronouslyInsertTextPlaceholderWithSize:(CGSize)size
+{
+    __block bool finished = false;
+    __block RetainPtr<UITextPlaceholder> result;
+    [self.textInputContentView insertTextPlaceholderWithSize:size completionHandler:^(UITextPlaceholder *placeholder) {
+        result = placeholder;
+        finished = true;
+    }];
+    TestWebKitAPI::Util::run(&finished);
+    return result.autorelease();
+}
+
+- (void)synchronouslyRemoveTextPlaceholder:(UITextPlaceholder *)placeholder willInsertText:(BOOL)willInsertText
+{
+    __block bool finished = false;
+    [self.textInputContentView removeTextPlaceholder:placeholder willInsertText:willInsertText completionHandler:^(void) {
+        finished = true;
+    }];
+    TestWebKitAPI::Util::run(&finished);
+}
+
 @end
 
 static NSString *applyStyle(NSString *htmlString)
@@ -833,6 +854,74 @@
     EXPECT_NSSTRING_EQ(" over the lazy", context.contextAfter);
 }
 
+TEST(DocumentEditingContext, RequestBeforeInlinePlaceholder)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView synchronouslyLoadHTMLString:applyStyle(@"<span id='wrapper' contenteditable>hello world</span>")];
+    [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(wrapper.firstChild, 5)"]; // Place cursor after "hello".
+
+    auto *placeholder = [webView synchronouslyInsertTextPlaceholderWithSize:CGSizeMake(5, 5)];
+    EXPECT_NOT_NULL(placeholder);
+
+    auto *context = [webView synchronouslyRequestDocumentContext:makeRequest(UIWKDocumentRequestText, UITextGranularityCharacter, 200)];
+    EXPECT_NOT_NULL(context);
+    EXPECT_NSSTRING_EQ("hello", context.contextBefore);
+    EXPECT_NSSTRING_EQ("\uFFFC world", context.contextAfter);
+
+    [webView synchronouslyRemoveTextPlaceholder:placeholder willInsertText:NO];
+}
+
+TEST(DocumentEditingContext, RequestAfterInlinePlaceholder)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView synchronouslyLoadHTMLString:applyStyle(@"<span id='wrapper' contenteditable>hello world</span>")];
+    [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(wrapper.firstChild, 6)"]; // Place cursor before "world".
+
+    auto *placeholder = [webView synchronouslyInsertTextPlaceholderWithSize:CGSizeMake(5, 5)];
+    EXPECT_NOT_NULL(placeholder);
+
+    auto *context = [webView synchronouslyRequestDocumentContext:makeRequest(UIWKDocumentRequestText, UITextGranularityCharacter, 200)];
+    EXPECT_NOT_NULL(context);
+    EXPECT_NSSTRING_EQ("hello ", context.contextBefore);
+    EXPECT_NSSTRING_EQ("\uFFFCworld", context.contextAfter);
+
+    [webView synchronouslyRemoveTextPlaceholder:placeholder willInsertText:NO];
+}
+
+TEST(DocumentEditingContext, RequestBeforeBlockPlaceholder)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView synchronouslyLoadHTMLString:applyStyle(@"<span id='wrapper' contenteditable>hello world</span>")];
+    [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(wrapper.firstChild, 5)"]; // Place cursor after "hello".
+
+    auto *placeholder = [webView synchronouslyInsertTextPlaceholderWithSize:CGSizeMake(0, 5)];
+    EXPECT_NOT_NULL(placeholder);
+
+    auto *context = [webView synchronouslyRequestDocumentContext:makeRequest(UIWKDocumentRequestText, UITextGranularityCharacter, 200)];
+    EXPECT_NOT_NULL(context);
+    EXPECT_NSSTRING_EQ("hello", context.contextBefore);
+    EXPECT_NSSTRING_EQ("\uFFFC world", context.contextAfter);
+
+    [webView synchronouslyRemoveTextPlaceholder:placeholder willInsertText:NO];
+}
+
+TEST(DocumentEditingContext, RequestAfterBlockPlaceholder)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
+    [webView synchronouslyLoadHTMLString:applyStyle(@"<span id='wrapper' contenteditable>hello world</span>")];
+    [webView stringByEvaluatingJavaScript:@"getSelection().setPosition(wrapper.firstChild, 6)"]; // Place cursor before "world".
+
+    auto *placeholder = [webView synchronouslyInsertTextPlaceholderWithSize:CGSizeMake(0, 5)];
+    EXPECT_NOT_NULL(placeholder);
+
+    auto *context = [webView synchronouslyRequestDocumentContext:makeRequest(UIWKDocumentRequestText, UITextGranularityCharacter, 200)];
+    EXPECT_NOT_NULL(context);
+    EXPECT_NSSTRING_EQ("hello", context.contextBefore);
+    EXPECT_NSSTRING_EQ("\uFFFCworld", context.contextAfter);
+
+    [webView synchronouslyRemoveTextPlaceholder:placeholder willInsertText:NO];
+}
+
 // MARK: Tests using sentence granularity
 
 constexpr NSString * const threeSentencesExample = @"<p id='text' contenteditable>The first sentence. The second sentence. The third sentence.</p>";

Modified: trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h (264419 => 264420)


--- trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h	2020-07-15 21:15:16 UTC (rev 264419)
+++ trunk/Tools/TestWebKitAPI/ios/UIKitSPI.h	2020-07-15 21:15:55 UTC (rev 264420)
@@ -181,6 +181,10 @@
 - (void)updateSelectionWithExtentPoint:(CGPoint)point completionHandler:(void (^)(BOOL selectionEndIsMoving))completionHandler;
 - (void)updateSelectionWithExtentPoint:(CGPoint)point withBoundary:(UITextGranularity)granularity completionHandler:(void (^)(BOOL selectionEndIsMoving))completionHandler;
 @property (nonatomic, readonly) NSString *selectedText;
+
+@optional
+- (void)insertTextPlaceholderWithSize:(CGSize)size completionHandler:(void (^)(UITextPlaceholder *))completionHandler;
+- (void)removeTextPlaceholder:(UITextPlaceholder *)placeholder willInsertText:(BOOL)willInsertText completionHandler:(void (^)(void))completionHandler;
 @end
 
 @interface UIViewController ()
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to