Title: [229783] trunk
Revision
229783
Author
wenson_hs...@apple.com
Date
2018-03-20 19:28:29 -0700 (Tue, 20 Mar 2018)

Log Message

Add AssistedNodeInformation plumbing for form control placeholder text and label text
https://bugs.webkit.org/show_bug.cgi?id=183802
<rdar://problem/38686273>

Reviewed by Tim Horton.

Source/WebKit:

Surfaces some additional information about the currently focused element to the input delegate in the UI process.
See comments below for more details.

Test: WebKit.FocusedElementInfo

* Shared/AssistedNodeInformation.cpp:
(WebKit::AssistedNodeInformation::encode const):
(WebKit::AssistedNodeInformation::decode):
* Shared/AssistedNodeInformation.h:

Add `placeholder` and `label` to AssistedNodeInformation, which capture the value of the placeholder attribute
and the text of the first associated label element for the focused form control. Also add boilerplate encoder/
decoder support for these members.

* UIProcess/API/Cocoa/_WKFocusedElementInfo.h:

Augment _WKFocusedElementInfo to include placeholder and label.

* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKFocusedElementInfo initWithAssistedNodeInformation:isUserInitiated:userObject:]):
(-[WKFocusedElementInfo label]):
(-[WKFocusedElementInfo placeholder]):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getAssistedNodeInformation):

For input elements and textareas, set the placeholder to the value of the placeholder attribute. For all
elements with associated labels, grab the inner text of the first label that is not empty, ignoring all labels
that are `display: none` (i.e. not being rendered).

Tools:

Adds a new API test to exercise new placeholder and label SPI on _WKFocusedFormElement.

* TestWebKitAPI/Tests/WebKitCocoa/_WKInputDelegate.mm:
(-[InputDelegate _webView:focusShouldStartInputSession:]):
(-[InputDelegate shouldStartInputSessionHandler]):
(-[InputDelegate setShouldStartInputSessionHandler:]):
(TEST):
(-[FormSubmissionDelegate webView:startURLSchemeTask:]): Deleted.
(-[FormSubmissionDelegate webView:stopURLSchemeTask:]): Deleted.
(-[FormSubmissionDelegate _webView:willSubmitFormValues:userObject:submissionHandler:]): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (229782 => 229783)


--- trunk/Source/WebKit/ChangeLog	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Source/WebKit/ChangeLog	2018-03-21 02:28:29 UTC (rev 229783)
@@ -1,3 +1,40 @@
+2018-03-20  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        Add AssistedNodeInformation plumbing for form control placeholder text and label text
+        https://bugs.webkit.org/show_bug.cgi?id=183802
+        <rdar://problem/38686273>
+
+        Reviewed by Tim Horton.
+
+        Surfaces some additional information about the currently focused element to the input delegate in the UI process.
+        See comments below for more details.
+
+        Test: WebKit.FocusedElementInfo
+
+        * Shared/AssistedNodeInformation.cpp:
+        (WebKit::AssistedNodeInformation::encode const):
+        (WebKit::AssistedNodeInformation::decode):
+        * Shared/AssistedNodeInformation.h:
+
+        Add `placeholder` and `label` to AssistedNodeInformation, which capture the value of the placeholder attribute
+        and the text of the first associated label element for the focused form control. Also add boilerplate encoder/
+        decoder support for these members.
+
+        * UIProcess/API/Cocoa/_WKFocusedElementInfo.h:
+
+        Augment _WKFocusedElementInfo to include placeholder and label.
+
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKFocusedElementInfo initWithAssistedNodeInformation:isUserInitiated:userObject:]):
+        (-[WKFocusedElementInfo label]):
+        (-[WKFocusedElementInfo placeholder]):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getAssistedNodeInformation):
+
+        For input elements and textareas, set the placeholder to the value of the placeholder attribute. For all
+        elements with associated labels, grab the inner text of the first label that is not empty, ignoring all labels
+        that are `display: none` (i.e. not being rendered).
+
 2018-03-20  Brady Eidson  <beid...@apple.com>
 
         First piece of process swapping on navigation.

