⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 268866 in webkit


Ignore:
Timestamp:
Oct 22, 2020, 8:55:54 AM (6 years ago)
Author:
Aditya Keerthi
Message:

[iOS] Prevent presentation of input peripherals when focusing form controls with a validation message
https://bugs.webkit.org/show_bug.cgi?id=218004
<rdar://problem/70507678>

Reviewed by Wenson Hsieh.

Source/WebCore:

Added isFocusingWithValidationMessage() to HTMLFormControlElement so
that the state can be encoded in FocusedElementInformation and sent to
the UIProcess.

See WebKit Changelog for more information.

Test: fast/forms/ios/input-peripherals-with-validation-message.html

  • html/HTMLFormControlElement.cpp:

(WebCore::HTMLFormControlElement::isFocusingWithValidationMessage const):
(WebCore::HTMLFormControlElement::focusAndShowValidationMessage):

  • html/HTMLFormControlElement.h:

Source/WebKit:

Interactive form validation can result in the presentation of a
validation message bubble near the first form control that has invalid
data. Prior to displaying the message, the invalid control is focused.
On iOS, this also has the effect of also presenting a virtual keyboard
or another custom input peripheral, such as a context menu for date
inputs.

Attempting to present both the validation message and custom input
peripheral can leave the view in an inconsistent state. For example,
<select> popovers have a strange flashing behavior when presented
alongside a validation message, and context menus can fail to present
entirely.

In order to address these issues, we should never attempt to present
both a validation message and an input peripheral. Instead, we can
prevent the presentation of input peripherals when the focused control
is presenting a validation message. This behavior matches macOS. Note
that we still present the keyboard for controls that have a keyboard
view, since the keyboard area does overlap the area where a validation
message is presented.

  • Shared/FocusedElementInformation.cpp:

(WebKit::FocusedElementInformation::encode const):
(WebKit::FocusedElementInformation::decode):

  • Shared/FocusedElementInformation.h:

Added isFocusingWithValidationMessage to the struct, so that the UIProcess
knows that the element gained focus due to the presentation of a
validation message.

  • UIProcess/ios/WKContentViewInteraction.mm:

(-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):

Prevent an input view from being shown if the control does not present
a keyboard and was focused with a validation message.

(-[WKContentView _elementDidBlur]):

  • WebProcess/WebPage/ios/WebPageIOS.mm:

(WebKit::WebPage::getFocusedElementInformation):

LayoutTests:

Added a test which verifies that focusing on a date input as a result
of presenting a validation message, successfully presents the message,
and does not present a context menu. The test also ensures that controls
that present a keyboard, such as text inputs, present both the message
and the keyboard.

  • fast/forms/ios/input-peripherals-with-validation-message-expected.txt: Added.
  • fast/forms/ios/input-peripherals-with-validation-message.html: Added.
  • resources/ui-helper.js:

(window.UIHelper.isShowingPopover):

