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

Changeset 249194 in webkit


Ignore:
Timestamp:
Aug 28, 2019, 3:22:56 AM (7 years ago)
Author:
Carlos Garcia Campos
Message:

Unable to enter text in https://eat.fi
https://bugs.webkit.org/show_bug.cgi?id=193046

Reviewed by Ryosuke Niwa.

Source/WebCore:

This is because the button element inside the label is receiving the click event, which causes the form to be
submitted. According to the spec we should do nothing in this case, because button element is considered to be
interactive content.

"The activation behavior of a label element for events targeted at interactive content descendants of a label
element, and any descendants of those interactive content descendants, must be to do nothing."
https://html.spec.whatwg.org/#the-label-element

This patch adds HTMLElement::isInteractiveContent() according to the HTML spec:

"Interactive content is content that is specifically intended for user interaction.
a (if the href attribute is present), audio (if the controls attribute is present), button, details, embed,
iframe, img (if the usemap attribute is present), input (if the type attribute is not in the Hidden state),
label, object (if the usemap attribute is present), select, textarea, video (if the controls attribute is
present)"
https://html.spec.whatwg.org/#interactive-content-2

That's used in HTMLLabelElement::defaultEventHandler() using the helper method
isEventTargetedAtInteractiveDescendants() to decide whether to simulate a click event or do nothing.

  • html/HTMLAnchorElement.cpp:

(WebCore::HTMLAnchorElement::isInteractiveContent const):

  • html/HTMLAnchorElement.h:
  • html/HTMLButtonElement.h:
  • html/HTMLDetailsElement.h:
  • html/HTMLElement.h:

(WebCore::HTMLElement::isInteractiveContent const):

  • html/HTMLEmbedElement.h:
  • html/HTMLIFrameElement.h:
  • html/HTMLImageElement.cpp:

(WebCore::HTMLImageElement::isInteractiveContent const):

  • html/HTMLImageElement.h:
  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::isInteractiveContent const):

  • html/HTMLInputElement.h:
  • html/HTMLLabelElement.cpp:

(WebCore::HTMLLabelElement::isEventTargetedAtInteractiveDescendants const):
(WebCore::HTMLLabelElement::defaultEventHandler):

  • html/HTMLLabelElement.h:
  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::isInteractiveContent const):

  • html/HTMLMediaElement.h:
  • html/HTMLObjectElement.cpp:

(WebCore::HTMLObjectElement::isInteractiveContent const):

  • html/HTMLObjectElement.h:
  • html/HTMLSelectElement.h:
  • html/HTMLTextAreaElement.h:
  • html/HiddenInputType.h:
  • html/InputType.cpp:

(WebCore::InputType::isInteractiveContent const):

  • html/InputType.h:

LayoutTests:

Add new test imported for blink.

  • imported/blink/fast/forms/label/label-contains-other-interactive-content-expected.txt: Added.
  • imported/blink/fast/forms/label/label-contains-other-interactive-content.html: Added.
  • platform/ios-wk2/TestExpectations: Skip the new test because it requires eventSender.mouseDown/Up/MoveTo()
