Changeset 215404 in webkit


Ignore:
Timestamp:
Apr 16, 2017 5:56:47 PM (7 years ago)
Author:
Chris Dumez
Message:

CMD+R / CMD+Q is considered as user interaction and beforeunload alert is shown
https://bugs.webkit.org/show_bug.cgi?id=169995
<rdar://problem/23798897>

Reviewed by Sam Weinig.

Source/WebCore:

Any key event was considered as user interaction with the page, which meant that they
would allow beforeunload alerts to be shown even when they do not represent actual
user interaction (e.g CMD+R / CMD+Q / CMD+T keyboard shortcuts).

To address the issue, we now only treat as user interaction with the page key events
that are actually handled by the page (i.e. handled by JS, typed into a field, ...).

Tests: fast/events/beforeunload-alert-handled-keydown.html

fast/events/beforeunload-alert-unhandled-keydown.html

  • dom/Document.h:

(WebCore::Document::setUserDidInteractWithPage):
(WebCore::Document::userDidInteractWithPage):

  • dom/UserGestureIndicator.cpp:

(WebCore::UserGestureIndicator::UserGestureIndicator):

  • loader/FrameLoader.cpp:

(WebCore::shouldAskForNavigationConfirmation):

  • page/EventHandler.cpp:

(WebCore::EventHandler::keyEvent):
(WebCore::EventHandler::internalKeyEvent):

  • page/EventHandler.h:

LayoutTests:

Add layout test coverage.

  • fast/events/beforeunload-alert-handled-keydown-expected.txt: Added.
  • fast/events/beforeunload-alert-handled-keydown.html: Added.
  • fast/events/beforeunload-alert-unhandled-keydown-expected.txt: Added.
  • fast/events/beforeunload-alert-unhandled-keydown.html: Added.
