Changeset 238440 in webkit


Ignore:
Timestamp:
Nov 21, 2018 10:39:15 PM (5 years ago)
Author:
rniwa@webkit.org
Message:

Phantom focus/blur events fire on clicking between text input fields when listening with addEventListener
https://bugs.webkit.org/show_bug.cgi?id=179990

Reviewed by Tim Horton.

The bug was caused by TemporarySelectionChange which is used by TextIndicator::createWithRange
to set and restore the selection putting the focus on the newly mouse-down'ed input element
and restoring the focus back to the input element which originally had the focus immediately.

Fixed the bug by avoiding to set the focus since only selection highlights need to be updated here.
Also made TemporarySelectionOption an enum class.

Unfortunately, no new tests since force click testing is broken :( See <rdar://problem/31301721>.

  • editing/Editor.cpp:

(WebCore::TemporarySelectionChange::TemporarySelectionChange):
(WebCore::TemporarySelectionChange::~TemporarySelectionChange):
(WebCore::TemporarySelectionChange::setSelection): Extracted. Fixed the bug by adding
FrameSelection::DoNotSetFocus to the option when TemporarySelectionOption::DoNotSetFocus is set.

  • editing/Editor.h:
  • page/DragController.cpp:

(WebCore::DragController::performDragOperation):

  • page/TextIndicator.cpp:

(WebCore::TextIndicator::createWithRange): Set TemporarySelectionOption::DoNotSetFocus.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r238438 r238440  
     12018-11-21  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Phantom focus/blur events fire on clicking between text input fields when listening with addEventListener
     4        https://bugs.webkit.org/show_bug.cgi?id=179990
     5
     6        Reviewed by Tim Horton.
     7
     8        The bug was caused by TemporarySelectionChange which is used by TextIndicator::createWithRange
     9        to set and restore the selection putting the focus on the newly mouse-down'ed input element
     10        and restoring the focus back to the input element which originally had the focus immediately.
     11
     12        Fixed the bug by avoiding to set the focus since only selection highlights need to be updated here.
     13        Also made TemporarySelectionOption an enum class.
     14
     15        Unfortunately, no new tests since force click testing is broken :( See <rdar://problem/31301721>.
     16
     17        * editing/Editor.cpp:
     18        (WebCore::TemporarySelectionChange::TemporarySelectionChange):
     19        (WebCore::TemporarySelectionChange::~TemporarySelectionChange):
     20        (WebCore::TemporarySelectionChange::setSelection): Extracted. Fixed the bug by adding
     21        FrameSelection::DoNotSetFocus to the option when TemporarySelectionOption::DoNotSetFocus is set.
     22        * editing/Editor.h:
     23        * page/DragController.cpp:
     24        (WebCore::DragController::performDragOperation):
     25        * page/TextIndicator.cpp:
     26        (WebCore::TextIndicator::createWithRange): Set TemporarySelectionOption::DoNotSetFocus.
     27
    1282018-11-21  Wenson Hsieh  <wenson_hsieh@apple.com>
    229
  • trunk/Source/WebCore/editing/Editor.cpp

    r238359 r238440  
    207207{
    208208#if PLATFORM(IOS_FAMILY)
    209     if (options & TemporarySelectionOptionEnableAppearanceUpdates)
     209    if (options & TemporarySelectionOption::EnableAppearanceUpdates)
    210210        frame.selection().setUpdateAppearanceEnabled(true);
    211211#endif
    212212
    213     if (options & TemporarySelectionOptionIgnoreSelectionChanges)
     213    if (options & TemporarySelectionOption::IgnoreSelectionChanges)
    214214        frame.editor().setIgnoreSelectionChanges(true);
    215215
    216216    if (temporarySelection) {
    217217        m_selectionToRestore = frame.selection().selection();
    218         frame.selection().setSelection(temporarySelection.value());
     218        setSelection(temporarySelection.value());
    219219    }
    220220}
     
    223223{
    224224    if (m_selectionToRestore)
    225         m_frame->selection().setSelection(m_selectionToRestore.value());
    226 
    227     if (m_options & TemporarySelectionOptionIgnoreSelectionChanges) {
    228         auto revealSelection = m_options & TemporarySelectionOptionRevealSelection ? Editor::RevealSelection::Yes : Editor::RevealSelection::No;
     225        setSelection(m_selectionToRestore.value());
     226
     227    if (m_options & TemporarySelectionOption::IgnoreSelectionChanges) {
     228        auto revealSelection = m_options & TemporarySelectionOption::RevealSelection ? Editor::RevealSelection::Yes : Editor::RevealSelection::No;
    229229        m_frame->editor().setIgnoreSelectionChanges(m_wasIgnoringSelectionChanges, revealSelection);
    230230    }
    231231
    232232#if PLATFORM(IOS_FAMILY)
    233     if (m_options & TemporarySelectionOptionEnableAppearanceUpdates)
     233    if (m_options & TemporarySelectionOption::EnableAppearanceUpdates)
    234234        m_frame->selection().setUpdateAppearanceEnabled(m_appearanceUpdatesWereEnabled);
    235235#endif
     236}
     237
     238void TemporarySelectionChange::setSelection(const VisibleSelection& selection)
     239{
     240    auto options = FrameSelection::defaultSetSelectionOptions();
     241    if (m_options & TemporarySelectionOption::DoNotSetFocus)
     242        options.add(FrameSelection::DoNotSetFocus);
     243    m_frame->selection().setSelection(selection, options);
    236244}
    237245
  • trunk/Source/WebCore/editing/Editor.h

    r238080 r238440  
    103103#endif
    104104
    105 enum TemporarySelectionOption : uint8_t {
    106     // Scroll to reveal the selection.
    107     TemporarySelectionOptionRevealSelection = 1 << 0,
     105enum class TemporarySelectionOption : uint8_t {
     106    RevealSelection = 1 << 0,
     107    DoNotSetFocus = 1 << 1,
    108108
    109109    // Don't propagate selection changes to the client layer.
    110     TemporarySelectionOptionIgnoreSelectionChanges = 1 << 1,
     110    IgnoreSelectionChanges = 1 << 2,
    111111
    112112    // Force the render tree to update selection state. Only respected on iOS.
    113     TemporarySelectionOptionEnableAppearanceUpdates = 1 << 2
     113    EnableAppearanceUpdates = 1 << 3,
    114114};
    115115
     
    120120
    121121private:
     122    void setSelection(const VisibleSelection&);
     123
    122124    Ref<Frame> m_frame;
    123125    OptionSet<TemporarySelectionOption> m_options;
  • trunk/Source/WebCore/page/DragController.cpp

    r238375 r238440  
    252252{
    253253    SetForScope<bool> isPerformingDrop(m_isPerformingDrop, true);
    254     TemporarySelectionChange ignoreSelectionChanges(m_page.focusController().focusedOrMainFrame(), std::nullopt, TemporarySelectionOptionIgnoreSelectionChanges);
     254    TemporarySelectionChange ignoreSelectionChanges(m_page.focusController().focusedOrMainFrame(), std::nullopt, TemporarySelectionOption::IgnoreSelectionChanges);
    255255
    256256    m_documentUnderMouse = m_page.mainFrame().documentAtPoint(dragData.clientPosition());
  • trunk/Source/WebCore/page/TextIndicator.cpp

    r237266 r238440  
    7878    VisibleSelection oldSelection = frame->selection().selection();
    7979    OptionSet<TemporarySelectionOption> temporarySelectionOptions;
    80 #if PLATFORM(IOS_FAMILY)
    81     temporarySelectionOptions.add(TemporarySelectionOptionIgnoreSelectionChanges);
    82     temporarySelectionOptions.add(TemporarySelectionOptionEnableAppearanceUpdates);
     80    temporarySelectionOptions.add(TemporarySelectionOption::DoNotSetFocus);
     81#if PLATFORM(IOS_FAMILY)
     82    temporarySelectionOptions.add(TemporarySelectionOption::IgnoreSelectionChanges);
     83    temporarySelectionOptions.add(TemporarySelectionOption::EnableAppearanceUpdates);
    8384#endif
    8485    TemporarySelectionChange selectionChange(*frame, { range }, temporarySelectionOptions);
Note: See TracChangeset for help on using the changeset viewer.