Modified: trunk/Source/WebKit/Shared/AssistedNodeInformation.cpp (229782 => 229783)


--- trunk/Source/WebKit/Shared/AssistedNodeInformation.cpp	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Source/WebKit/Shared/AssistedNodeInformation.cpp	2018-03-21 02:28:29 UTC (rev 229783)
@@ -89,6 +89,8 @@
     encoder << acceptsAutofilledLoginCredentials;
     encoder << representingPageURL;
     encoder.encodeEnum(autofillFieldName);
+    encoder << placeholder;
+    encoder << label;
     encoder << assistedNodeIdentifier;
 }
 
@@ -172,6 +174,12 @@
     if (!decoder.decodeEnum(result.autofillFieldName))
         return false;
 
+    if (!decoder.decode(result.placeholder))
+        return false;
+
+    if (!decoder.decode(result.label))
+        return false;
+
     if (!decoder.decode(result.assistedNodeIdentifier))
         return false;
 

Modified: trunk/Source/WebKit/Shared/AssistedNodeInformation.h (229782 => 229783)


--- trunk/Source/WebKit/Shared/AssistedNodeInformation.h	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Source/WebKit/Shared/AssistedNodeInformation.h	2018-03-21 02:28:29 UTC (rev 229783)
@@ -113,6 +113,8 @@
     bool acceptsAutofilledLoginCredentials { false };
     WebCore::URL representingPageURL;
     WebCore::AutofillFieldName autofillFieldName { WebCore::AutofillFieldName::None };
+    String placeholder;
+    String label;
 
     uint64_t assistedNodeIdentifier { 0 };
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKFocusedElementInfo.h (229782 => 229783)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKFocusedElementInfo.h	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKFocusedElementInfo.h	2018-03-21 02:28:29 UTC (rev 229783)
@@ -68,6 +68,12 @@
 /* The value of the input at the time it was focused. */
 @property (nonatomic, readonly, copy) NSString *value;
 
