[Extra zoom mode] Missing label when focusing a <select> with a title attribute but...
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Apr 2018 16:43:53 +0000 (16:43 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Apr 2018 16:43:53 +0000 (16:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184352
<rdar://problem/39237683>

Reviewed by Andy Estes.

Source/WebKit:

Currently, AssistedNodeInformation only sends the `title` of input elements to the UI process. This means that
any information requested in the UI process that is dependent on the `title` of the focused element is broken
in the case of select elements. An existing example of this is the title of the table view controller used to
present select menus on iPad.

To fix this, we simply send the `title` of the focused element across, as long as the focused element is an
HTMLElement. This ensures that there's label text when focusing unlabeled select elements with titles in extra
zoom mode, and also fixes a currenly broken codepath where we show the title of the select in the presented view
controller's title.

Test: fast/forms/ios/ipad/select-with-title.html

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView selectFormPopoverTitle]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:

Add new testing SPI to fetch the title of the UITableViewController presented for the currently focused select
element.

* UIProcess/ios/WKContentViewInteraction.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView selectFormPopoverTitle]):
* UIProcess/ios/forms/WKFormSelectControl.h:
* UIProcess/ios/forms/WKFormSelectControl.mm:
(-[WKFormSelectControl selectFormPopoverTitle]):
* UIProcess/ios/forms/WKFormSelectPopover.h:
* UIProcess/ios/forms/WKFormSelectPopover.mm:
(-[WKSelectPopover initWithView:hasGroups:]):
(-[WKSelectPopover tableViewController]):
* WebProcess/WebPage/ios/WebPageIOS.mm:

Always send the title across if the focused node is an HTMLElement.

(WebKit::WebPage::getAssistedNodeInformation):

Tools:

Add support for UIScriptController::selectFormPopoverTitle, which returns the title of the current select
popover's UITableViewController (for testing purposes).

* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::selectFormPopoverTitle const):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::selectFormPopoverTitle const):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::selectFormPopoverTitle const):

LayoutTests:

Add a new layout test to check that the title of select elements is propagated to the UI process upon focus.
This title is used for several purposes, one of them being the title of select menus in the table view
controller presented when tapping on a select on an iPad, so the test checks that the title of the select is
shown here.

Also moves a select-related helper into UIHelper from basic-gestures.js (since this doesn't involve user gesture
simulation in any way) and also introduces a new UIHelper method for querying the title of the select menu that
is currently being presented.

* fast/forms/ios/ipad/multiple-select-updates-renderer.html:
* fast/forms/ios/ipad/select-with-title-expected.txt: Added.
* fast/forms/ios/ipad/select-with-title.html: Copied from LayoutTests/fast/forms/ios/ipad/multiple-select-updates-renderer.html.
* resources/basic-gestures.js:
* resources/ui-helper.js:
(window.UIHelper.selectFormAccessoryPickerRow):
(window.UIHelper.selectFormPopoverTitle):
(window.UIHelper):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230527 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/ios/ipad/multiple-select-updates-renderer.html
LayoutTests/fast/forms/ios/ipad/select-with-title-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/ios/ipad/select-with-title.html [new file with mode: 0644]
LayoutTests/resources/basic-gestures.js
LayoutTests/resources/ui-helper.js
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.h
Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.mm
Source/WebKit/UIProcess/ios/forms/WKFormSelectPopover.h
Source/WebKit/UIProcess/ios/forms/WKFormSelectPopover.mm
Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm
Tools/ChangeLog
Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index 97d027d..d8842c1 100644 (file)
@@ -1,3 +1,29 @@
+2018-04-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] Missing label when focusing a <select> with a title attribute but no associated <label>
+        https://bugs.webkit.org/show_bug.cgi?id=184352
+        <rdar://problem/39237683>
+
+        Reviewed by Andy Estes.
+
+        Add a new layout test to check that the title of select elements is propagated to the UI process upon focus.
+        This title is used for several purposes, one of them being the title of select menus in the table view
+        controller presented when tapping on a select on an iPad, so the test checks that the title of the select is
+        shown here.
+
+        Also moves a select-related helper into UIHelper from basic-gestures.js (since this doesn't involve user gesture
+        simulation in any way) and also introduces a new UIHelper method for querying the title of the select menu that
+        is currently being presented.
+
+        * fast/forms/ios/ipad/multiple-select-updates-renderer.html:
+        * fast/forms/ios/ipad/select-with-title-expected.txt: Added.
+        * fast/forms/ios/ipad/select-with-title.html: Copied from LayoutTests/fast/forms/ios/ipad/multiple-select-updates-renderer.html.
+        * resources/basic-gestures.js:
+        * resources/ui-helper.js:
+        (window.UIHelper.selectFormAccessoryPickerRow):
+        (window.UIHelper.selectFormPopoverTitle):
+        (window.UIHelper):
+
 2018-04-10  Ryan Haddad  <ryanhaddad@apple.com>
 
         Mark imported/w3c/web-platform-tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback.html as flaky.