Location:
trunk
Files:
4 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r215400 r215404  
     12017-04-16  Chris Dumez  <cdumez@apple.com>
     2
     3        CMD+R / CMD+Q is considered as user interaction and beforeunload alert is shown
     4        https://bugs.webkit.org/show_bug.cgi?id=169995
     5        <rdar://problem/23798897>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Add layout test coverage.
     10
     11        * fast/events/beforeunload-alert-handled-keydown-expected.txt: Added.
     12        * fast/events/beforeunload-alert-handled-keydown.html: Added.
     13        * fast/events/beforeunload-alert-unhandled-keydown-expected.txt: Added.
     14        * fast/events/beforeunload-alert-unhandled-keydown.html: Added.
     15
    1162017-04-16  Joseph Pecoraro  <pecoraro@apple.com>
    217
  • trunk/LayoutTests/platform/ios/TestExpectations

    r215376 r215404  
    366366# This test relies on EventSender.keydown(), which is not supported on iOS
    367367webkit.org/b/155233 fast/events/max-tabindex-focus.html [ Skip ]
     368fast/events/beforeunload-alert-handled-keydown.html [ Skip ]
     369fast/events/beforeunload-alert-unhandled-keydown.html [ Skip ]
    368370fast/events/beforeunload-alert-user-interaction.html [ Skip ]
    369371fast/forms/validation-bubble-escape-key-dismiss.html [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r215403 r215404  
     12017-04-16  Chris Dumez  <cdumez@apple.com>
     2
     3        CMD+R / CMD+Q is considered as user interaction and beforeunload alert is shown
     4        https://bugs.webkit.org/show_bug.cgi?id=169995
     5        <rdar://problem/23798897>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Any key event was considered as user interaction with the page, which meant that they
     10        would allow beforeunload alerts to be shown even when they do not represent actual
     11        user interaction (e.g CMD+R / CMD+Q / CMD+T keyboard shortcuts).
     12
     13        To address the issue, we now only treat as user interaction with the page key events
     14        that are actually handled by the page (i.e. handled by JS, typed into a field, ...).
     15
     16        Tests: fast/events/beforeunload-alert-handled-keydown.html
     17               fast/events/beforeunload-alert-unhandled-keydown.html
     18
     19        * dom/Document.h:
     20        (WebCore::Document::setUserDidInteractWithPage):
     21        (WebCore::Document::userDidInteractWithPage):
     22        * dom/UserGestureIndicator.cpp:
     23        (WebCore::UserGestureIndicator::UserGestureIndicator):
     24        * loader/FrameLoader.cpp:
     25        (WebCore::shouldAskForNavigationConfirmation):
     26        * page/EventHandler.cpp:
     27        (WebCore::EventHandler::keyEvent):
     28        (WebCore::EventHandler::internalKeyEvent):
     29        * page/EventHandler.h:
     30
    1312017-04-16  Sam Weinig  <sam@webkit.org>
    232
  • trunk/Source/WebCore/dom/Document.h

    r215070 r215404  
    11481148    void updateLastHandledUserGestureTimestamp(MonotonicTime);
    11491149
     1150    void setUserDidInteractWithPage(bool userDidInteractWithPage) { ASSERT(&topDocument() == this); m_userDidInteractWithPage = userDidInteractWithPage; }
     1151    bool userDidInteractWithPage() const { ASSERT(&topDocument() == this); return m_userDidInteractWithPage; }
     1152
    11501153    // Used for testing. Count handlers in the main document, and one per frame which contains handlers.
    11511154    WEBCORE_EXPORT unsigned wheelEventHandlerCount() const;
     
    17351738
    17361739    bool m_areDeviceMotionAndOrientationUpdatesSuspended { false };
     1740    bool m_userDidInteractWithPage { false };
    17371741
    17381742#if ENABLE(TELEPHONE_NUMBER_DETECTION)
  • trunk/Source/WebCore/dom/UserGestureIndicator.cpp

    r214982 r215404  
    5959        document->updateLastHandledUserGestureTimestamp(MonotonicTime::now());
    6060        ResourceLoadObserver::sharedObserver().logUserInteractionWithReducedTimeResolution(*document);
     61        document->topDocument().setUserDidInteractWithPage(true);
    6162    }
    6263}
  • trunk/Source/WebCore/loader/FrameLoader.cpp

    r215262 r215404  
    30373037static bool shouldAskForNavigationConfirmation(Document& document, const BeforeUnloadEvent& event)
    30383038{
    3039     bool userDidInteractWithPage = document.topDocument().hasHadUserInteraction();
     3039    bool userDidInteractWithPage = document.topDocument().userDidInteractWithPage();
    30403040    // Web pages can request we ask for confirmation before navigating by:
    30413041    // - Cancelling the BeforeUnloadEvent (modern way)
  • trunk/Source/WebCore/page/EventHandler.cpp

    r215173 r215404  
    30943094#endif
    30953095
    3096 bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
     3096bool EventHandler::keyEvent(const PlatformKeyboardEvent& keyEvent)
     3097{
     3098    Document* topDocument = m_frame.document() ? &m_frame.document()->topDocument() : nullptr;
     3099    bool savedUserDidInteractWithPage = topDocument ? topDocument->userDidInteractWithPage() : false;
     3100    bool wasHandled = internalKeyEvent(keyEvent);
     3101
     3102    // If the key event was not handled, do not treat it as user interaction with the page.
     3103    if (topDocument && !wasHandled)
     3104        topDocument->setUserDidInteractWithPage(savedUserDidInteractWithPage);
     3105
     3106    return wasHandled;
     3107}
     3108
     3109bool EventHandler::internalKeyEvent(const PlatformKeyboardEvent& initialKeyEvent)
    30973110{
    30983111    Ref<Frame> protectedFrame(m_frame);
  • trunk/Source/WebCore/page/EventHandler.h

    r213278 r215404  
    348348    WEBCORE_EXPORT bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
    349349
     350    bool internalKeyEvent(const PlatformKeyboardEvent&);
     351
    350352    std::optional<Cursor> selectCursor(const HitTestResult&, bool shiftKey);
    351353    void updateCursor(FrameView&, const HitTestResult&, bool shiftKey);
Note: See TracChangeset for help on using the changeset viewer.