Changeset 246096 in webkit


Ignore:
Timestamp:
Jun 4, 2019 9:15:21 PM (5 years ago)
Author:
Alan Bujtas
Message:

[ContentChangeObserver] Gmail text editing controls require two taps
https://bugs.webkit.org/show_bug.cgi?id=198541
<rdar://problem/51375055>

Reviewed by Simon Fraser.

Source/WebCore:

When the animation completes we should also check if the newly visible content is also clickable and report it accordingly.
When the animated content is not clickable, we need to proceed with click instead of stopping at hover.

Test: fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-no-clickable.html

  • page/ios/ContentChangeObserver.cpp:

(WebCore::isConsideredClickable):
(WebCore::ContentChangeObserver::didFinishTransition):
(WebCore::ContentChangeObserver::adjustObservedState):
(WebCore::ContentChangeObserver::StyleChangeScope::~StyleChangeScope):
(WebCore::ContentChangeObserver::StyleChangeScope::isConsideredClickable const): Deleted. -> Turn it into a static function so that didFinishTransition could call it as well.

  • page/ios/ContentChangeObserver.h:

LayoutTests:

  • fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-no-clickable.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r246089 r246096  
     12019-06-04  Zalan Bujtas  <zalan@apple.com>
     2
     3        [ContentChangeObserver] Gmail text editing controls require two taps
     4        https://bugs.webkit.org/show_bug.cgi?id=198541
     5        <rdar://problem/51375055>
     6
     7        Reviewed by Simon Fraser.
     8
     9        * fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-no-clickable.html: Added.
     10
    1112019-06-04  Youenn Fablet  <youenn@apple.com>
    212
  • trunk/Source/WebCore/ChangeLog

    r246095 r246096  
     12019-06-04  Zalan Bujtas  <zalan@apple.com>
     2
     3        [ContentChangeObserver] Gmail text editing controls require two taps
     4        https://bugs.webkit.org/show_bug.cgi?id=198541
     5        <rdar://problem/51375055>
     6
     7        Reviewed by Simon Fraser.
     8
     9        When the animation completes we should also check if the newly visible content is also clickable and report it accordingly.
     10        When the animated content is not clickable, we need to proceed with click instead of stopping at hover.
     11
     12        Test: fast/events/touch/ios/content-observation/100ms-delay-10ms-transition-on-mousemove-no-clickable.html
     13
     14        * page/ios/ContentChangeObserver.cpp:
     15        (WebCore::isConsideredClickable):
     16        (WebCore::ContentChangeObserver::didFinishTransition):
     17        (WebCore::ContentChangeObserver::adjustObservedState):
     18        (WebCore::ContentChangeObserver::StyleChangeScope::~StyleChangeScope):
     19        (WebCore::ContentChangeObserver::StyleChangeScope::isConsideredClickable const): Deleted. -> Turn it into a static function so that didFinishTransition could call it as well.
     20        * page/ios/ContentChangeObserver.h:
     21
    1222019-06-04  Michael Catanzaro  <mcatanzaro@igalia.com>
    223
  • trunk/Source/WebCore/page/ios/ContentChangeObserver.cpp

    r243760 r246096  
    8484}
    8585
     86enum class ElementHadRenderer { No, Yes };
     87static bool isConsideredClickable(const Element& newlyVisibleElement, ElementHadRenderer hadRenderer)
     88{
     89    auto& element = const_cast<Element&>(newlyVisibleElement);
     90    if (element.isInUserAgentShadowTree())
     91        return false;
     92
     93    if (is<HTMLIFrameElement>(element))
     94        return true;
     95
     96    if (is<HTMLImageElement>(element)) {
     97        // This is required to avoid HTMLImageElement's touch callout override logic. See rdar://problem/48937767.
     98        return element.Element::willRespondToMouseClickEvents();
     99    }
     100
     101    auto willRespondToMouseClickEvents = element.willRespondToMouseClickEvents();
     102    if (hadRenderer == ElementHadRenderer::No || willRespondToMouseClickEvents)
     103        return willRespondToMouseClickEvents;
     104    // In case when the visible content already had renderers it's not sufficient to check the "newly visible" element only since it might just be the container for the clickable content. 
     105    for (auto& descendant : descendantsOfType<RenderElement>(*element.renderer())) {
     106        if (!descendant.element())
     107            continue;
     108        if (descendant.element()->willRespondToMouseClickEvents())
     109            return true;
     110    }
     111    return false;
     112}
    86113ContentChangeObserver::ContentChangeObserver(Document& document)
    87114    : m_document(document)
     
    160187    LOG_WITH_STREAM(ContentObservation, stream << "didFinishTransition: transition finished (" << &element << ").");
    161188
    162     adjustObservedState(isConsideredHidden(element) ? Event::EndedTransition : Event::CompletedTransition);
     189    if (isConsideredHidden(element)) {
     190        adjustObservedState(Event::EndedTransitionButFinalStyleIsNotDefiniteYet);
     191        return;
     192    }
     193    adjustObservedState(isConsideredClickable(element, ElementHadRenderer::Yes) ? Event::CompletedTransitionWithClickableContent : Event::CompletedTransitionWithoutClickableContent);
    163194}
    164195
     
    473504            adjustStateAndNotifyContentChangeIfNeeded();
    474505        break;
    475     case Event::EndedTransition:
     506    case Event::EndedTransitionButFinalStyleIsNotDefiniteYet:
    476507        // onAnimationEnd can be called while in the middle of resolving the document (synchronously) or
    477508        // asynchronously right before the style update is issued. It also means we don't know whether this animation ends up producing visible content yet.
     
    482513            setShouldObserveNextStyleRecalc(true);
    483514        break;
    484     case Event::CompletedTransition:
     515    case Event::CompletedTransitionWithClickableContent:
    485516        // Set visibility flag on and report visible change synchronously or asynchronously depending whether we are in the middle of style recalc.
    486517        contentVisibilityDidChange();
     518        FALLTHROUGH;
     519    case Event::CompletedTransitionWithoutClickableContent:
    487520        if (m_document.inStyleRecalc())
    488521            m_isInObservedStyleRecalc = true;
     
    521554    };
    522555
    523     if (changedFromHiddenToVisible() && isConsideredClickable())
     556    if (changedFromHiddenToVisible() && isConsideredClickable(m_element, m_hadRenderer ? ElementHadRenderer::Yes : ElementHadRenderer::No))
    524557        m_contentChangeObserver.contentVisibilityDidChange();
    525 }
    526 
    527 bool ContentChangeObserver::StyleChangeScope::isConsideredClickable() const
    528 {
    529     if (m_element.isInUserAgentShadowTree())
    530         return false;
    531 
    532     auto& element = const_cast<Element&>(m_element);
    533     if (is<HTMLIFrameElement>(element))
    534         return true;
    535 
    536     if (is<HTMLImageElement>(element)) {
    537         // This is required to avoid HTMLImageElement's touch callout override logic. See rdar://problem/48937767.
    538         return element.Element::willRespondToMouseClickEvents();
    539     }
    540 
    541     auto willRespondToMouseClickEvents = element.willRespondToMouseClickEvents();
    542     if (!m_hadRenderer || willRespondToMouseClickEvents)
    543         return willRespondToMouseClickEvents;
    544     // In case when the visible content already had renderers it's not sufficient to check the "newly visible" element only since it might just be the container for the clickable content. 
    545     ASSERT(m_element.renderer());
    546     for (auto& descendant : descendantsOfType<RenderElement>(*element.renderer())) {
    547         if (!descendant.element())
    548             continue;
    549         if (descendant.element()->willRespondToMouseClickEvents())
    550             return true;
    551     }
    552     return false;
    553558}
    554559
  • trunk/Source/WebCore/page/ios/ContentChangeObserver.h

    r244588 r246096  
    7272
    7373    private:
    74         bool isConsideredClickable() const;
    75 
    7674        ContentChangeObserver& m_contentChangeObserver;
    7775        const Element& m_element;
     
    190188        EndedStyleRecalc,
    191189        AddedTransition,
    192         EndedTransition,
    193         CompletedTransition,
     190        EndedTransitionButFinalStyleIsNotDefiniteYet,
     191        CompletedTransitionWithClickableContent,
     192        CompletedTransitionWithoutClickableContent,
    194193        CanceledTransition,
    195194        StartedFixedObservationTimeWindow,
Note: See TracChangeset for help on using the changeset viewer.