index b6e71bf..e9f054c 100644 (file)
@@ -14,6 +14,7 @@
     }
 </style>
 <script src="../../../../resources/basic-gestures.js"></script>
+<script src="../../../../resources/ui-helper.js"></script>
 <script>
     async function run()
     {
@@ -21,7 +22,7 @@
             return;
 
         await tapAtPoint(100, 100);
-        await selectFormAccessoryPickerRow(0);
+        await UIHelper.selectFormAccessoryPickerRow(0);
         doneEvaluatingUIScript = true;
         checkDone();
     }
diff --git a/LayoutTests/fast/forms/ios/ipad/select-with-title-expected.txt b/LayoutTests/fast/forms/ios/ipad/select-with-title-expected.txt
new file mode 100644 (file)
index 0000000..0ffa9a4
--- /dev/null
@@ -0,0 +1,6 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS popoverTitle is document.getElementById('select').title
+
+
diff --git a/LayoutTests/fast/forms/ios/ipad/select-with-title.html b/LayoutTests/fast/forms/ios/ipad/select-with-title.html
new file mode 100644 (file)
index 0000000..fda5ffb
--- /dev/null
@@ -0,0 +1,58 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+<style>
+    body, html {
+        width: 100%;
+        height: 100%;
+        margin: 0;
+    }
+    select {
+        width: 200px;
+        height: 200px;
+    }
+</style>
+<script src="../../../../resources/js-test.js"></script>
+<script src="../../../../resources/ui-helper.js"></script>
+<script src="../../../../resources/basic-gestures.js"></script>
+<script>
+    async function run()
+    {
+        if (!window.testRunner)
+            return;
+
+        await tapAtPoint(100, 100);
+        popoverTitle = await UIHelper.selectFormPopoverTitle();
+        await UIHelper.selectFormAccessoryPickerRow(1);
+        checkDone();
+    }
+
+    function checkDone()
+    {
+        doneCount = 1 + (window.doneCount ? doneCount : 0);
+        if (doneCount == 2 && window.testRunner) {
+            shouldBe("popoverTitle", "document.getElementById('select').title");
+            testRunner.notifyDone();
+        }
+    }
+</script>
+</head>
+<body onload="run()">
+    <select title="This is a title" id="select">
+        <option>1</option>
+        <option>2</option>
+        <option>3</option>
+    </select>
+    <pre id="output"></pre>
+</body>
+<script>
+    select.addEventListener("blur", checkDone);
+    select.addEventListener("change", () => select.blur());
+
+    if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.dumpAsText();
+    }
+</script>
+</html>
index 9d46d2c..c9659a4 100644 (file)
@@ -140,12 +140,6 @@ function touchAndDragFromPointToPoint(startX, startY, endX, endY)
     });
 }
 