+/* The placeholder text of the input. */
+@property (nonatomic, readonly, copy) NSString *placeholder;
+
+/* The text of a label element associated with the input. */
+@property (nonatomic, readonly, copy) NSString *label;
+
 /**
  * Whether the element was focused due to user interaction. NO indicates that
  * the element was focused programmatically, e.g. by calling focus() in _javascript_

Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (229782 => 229783)


--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm	2018-03-21 02:28:29 UTC (rev 229783)
@@ -407,6 +407,8 @@
     RetainPtr<NSString> _value;
     BOOL _isUserInitiated;
     RetainPtr<NSObject <NSSecureCoding>> _userObject;
+    RetainPtr<NSString> _placeholder;
+    RetainPtr<NSString> _label;
 }
 
 - (instancetype)initWithAssistedNodeInformation:(const AssistedNodeInformation&)information isUserInitiated:(BOOL)isUserInitiated userObject:(NSObject <NSSecureCoding> *)userObject
@@ -473,6 +475,8 @@
     _value = information.value;
     _isUserInitiated = isUserInitiated;
     _userObject = userObject;
+    _placeholder = information.placeholder;
+    _label = information.label;
     return self;
 }
 
@@ -495,6 +499,17 @@
 {
     return _userObject.get();
 }
+
+- (NSString *)label
+{
+    return _label.get();
+}
+
+- (NSString *)placeholder
+{
+    return _placeholder.get();
+}
+
 @end
 
 #if ENABLE(DRAG_SUPPORT)

Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (229782 => 229783)


--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm	2018-03-21 02:28:29 UTC (rev 229783)
@@ -91,6 +91,7 @@
 #import <WebCore/MainFrame.h>
 #import <WebCore/MediaSessionManagerIOS.h>
 #import <WebCore/Node.h>
+#import <WebCore/NodeList.h>
 #import <WebCore/NotImplemented.h>
 #import <WebCore/Page.h>
 #import <WebCore/Pasteboard.h>
@@ -2749,6 +2750,22 @@
     information.hasPreviousNode = hasAssistableElement(m_assistedNode.get(), *m_page, false);
     information.assistedNodeIdentifier = m_currentAssistedNodeIdentifier;
 
+    if (is<LabelableElement>(*m_assistedNode)) {
+        auto labels = downcast<LabelableElement>(*m_assistedNode).labels();
+        Vector<Ref<Element>> associatedLabels;
+        for (unsigned index = 0; index < labels->length(); ++index) {
+            if (is<Element>(labels->item(index)) && labels->item(index)->renderer())
+                associatedLabels.append(downcast<Element>(*labels->item(index)));
+        }
+        for (auto& labelElement : associatedLabels) {
+            auto text = labelElement->innerText();
+            if (!text.isEmpty()) {
+                information.label = WTFMove(text);
+                break;
+            }
+        }
+    }
+
     if (is<HTMLSelectElement>(*m_assistedNode)) {
         HTMLSelectElement& element = downcast<HTMLSelectElement>(*m_assistedNode);
         information.elementType = InputType::Select;
@@ -2779,6 +2796,7 @@
         information.isReadOnly = element.isReadOnly();
         information.value = element.value();
         information.autofillFieldName = WebCore::toAutofillFieldName(element.autofillData().fieldName);
+        information.placeholder = element.attributeWithoutSynchronization(HTMLNames::placeholderAttr);
     } else if (is<HTMLInputElement>(*m_assistedNode)) {
         HTMLInputElement& element = downcast<HTMLInputElement>(*m_assistedNode);
         HTMLFormElement* form = element.form();
@@ -2788,6 +2806,7 @@
         information.representingPageURL = element.document().urlForBindings();
         information.autocapitalizeType = element.autocapitalizeType();
         information.isAutocorrect = element.shouldAutocorrect();
+        information.placeholder = element.attributeWithoutSynchronization(HTMLNames::placeholderAttr);
         if (element.isPasswordField())
             information.elementType = InputType::Password;
         else if (element.isSearchField())

Modified: trunk/Tools/ChangeLog (229782 => 229783)


--- trunk/Tools/ChangeLog	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Tools/ChangeLog	2018-03-21 02:28:29 UTC (rev 229783)
@@ -1,3 +1,22 @@
+2018-03-20  Wenson Hsieh  <wenson_hs...@apple.com>
+
+        Add AssistedNodeInformation plumbing for form control placeholder text and label text
+        https://bugs.webkit.org/show_bug.cgi?id=183802
+        <rdar://problem/38686273>
+
+        Reviewed by Tim Horton.
+
+        Adds a new API test to exercise new placeholder and label SPI on _WKFocusedFormElement.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/_WKInputDelegate.mm:
+        (-[InputDelegate _webView:focusShouldStartInputSession:]):
+        (-[InputDelegate shouldStartInputSessionHandler]):
+        (-[InputDelegate setShouldStartInputSessionHandler:]):
+        (TEST):
+        (-[FormSubmissionDelegate webView:startURLSchemeTask:]): Deleted.
+        (-[FormSubmissionDelegate webView:stopURLSchemeTask:]): Deleted.
+        (-[FormSubmissionDelegate _webView:willSubmitFormValues:userObject:submissionHandler:]): Deleted.
+
 2018-03-20  Basuke Suzuki  <basuke.suz...@sony.com>
 
         [WinCairo] Fix to run-webkit-httpd from native Windows.

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKInputDelegate.mm (229782 => 229783)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKInputDelegate.mm	2018-03-21 01:31:09 UTC (rev 229782)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/_WKInputDelegate.mm	2018-03-21 02:28:29 UTC (rev 229783)
@@ -27,8 +27,12 @@
 
 #import "PlatformUtilities.h"
 #import "Test.h"
+#import "TestWKWebView.h"
 #import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKFocusedElementInfo.h>
+#import <WebKit/_WKFormInputSession.h>
 #import <WebKit/_WKInputDelegate.h>
+#import <wtf/BlockPtr.h>
 #import <wtf/RetainPtr.h>
 
 #if WK_API_ENABLED
@@ -36,10 +40,13 @@
 static bool done;
 static bool willSubmitFormValuesCalled;
 
-@interface FormSubmissionDelegate : NSObject <_WKInputDelegate, WKURLSchemeHandler>
+@interface InputDelegate : NSObject <_WKInputDelegate, WKURLSchemeHandler>
+@property (nonatomic, copy) BOOL(^shouldStartInputSessionHandler)(id <_WKFocusedElementInfo>);
 @end
 
-@implementation FormSubmissionDelegate
+@implementation InputDelegate {
+    BlockPtr<BOOL(id <_WKFocusedElementInfo>)> _shouldStartInputSessionHandler;
+}
 
 - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task
 {
@@ -64,11 +71,28 @@
     submissionHandler();
 }
 
+- (BOOL)_webView:(WKWebView *)webView focusShouldStartInputSession:(id <_WKFocusedElementInfo>)info
+{
+    if (_shouldStartInputSessionHandler)
+        return _shouldStartInputSessionHandler(info);
+    return [info isUserInitiated];
+}
+
+- (BOOL(^)(id <_WKFocusedElementInfo>))shouldStartInputSessionHandler
+{
+    return _shouldStartInputSessionHandler.get();
+}
+
+- (void)setShouldStartInputSessionHandler:(BOOL(^)(id <_WKFocusedElementInfo>))handler
+{
+    _shouldStartInputSessionHandler = makeBlockPtr(handler);
+}
+
 @end
 
 TEST(WebKit, FormSubmission)
 {
-    auto delegate = adoptNS([[FormSubmissionDelegate alloc] init]);
+    auto delegate = adoptNS([[InputDelegate alloc] init]);
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     [configuration setURLSchemeHandler:delegate.get() forURLScheme:@"test"];
     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
@@ -81,6 +105,47 @@
     TestWebKitAPI::Util::run(&done);
 }
 
+#if PLATFORM(IOS)
+
+TEST(WebKit, FocusedElementInfo)
+{
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
+    auto delegate = adoptNS([[InputDelegate alloc] init]);
+    [webView _setInputDelegate:delegate.get()];
+
+    __block RetainPtr<id <_WKFocusedElementInfo>> currentElement;
+    [delegate setShouldStartInputSessionHandler:^BOOL(id<_WKFocusedElementInfo> element) {
+        currentElement = element;
+        return NO;
+    }];
+
+    [webView synchronouslyLoadHTMLString:@"<label for=''>bar</label><input id='foo'>"];
+    [webView stringByEvaluatingJavaScript:@"foo.focus()"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_WK_STREQ("", [currentElement placeholder]);
+    EXPECT_WK_STREQ("bar", [currentElement label]);
+
+    [webView synchronouslyLoadHTMLString:@"<input placeholder='bar'>"];
+    [webView stringByEvaluatingJavaScript:@"document.querySelector('input').focus()"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_WK_STREQ("bar", [currentElement placeholder]);
+    EXPECT_WK_STREQ("", [currentElement label]);
+
+    [webView synchronouslyLoadHTMLString:@"<label for=''>garply</label><select id='baz'></select>"];
+    [webView stringByEvaluatingJavaScript:@"baz.focus()"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_WK_STREQ("", [currentElement placeholder]);
+    EXPECT_WK_STREQ("garply", [currentElement label]);
+
+    [webView synchronouslyLoadHTMLString:@"<label for='' style='display: none'>bar</label><label for=''></label><input id='foo'><label for=''>garply</label>"];
+    [webView stringByEvaluatingJavaScript:@"foo.focus()"];
+    [webView waitForNextPresentationUpdate];
+    EXPECT_WK_STREQ("", [currentElement placeholder]);
+    EXPECT_WK_STREQ("garply", [currentElement label]);
+}
+
+#endif // PLATFORM(IOS)
+
 #endif // WK_API_ENABLED
 
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to