Location:
trunk
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r268865 r268866  
     12020-10-22  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [iOS] Prevent presentation of input peripherals when focusing form controls with a validation message
     4        https://bugs.webkit.org/show_bug.cgi?id=218004
     5        <rdar://problem/70507678>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Added a test which verifies that focusing on a date input as a result
     10        of presenting a validation message, successfully presents the message,
     11        and does not present a context menu. The test also ensures that controls
     12        that present a keyboard, such as text inputs, present both the message
     13        and the keyboard.
     14
     15        * fast/forms/ios/input-peripherals-with-validation-message-expected.txt: Added.
     16        * fast/forms/ios/input-peripherals-with-validation-message.html: Added.
     17        * resources/ui-helper.js:
     18        (window.UIHelper.isShowingPopover):
     19
    1202020-10-22  Peng Liu  <peng.liu6@apple.com>
    221
  • trunk/LayoutTests/resources/ui-helper.js

    r268847 r268866  
    578578        return new Promise(resolve => {
    579579            testRunner.runUIScript("uiController.isShowingKeyboard", result => resolve(result === "true"));
     580        });
     581    }
     582
     583    static isShowingPopover()
     584    {
     585        return new Promise(resolve => {
     586            testRunner.runUIScript("uiController.isShowingPopover", result => resolve(result === "true"));
    580587        });
    581588    }
  • trunk/Source/WebCore/ChangeLog

    r268865 r268866  
     12020-10-22  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [iOS] Prevent presentation of input peripherals when focusing form controls with a validation message
     4        https://bugs.webkit.org/show_bug.cgi?id=218004
     5        <rdar://problem/70507678>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Added isFocusingWithValidationMessage() to HTMLFormControlElement so
     10        that the state can be encoded in FocusedElementInformation and sent to
     11        the UIProcess.
     12
     13        See WebKit Changelog for more information.
     14
     15        Test: fast/forms/ios/input-peripherals-with-validation-message.html
     16
     17        * html/HTMLFormControlElement.cpp:
     18        (WebCore::HTMLFormControlElement::isFocusingWithValidationMessage const):
     19        (WebCore::HTMLFormControlElement::focusAndShowValidationMessage):
     20        * html/HTMLFormControlElement.h:
     21
    1222020-10-22  Peng Liu  <peng.liu6@apple.com>
    223
  • trunk/Source/WebCore/html/HTMLFormControlElement.cpp

    r264332 r268866  
    5050#include <wtf/IsoMallocInlines.h>
    5151#include <wtf/Ref.h>
     52#include <wtf/SetForScope.h>
    5253#include <wtf/Vector.h>
    5354
     
    497498}
    498499
     500bool HTMLFormControlElement::isFocusingWithValidationMessage() const
     501{
     502    return m_isFocusingWithValidationMessage;
     503}
     504
    499505bool HTMLFormControlElement::isShowingValidationMessage() const
    500506{
     
    530536void HTMLFormControlElement::focusAndShowValidationMessage()
    531537{
     538    SetForScope<bool> isFocusingWithValidationMessageScope(m_isFocusingWithValidationMessage, true);
     539
    532540    // Calling focus() will scroll the element into view.
    533541    focus();
  • trunk/Source/WebCore/html/HTMLFormControlElement.h

    r257188 r268866  
    107107    void focusAndShowValidationMessage();
    108108    bool isShowingValidationMessage() const;
     109    WEBCORE_EXPORT bool isFocusingWithValidationMessage() const;
    109110    // This must be called when a validation constraint or control value is changed.
    110111    void updateValidity();
     
    181182
    182183    std::unique_ptr<ValidationMessage> m_validationMessage;
     184    bool m_isFocusingWithValidationMessage { false };
     185
    183186    unsigned m_disabled : 1;
    184187    unsigned m_isReadOnly : 1;
  • trunk/Source/WebKit/ChangeLog

    r268858 r268866  
     12020-10-22  Aditya Keerthi  <akeerthi@apple.com>
     2
     3        [iOS] Prevent presentation of input peripherals when focusing form controls with a validation message
     4        https://bugs.webkit.org/show_bug.cgi?id=218004
     5        <rdar://problem/70507678>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Interactive form validation can result in the presentation of a
     10        validation message bubble near the first form control that has invalid
     11        data. Prior to displaying the message, the invalid control is focused.
     12        On iOS, this also has the effect of also presenting a virtual keyboard
     13        or another custom input peripheral, such as a context menu for date
     14        inputs.
     15
     16        Attempting to present both the validation message and custom input
     17        peripheral can leave the view in an inconsistent state. For example,
     18        <select> popovers have a strange flashing behavior when presented
     19        alongside a validation message, and context menus can fail to present
     20        entirely.
     21
     22        In order to address these issues, we should never attempt to present
     23        both a validation message and an input peripheral. Instead, we can
     24        prevent the presentation of input peripherals when the focused control
     25        is presenting a validation message. This behavior matches macOS. Note
     26        that we still present the keyboard for controls that have a keyboard
     27        view, since the keyboard area does overlap the area where a validation
     28        message is presented.
     29
     30        * Shared/FocusedElementInformation.cpp:
     31        (WebKit::FocusedElementInformation::encode const):
     32        (WebKit::FocusedElementInformation::decode):
     33        * Shared/FocusedElementInformation.h:
     34
     35        Added isFocusingWithValidationMessage to the struct, so that the UIProcess
     36        knows that the element gained focus due to the presentation of a
     37        validation message.
     38
     39        * UIProcess/ios/WKContentViewInteraction.mm:
     40        (-[WKContentView _elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:]):
     41
     42        Prevent an input view from being shown if the control does not present
     43        a keyboard and was focused with a validation message.
     44
     45        (-[WKContentView _elementDidBlur]):
     46        * WebProcess/WebPage/ios/WebPageIOS.mm:
     47        (WebKit::WebPage::getFocusedElementInformation):
     48
    1492020-10-22  Carlos Garcia Campos  <cgarcia@igalia.com>
    250
  • trunk/Source/WebKit/Shared/FocusedElementInformation.cpp

    r266342 r268866  
    111111    encoder << shouldAvoidScrollingWhenFocusedContentIsVisible;
    112112    encoder << shouldUseLegacySelectPopoverDismissalBehaviorInDataActivation;
     113    encoder << isFocusingWithValidationMessage;
    113114}
    114115
     
    247248        return false;
    248249
     250    if (!decoder.decode(result.isFocusingWithValidationMessage))
     251        return false;
     252
    249253    return true;
    250254}
  • trunk/Source/WebKit/Shared/FocusedElementInformation.h

    r266342 r268866  
    145145    bool shouldAvoidScrollingWhenFocusedContentIsVisible { false };
    146146    bool shouldUseLegacySelectPopoverDismissalBehaviorInDataActivation { false };
     147    bool isFocusingWithValidationMessage { false };
    147148
    148149    FocusedElementIdentifier focusedElementIdentifier { 0 };
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r268182 r268866  
    59415941    }();
    59425942
     5943    // Do not present input peripherals if a validation message is being displayed.
     5944    if (information.isFocusingWithValidationMessage && !_isFocusingElementWithKeyboard)
     5945        shouldShowInputView = NO;
     5946
    59435947    if (blurPreviousNode) {
    59445948        // Defer view updates until the end of this function to avoid a noticeable flash when switching focus
     
    60736077    _focusedElementInformation.shouldAvoidScrollingWhenFocusedContentIsVisible = false;
    60746078    _focusedElementInformation.shouldUseLegacySelectPopoverDismissalBehaviorInDataActivation = false;
     6079    _focusedElementInformation.isFocusingWithValidationMessage = false;
    60756080    _inputPeripheral = nil;
    60766081    _focusRequiresStrongPasswordAssistance = NO;
  • trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm

    r268635 r268866  
    30533053        information.isSpellCheckingEnabled = downcast<HTMLElement>(*focusedElement).spellcheck();
    30543054
     3055    if (is<HTMLFormControlElement>(focusedElement))
     3056        information.isFocusingWithValidationMessage = downcast<HTMLFormControlElement>(*focusedElement).isFocusingWithValidationMessage();
     3057
    30553058    information.minimumScaleFactor = minimumPageScaleFactor();
    30563059    information.maximumScaleFactor = maximumPageScaleFactor();
Note: See TracChangeset for help on using the changeset viewer.