-function selectFormAccessoryPickerRow(rowIndex)
-{
-    const selectRowScript = `(() => uiController.selectFormAccessoryPickerRow(${rowIndex}))()`;
-    return new Promise(resolve => testRunner.runUIScript(selectRowScript, resolve));
-}
-
 function holdAtPoint(x, y)
 {
     return new Promise(resolve => {
index 44b7689..22adaeb 100644 (file)
@@ -161,4 +161,19 @@ window.UIHelper = class UIHelper {
     {
         internals.withUserGesture(callback);
     }
+
+    static selectFormAccessoryPickerRow(rowIndex)
+    {
+        const selectRowScript = `(() => uiController.selectFormAccessoryPickerRow(${rowIndex}))()`;
+        return new Promise(resolve => testRunner.runUIScript(selectRowScript, resolve));
+    }
+
+    static selectFormPopoverTitle()
+    {
+        return new Promise(resolve => {
+            testRunner.runUIScript(`(() => {
+                uiController.uiScriptComplete(uiController.selectFormPopoverTitle);
+            })()`, resolve);
+        });
+    }
 }
index cbc2197..d81e4bc 100644 (file)
@@ -1,3 +1,46 @@
+2018-04-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] Missing label when focusing a <select> with a title attribute but no associated <label>
+        https://bugs.webkit.org/show_bug.cgi?id=184352
+        <rdar://problem/39237683>
+
+        Reviewed by Andy Estes.
+
+        Currently, AssistedNodeInformation only sends the `title` of input elements to the UI process. This means that
+        any information requested in the UI process that is dependent on the `title` of the focused element is broken
+        in the case of select elements. An existing example of this is the title of the table view controller used to
+        present select menus on iPad.
+
+        To fix this, we simply send the `title` of the focused element across, as long as the focused element is an
+        HTMLElement. This ensures that there's label text when focusing unlabeled select elements with titles in extra
+        zoom mode, and also fixes a currenly broken codepath where we show the title of the select in the presented view
+        controller's title.
+
+        Test: fast/forms/ios/ipad/select-with-title.html
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView selectFormPopoverTitle]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+
+        Add new testing SPI to fetch the title of the UITableViewController presented for the currently focused select
+        element.
+
+        * UIProcess/ios/WKContentViewInteraction.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (-[WKContentView selectFormPopoverTitle]):
+        * UIProcess/ios/forms/WKFormSelectControl.h:
+        * UIProcess/ios/forms/WKFormSelectControl.mm:
+        (-[WKFormSelectControl selectFormPopoverTitle]):
+        * UIProcess/ios/forms/WKFormSelectPopover.h:
+        * UIProcess/ios/forms/WKFormSelectPopover.mm:
+        (-[WKSelectPopover initWithView:hasGroups:]):
+        (-[WKSelectPopover tableViewController]):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+
+        Always send the title across if the focused node is an HTMLElement.
+
+        (WebKit::WebPage::getAssistedNodeInformation):
+
 2018-04-11  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r230508.
index 8bb4b42..9c5d478 100644 (file)
@@ -5871,6 +5871,11 @@ static WebCore::UserInterfaceLayoutDirection toUserInterfaceLayoutDirection(UISe
     [_contentView selectFormAccessoryPickerRow:rowIndex];
 }
 
+- (NSString *)selectFormPopoverTitle
+{
+    return [_contentView selectFormPopoverTitle];
+}
+
 - (void)didStartFormControlInteraction
 {
     // For subclasses to override.
index 6d88d9e..63dd1b8 100644 (file)
@@ -381,6 +381,7 @@ typedef NS_OPTIONS(NSUInteger, _WKRectEdge) {
 - (void)keyboardAccessoryBarPrevious WK_API_AVAILABLE(ios(10.0));
 - (void)dismissFormAccessoryView WK_API_AVAILABLE(ios(10.3));
 - (void)selectFormAccessoryPickerRow:(int)rowIndex WK_API_AVAILABLE(ios(10.3));
+@property (nonatomic, readonly) NSString *selectFormPopoverTitle WK_API_AVAILABLE(ios(WK_IOS_TBA));
 
 - (void)applyAutocorrection:(NSString *)newString toString:(NSString *)oldString withCompletionHandler:(void (^)(void))completionHandler WK_API_AVAILABLE(ios(11.0));
 
index d4b59de..607af3b 100644 (file)
@@ -363,6 +363,8 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW)
 - (void)selectFormAccessoryPickerRow:(NSInteger)rowIndex;
 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem;
 
+@property (nonatomic, readonly) NSString *selectFormPopoverTitle;
+
 @end
 
 #if HAVE(LINK_PREVIEW)
index c08c3ad..80645be 100644 (file)
@@ -5439,6 +5439,14 @@ static NSArray<UIItemProvider *> *extractItemProvidersFromDropSession(id <UIDrop
         [(WKFormSelectControl *)_inputPeripheral selectRow:rowIndex inComponent:0 extendingSelection:NO];
 }
 
+- (NSString *)selectFormPopoverTitle
+{
+    if (![_inputPeripheral isKindOfClass:[WKFormSelectControl self]])
+        return nil;
+
+    return [(WKFormSelectControl *)_inputPeripheral selectFormPopoverTitle];
+}
+
 - (NSDictionary *)_contentsOfUserInterfaceItem:(NSString *)userInterfaceItem
 {
     if ([userInterfaceItem isEqualToString:@"actionSheet"])
index d230f88..f8e4ea1 100644 (file)
@@ -41,6 +41,7 @@ CGFloat adjustedFontSize(CGFloat textWidth, UIFont *, CGFloat initialFontSize, c
 
 @interface WKFormSelectControl(WKTesting)
 - (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection;
+@property (nonatomic, readonly) NSString *selectFormPopoverTitle;
 @end
 
 @protocol WKSelectTesting
index 4a534fe..23be0fb 100644 (file)
@@ -111,6 +111,14 @@ CGFloat adjustedFontSize(CGFloat textWidth, UIFont *font, CGFloat initialFontSiz
         [id<WKSelectTesting>(_control.get()) selectRow:rowIndex inComponent:componentIndex extendingSelection:extendingSelection];
 }
 
+- (NSString *)selectFormPopoverTitle
+{
+    if (![_control isKindOfClass:[WKSelectPopover class]])
+        return nil;
+
+    return [(WKSelectPopover *)_control.get() tableViewController].title;
+}
+
 @end
 
 #endif  // PLATFORM(IOS)
index 9829615..05abbf3 100644 (file)
 #import "WKFormPeripheral.h"
 #import "WKFormPopover.h"
 
+@class UITableViewController;
 @class WKContentView;
 
 @interface WKSelectPopover : WKFormRotatingAccessoryPopover<WKFormControl>
 - (instancetype)initWithView:(WKContentView *)view hasGroups:(BOOL)hasGroups;
 - (void)_userActionDismissedPopover:(id)sender;
+@property (nonatomic, readonly) UITableViewController *tableViewController;
 @end
 
 #endif // PLATFORM(IOS)
index 4dde329..57bfa40 100644 (file)
@@ -389,8 +389,7 @@ static NSString *stringWithWritingDirection(NSString *string, UITextWritingDirec
     [_tableViewController setPopover:self];
     UIViewController *popoverViewController = _tableViewController.get();
     UINavigationController *navController = nil;
-    NSString *title = view.assistedNodeInformation.title;
-    BOOL needsNavigationController = !!title.length;
+    BOOL needsNavigationController = !view.assistedNodeInformation.title.isEmpty();
     if (needsNavigationController) {
         navController = [[UINavigationController alloc] initWithRootViewController:_tableViewController.get()];
         popoverViewController = navController;
@@ -442,6 +441,11 @@ static NSString *stringWithWritingDirection(NSString *string, UITextWritingDirec
     [self accessoryDone];
 }
 
+- (UITableViewController *)tableViewController
+{
+    return _tableViewController.get();
+}
+
 @end
 
 @implementation WKSelectPopover(WKTesting)
index e06cc56..46e9838 100644 (file)
@@ -2786,6 +2786,9 @@ void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information)
         }
     }
 
+    if (is<HTMLElement>(m_assistedNode.get()))
+        information.title = downcast<HTMLElement>(*m_assistedNode).title();
+
     if (is<HTMLSelectElement>(*m_assistedNode)) {
         HTMLSelectElement& element = downcast<HTMLSelectElement>(*m_assistedNode);
         information.elementType = InputType::Select;
@@ -2866,7 +2869,6 @@ void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information)
         information.isReadOnly = element.isReadOnly();
         information.value = element.value();
         information.valueAsNumber = element.valueAsNumber();
-        information.title = element.title();
         information.autofillFieldName = WebCore::toAutofillFieldName(element.autofillData().fieldName);
     } else if (m_assistedNode->hasEditableStyle()) {
         information.elementType = InputType::ContentEditable;
index ffc1250..12a5c18 100644 (file)
@@ -1,3 +1,23 @@
+2018-04-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [Extra zoom mode] Missing label when focusing a <select> with a title attribute but no associated <label>
+        https://bugs.webkit.org/show_bug.cgi?id=184352
+        <rdar://problem/39237683>
+
+        Reviewed by Andy Estes.
+
+        Add support for UIScriptController::selectFormPopoverTitle, which returns the title of the current select
+        popover's UITableViewController (for testing purposes).
+
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::selectFormPopoverTitle const):
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::selectFormPopoverTitle const):
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::selectFormPopoverTitle const):
+
 2018-04-10  Nan Wang  <n_wang@apple.com>
 
         AX: Expose strong password fields on iOS
index b613981..b5506ca 100644 (file)
@@ -158,6 +158,11 @@ void UIScriptController::dismissFormAccessoryView()
 void UIScriptController::selectFormAccessoryPickerRow(long rowIndex)
 {
 }
+
+JSRetainPtr<JSStringRef> UIScriptController::selectFormPopoverTitle() const
+{
+    return nullptr;
+}
     
 JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
 {
index 8a8c8f6..79ec491 100644 (file)
@@ -187,6 +187,7 @@ interface UIScriptController {
 
     // <select> picker
     void selectFormAccessoryPickerRow(long rowIndex);
+    readonly attribute DOMString selectFormPopoverTitle;
 
     void keyboardAccessoryBarNext();
     void keyboardAccessoryBarPrevious();
index de1dee7..9a6b71c 100644 (file)
@@ -298,6 +298,11 @@ void UIScriptController::selectFormAccessoryPickerRow(long)
 {
 }
 
+JSRetainPtr<JSStringRef> UIScriptController::selectFormPopoverTitle() const
+{
+    return nullptr;
+}
+
 void UIScriptController::scrollToOffset(long x, long y)
 {
 }
index b82397e..e266558 100644 (file)
@@ -97,6 +97,7 @@ public:
     
     void dismissFormAccessoryView();
     void selectFormAccessoryPickerRow(long);
+    JSRetainPtr<JSStringRef> selectFormPopoverTitle() const;
     
     JSObjectRef contentsOfUserInterfaceItem(JSStringRef) const;
     void overridePreference(JSStringRef preference, JSStringRef value);
index 89b7764..0546ddf 100644 (file)
@@ -418,6 +418,12 @@ void UIScriptController::dismissFormAccessoryView()
     [webView dismissFormAccessoryView];
 }
 
+JSRetainPtr<JSStringRef> UIScriptController::selectFormPopoverTitle() const
+{
+    TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
+    return JSStringCreateWithCFString((CFStringRef)webView.selectFormPopoverTitle);
+}
+
 void UIScriptController::selectFormAccessoryPickerRow(long rowIndex)
 {
     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();