Location:
trunk
Files:
2 added
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r249191 r249194  
     12019-08-28  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        Unable to enter text in https://eat.fi
     4        https://bugs.webkit.org/show_bug.cgi?id=193046
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Add new test imported for blink.
     9
     10        * imported/blink/fast/forms/label/label-contains-other-interactive-content-expected.txt: Added.
     11        * imported/blink/fast/forms/label/label-contains-other-interactive-content.html: Added.
     12        * platform/ios-wk2/TestExpectations: Skip the new test because it requires eventSender.mouseDown/Up/MoveTo()
     13
    1142019-08-28  Said Abou-Hallawa  <sabouhallawa@apple.com>
    215
  • trunk/LayoutTests/platform/ios-wk2/TestExpectations

    r249108 r249194  
    10171017fast/loader/location-hash-user-gesture.html [ Skip ]
    10181018imported/blink/editing/selection/selectstart-event-crash.html [ Skip ]
     1019imported/blink/fast/forms/label/label-contains-other-interactive-content.html [ Skip ]
    10191020fast/dom/Window/post-message-user-action.html [ Skip ]
    10201021fast/images/image-usemap-parsing.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r249192 r249194  
     12019-08-28  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        Unable to enter text in https://eat.fi
     4        https://bugs.webkit.org/show_bug.cgi?id=193046
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        This is because the button element inside the label is receiving the click event, which causes the form to be
     9        submitted. According to the spec we should do nothing in this case, because button element is considered to be
     10        interactive content.
     11
     12        "The activation behavior of a label element for events targeted at interactive content descendants of a label
     13        element, and any descendants of those interactive content descendants, must be to do nothing."
     14        https://html.spec.whatwg.org/#the-label-element
     15
     16        This patch adds HTMLElement::isInteractiveContent() according to the HTML spec:
     17
     18        "Interactive content is content that is specifically intended for user interaction.
     19        a (if the href attribute is present), audio (if the controls attribute is present), button, details, embed,
     20        iframe, img (if the usemap attribute is present), input (if the type attribute is not in the Hidden state),
     21        label, object (if the usemap attribute is present), select, textarea, video (if the controls attribute is
     22        present)"
     23        https://html.spec.whatwg.org/#interactive-content-2
     24
     25        That's used in HTMLLabelElement::defaultEventHandler() using the helper method
     26        isEventTargetedAtInteractiveDescendants() to decide whether to simulate a click event or do nothing.
     27
     28        * html/HTMLAnchorElement.cpp:
     29        (WebCore::HTMLAnchorElement::isInteractiveContent const):
     30        * html/HTMLAnchorElement.h:
     31        * html/HTMLButtonElement.h:
     32        * html/HTMLDetailsElement.h:
     33        * html/HTMLElement.h:
     34        (WebCore::HTMLElement::isInteractiveContent const):
     35        * html/HTMLEmbedElement.h:
     36        * html/HTMLIFrameElement.h:
     37        * html/HTMLImageElement.cpp:
     38        (WebCore::HTMLImageElement::isInteractiveContent const):
     39        * html/HTMLImageElement.h:
     40        * html/HTMLInputElement.cpp:
     41        (WebCore::HTMLInputElement::isInteractiveContent const):
     42        * html/HTMLInputElement.h:
     43        * html/HTMLLabelElement.cpp:
     44        (WebCore::HTMLLabelElement::isEventTargetedAtInteractiveDescendants const):
     45        (WebCore::HTMLLabelElement::defaultEventHandler):
     46        * html/HTMLLabelElement.h:
     47        * html/HTMLMediaElement.cpp:
     48        (WebCore::HTMLMediaElement::isInteractiveContent const):
     49        * html/HTMLMediaElement.h:
     50        * html/HTMLObjectElement.cpp:
     51        (WebCore::HTMLObjectElement::isInteractiveContent const):
     52        * html/HTMLObjectElement.h:
     53        * html/HTMLSelectElement.h:
     54        * html/HTMLTextAreaElement.h:
     55        * html/HiddenInputType.h:
     56        * html/InputType.cpp:
     57        (WebCore::InputType::isInteractiveContent const):
     58        * html/InputType.h:
     59
    1602019-08-28  Claudio Saavedra  <csaavedra@igalia.com>
    261
  • trunk/Source/WebCore/html/HTMLAnchorElement.cpp

    r248846 r249194  
    104104}
    105105
     106bool HTMLAnchorElement::isInteractiveContent() const
     107{
     108    return isLink();
     109}
     110
    106111static bool hasNonEmptyBox(RenderBoxModelObject* renderer)
    107112{
  • trunk/Source/WebCore/html/HTMLAnchorElement.h

    r248784 r249194  
    9191    int defaultTabIndex() const final;
    9292    bool draggable() const final;
     93    bool isInteractiveContent() const final;
    9394
    9495    String effectiveTarget() const;
  • trunk/Source/WebCore/html/HTMLAppletElement.h

    r246490 r249194  
    4545
    4646    bool canEmbedJava() const;
     47
     48    bool isInteractiveContent() const final { return true; }
    4749};
    4850
  • trunk/Source/WebCore/html/HTMLButtonElement.h

    r248914 r249194  
    6262    bool isEnumeratable() const final { return true; }
    6363    bool supportLabels() const final { return true; }
     64    bool isInteractiveContent() const final { return true; }
    6465
    6566    bool isSuccessfulSubmitButton() const final;
  • trunk/Source/WebCore/html/HTMLDetailsElement.h

    r246490 r249194  
    5252    void didAddUserAgentShadowRoot(ShadowRoot&) final;
    5353    bool hasCustomFocusLogic() const final { return true; }
     54    bool isInteractiveContent() const final { return true; }
    5455
    5556    bool m_isOpen { false };
  • trunk/Source/WebCore/html/HTMLElement.h

    r248784 r249194  
    9191    virtual FormAssociatedElement* asFormAssociatedElement();
    9292
     93    virtual bool isInteractiveContent() const { return false; }
     94
    9395    bool hasTagName(const HTMLQualifiedName& name) const { return hasLocalName(name.localName()); }
    9496
  • trunk/Source/WebCore/html/HTMLEmbedElement.h

    r246490 r249194  
    4444    const AtomString& imageSourceURL() const final;
    4545
     46    bool isInteractiveContent() const final { return true; }
     47
    4648    RenderWidget* renderWidgetLoadingPlugin() const final;
    4749
  • trunk/Source/WebCore/html/HTMLIFrameElement.h

    r247529 r249194  
    5454    void collectStyleForPresentationAttribute(const QualifiedName&, const AtomString&, MutableStyleProperties&) final;
    5555
     56    bool isInteractiveContent() const final { return true; }
     57
    5658    bool rendererIsNeeded(const RenderStyle&) final;
    5759    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
  • trunk/Source/WebCore/html/HTMLImageElement.cpp

    r246490 r249194  
    304304}
    305305
     306bool HTMLImageElement::isInteractiveContent() const
     307{
     308    return hasAttributeWithoutSynchronization(usemapAttr);
     309}
     310
    306311void HTMLImageElement::didAttachRenderers()
    307312{
  • trunk/Source/WebCore/html/HTMLImageElement.h

    r246490 r249194  
    157157    const HTMLImageElement& asHTMLElement() const final { return *this; }
    158158
     159    bool isInteractiveContent() const final;
     160
    159161    void selectImageSource();
    160162
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r248914 r249194  
    451451}
    452452
     453bool HTMLInputElement::isInteractiveContent() const
     454{
     455    return m_inputType->isInteractiveContent();
     456}
     457
    453458bool HTMLInputElement::isTextFormControlFocusable() const
    454459{
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r248914 r249194  
    376376    bool shouldUseInputMethod() final;
    377377
     378    bool isInteractiveContent() const final;
     379
    378380    bool isInnerTextElementEditable() const final { return !hasAutoFillStrongPasswordButton() && HTMLTextFormControlElement::isInnerTextElementEditable(); }
    379381
  • trunk/Source/WebCore/html/HTMLLabelElement.cpp

    r246490 r249194  
    112112}
    113113
     114bool HTMLLabelElement::isEventTargetedAtInteractiveDescendants(Event& event) const
     115{
     116    if (!is<Node>(event.target()))
     117        return false;
     118
     119    auto& node = downcast<Node>(*event.target());
     120    if (!containsIncludingShadowDOM(&node))
     121        return false;
     122
     123    for (const auto* it = &node; it && it != this; it = it->parentElementInComposedTree()) {
     124        if (is<HTMLElement>(it) && downcast<HTMLElement>(*it).isInteractiveContent())
     125            return true;
     126    }
     127
     128    return false;
     129}
    114130void HTMLLabelElement::defaultEventHandler(Event& event)
    115131{
     
    122138        // event, then there's no need for us to do anything.
    123139        if (!control || (is<Node>(event.target()) && control->containsIncludingShadowDOM(&downcast<Node>(*event.target())))) {
     140            HTMLElement::defaultEventHandler(event);
     141            return;
     142        }
     143
     144        // The activation behavior of a label element for events targeted at interactive
     145        // content descendants of a label element, and any descendants of those interactive
     146        // content descendants, must be to do nothing.
     147        // https://html.spec.whatwg.org/#the-label-element
     148        if (isEventTargetedAtInteractiveDescendants(event)) {
    124149            HTMLElement::defaultEventHandler(event);
    125150            return;
  • trunk/Source/WebCore/html/HTMLLabelElement.h

    r229694 r249194  
    4141    HTMLLabelElement(const QualifiedName&, Document&);
    4242
     43    bool isEventTargetedAtInteractiveDescendants(Event&) const;
     44
    4345    void accessKeyAction(bool sendMouseEvents) final;
    4446
     
    5153
    5254    void focus(bool restorePreviousSelection, FocusDirection) final;
     55
     56    bool isInteractiveContent() const final { return true; }
    5357};
    5458
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r249175 r249194  
    804804}
    805805
     806bool HTMLMediaElement::isInteractiveContent() const
     807{
     808    return controls();
     809}
     810
    806811void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomString& value)
    807812{
  • trunk/Source/WebCore/html/HTMLMediaElement.h

    r248762 r249194  
    627627    void removedFromAncestor(RemovalType, ContainerNode&) override;
    628628    void didRecalcStyle(Style::Change) override;
     629    bool isInteractiveContent() const override;
    629630
    630631    void willBecomeFullscreenElement() override;
  • trunk/Source/WebCore/html/HTMLObjectElement.cpp

    r247529 r249194  
    326326}
    327327
     328bool HTMLObjectElement::isInteractiveContent() const
     329{
     330    return hasAttributeWithoutSynchronization(usemapAttr);
     331}
     332
    328333const AtomString& HTMLObjectElement::imageSourceURL() const
    329334{
  • trunk/Source/WebCore/html/HTMLObjectElement.h

    r246490 r249194  
    9696    const HTMLObjectElement& asHTMLElement() const final { return *this; }
    9797
     98    bool isInteractiveContent() const final;
     99
    98100    bool isFormControlElement() const final { return false; }
    99101
  • trunk/Source/WebCore/html/HTMLSelectElement.h

    r248914 r249194  
    124124    bool isEnumeratable() const final { return true; }
    125125    bool supportLabels() const final { return true; }
     126
     127    bool isInteractiveContent() const final { return true; }
    126128
    127129    FormControlState saveFormControlState() const final;
  • trunk/Source/WebCore/html/HTMLTextAreaElement.h

    r248914 r249194  
    9999    bool supportLabels() const final { return true; }
    100100
     101    bool isInteractiveContent() const final { return true; }
     102
    101103    const AtomString& formControlType() const final;
    102104
  • trunk/Source/WebCore/html/HiddenInputType.h

    r246490 r249194  
    5050    bool isHiddenType() const override;
    5151    bool supportLabels() const override { return false; }
     52    bool isInteractiveContent() const final { return false; }
    5253    bool shouldRespectHeightAndWidthAttributes() override;
    5354    void setValue(const String&, bool, TextFieldEventBehavior) override;
  • trunk/Source/WebCore/html/InputType.cpp

    r246490 r249194  
    798798}
    799799
     800bool InputType::isInteractiveContent() const
     801{
     802    return true;
     803}
     804
    800805bool InputType::supportLabels() const
    801806{
  • trunk/Source/WebCore/html/InputType.h

    r246490 r249194  
    102102    virtual bool isHiddenType() const;
    103103    virtual bool isImageButton() const;
     104    virtual bool isInteractiveContent() const;
    104105    virtual bool supportLabels() const;
    105106    virtual bool isMonthField() const;
Note: See TracChangeset for help on using the changeset viewer.