Changeset 269587 in webkit


Ignore:
Timestamp:
Nov 9, 2020 11:08:31 AM (21 months ago)
Author:
Devin Rousso
Message:

autofocus of text input should not select text
https://bugs.webkit.org/show_bug.cgi?id=218585
<rdar://problem/60130704>

Reviewed by Wenson Hsieh.

Source/WebCore:

Test: fast/forms/input-text-autofocus.html

  • dom/Document.h:
  • history/CachedPage.cpp:

(WebCore::CachedPage::restore):

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

(WebCore::HTMLInputElement::updateFocusAppearance):
(WebCore::HTMLInputElement::setDefaultSelectionAfterFocus):
(WebCore::HTMLInputElement::runPostTypeUpdateTasks):
(WebCore::HTMLInputElement::didAttachRenderers):

  • html/HTMLTextAreaElement.cpp:

(WebCore::HTMLTextAreaElement::updateFocusAppearance):

  • html/InputType.cpp:

(WebCore::InputType::accessKeyAction):

  • page/EventHandler.cpp:

(WebCore::EventHandler::dispatchMouseEvent):

  • page/FocusController.cpp:

(WebCore::FocusController::advanceFocusInDocumentOrder):
(WebCore::FocusController::advanceFocusDirectionallyInContainer):
Slightly rework SelectionRestorationMode to replace SetDefault with two new values:

  • PlaceCaretAtStart puts the caret at the start, regardless of any cached selection
  • SelectAll selects all text, regardless of any cached selection (existing behavior)

In order to preserve existing behavior, the default Restore will have the same effect as
SelectAll if there is no cached selection (and is renamed to RestoreOrSelectAll as such).

  • dom/Element.h:
  • dom/Element.cpp:

(WebCore::Element::focus):

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

(WebCore::HTMLLabelElement::focus):

  • html/HTMLLegendElement.h:
  • html/HTMLLegendElement.cpp:

(WebCore::HTMLLegendElement::focus):
Replace the bool restorePreviousSelection with SelectionRestorationMode since that's
what it's eventually used for anyways. This also allows for more flexibility in behavior,
such as callers using the new SelectionRestorationMode values.

  • html/HTMLFormControlElement.cpp:

(WebCore::HTMLFormControlElement::didAttachRenderers):
Change to PlaceCaretAtStart to match other browsers.

Source/WebKit:

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::restoreSelectionInFocusedEditableElement):
Slightly rework SelectionRestorationMode to replace SetDefault with two new values:

  • PlaceCaretAtStart puts the caret at the start, regardless of any cached selection
  • SelectAll selects all text, regardless of any cached selection (existing behavior)

In order to preserve existing behavior, the default Restore will have the same effect as
SelectAll if there is no cached selection (and is renamed to RestoreOrSelectAll as such).

LayoutTests:

  • fast/forms/input-text-autofocus.html: Added.
  • fast/forms/input-text-autofocus-expected.txt: Added.
  • fast/forms/input-first-letter-edit.html:
  • fast/forms/input-first-letter-edit-expected.html:
Location:
trunk
Files:
2 added
21 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r269584 r269587  
     12020-11-09  Devin Rousso  <drousso@apple.com>
     2
     3        autofocus of text input should not select text
     4        https://bugs.webkit.org/show_bug.cgi?id=218585
     5        <rdar://problem/60130704>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * fast/forms/input-text-autofocus.html: Added.
     10        * fast/forms/input-text-autofocus-expected.txt: Added.
     11
     12        * fast/forms/input-first-letter-edit.html:
     13        * fast/forms/input-first-letter-edit-expected.html:
     14
    1152020-11-09  Per Arne Vollan  <pvollan@apple.com>
    216
  • trunk/LayoutTests/fast/forms/input-first-letter-edit-expected.html

    r118711 r269587  
    44</head>
    55<body>
    6     <input type="text" id="target" value="Hello" autofocus="autofocus" />
     6    <input type="text" id="target" value="Hello" />
    77</body>
    88</html>
  • trunk/LayoutTests/fast/forms/input-first-letter-edit.html

    r121008 r269587  
    2020        eventSender.keyDown("l");
    2121        eventSender.keyDown("o");
    22         document.execCommand("selectAll"); // Does selectAll for aligning the @autofocus attribute on the expectation.
     22        target.blur();
    2323        testRunner.notifyDone();
    2424    }
  • trunk/Source/WebCore/ChangeLog

    r269585 r269587  
     12020-11-09  Devin Rousso  <drousso@apple.com>
     2
     3        autofocus of text input should not select text
     4        https://bugs.webkit.org/show_bug.cgi?id=218585
     5        <rdar://problem/60130704>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        Test: fast/forms/input-text-autofocus.html
     10
     11        * dom/Document.h:
     12        * history/CachedPage.cpp:
     13        (WebCore::CachedPage::restore):
     14        * html/HTMLInputElement.h:
     15        * html/HTMLInputElement.cpp:
     16        (WebCore::HTMLInputElement::updateFocusAppearance):
     17        (WebCore::HTMLInputElement::setDefaultSelectionAfterFocus):
     18        (WebCore::HTMLInputElement::runPostTypeUpdateTasks):
     19        (WebCore::HTMLInputElement::didAttachRenderers):
     20        * html/HTMLTextAreaElement.cpp:
     21        (WebCore::HTMLTextAreaElement::updateFocusAppearance):
     22        * html/InputType.cpp:
     23        (WebCore::InputType::accessKeyAction):
     24        * page/EventHandler.cpp:
     25        (WebCore::EventHandler::dispatchMouseEvent):
     26        * page/FocusController.cpp:
     27        (WebCore::FocusController::advanceFocusInDocumentOrder):
     28        (WebCore::FocusController::advanceFocusDirectionallyInContainer):
     29        Slightly rework `SelectionRestorationMode` to replace `SetDefault` with two new values:
     30         - `PlaceCaretAtStart` puts the caret at the start, regardless of any cached selection
     31         - `SelectAll` selects all text, regardless of any cached selection (existing behavior)
     32        In order to preserve existing behavior, the default `Restore` will have the same effect as
     33        `SelectAll` if there is no cached selection (and is renamed to `RestoreOrSelectAll` as such).
     34
     35        * dom/Element.h:
     36        * dom/Element.cpp:
     37        (WebCore::Element::focus):
     38        * html/HTMLLabelElement.h:
     39        * html/HTMLLabelElement.cpp:
     40        (WebCore::HTMLLabelElement::focus):
     41        * html/HTMLLegendElement.h:
     42        * html/HTMLLegendElement.cpp:
     43        (WebCore::HTMLLegendElement::focus):
     44        Replace the `bool restorePreviousSelection` with `SelectionRestorationMode` since that's
     45        what it's eventually used for anyways. This also allows for more flexibility in behavior,
     46        such as callers using the new `SelectionRestorationMode` values.
     47
     48        * html/HTMLFormControlElement.cpp:
     49        (WebCore::HTMLFormControlElement::didAttachRenderers):
     50        Change to `PlaceCaretAtStart` to match other browsers.
     51
    1522020-11-09  Antti Koivisto  <antti@apple.com>
    253
  • trunk/Source/WebCore/dom/Document.h

    r269437 r269587  
    289289enum DimensionsCheck { WidthDimensionsCheck = 1 << 0, HeightDimensionsCheck = 1 << 1, AllDimensionsCheck = 1 << 2 };
    290290
    291 enum class SelectionRestorationMode { Restore, SetDefault };
     291enum class SelectionRestorationMode : uint8_t {
     292    RestoreOrSelectAll,
     293    SelectAll,
     294    PlaceCaretAtStart,
     295};
    292296
    293297enum class HttpEquivPolicy {
  • trunk/Source/WebCore/dom/Element.cpp

    r269161 r269587  
    29942994}
    29952995
    2996 void Element::focus(bool restorePreviousSelection, FocusDirection direction)
     2996void Element::focus(SelectionRestorationMode restorationMode, FocusDirection direction)
    29972997{
    29982998    if (!isConnected())
     
    30423042    }
    30433043
    3044     newTarget->revealFocusedElement(restorePreviousSelection ? SelectionRestorationMode::Restore : SelectionRestorationMode::SetDefault);
     3044    newTarget->revealFocusedElement(restorationMode);
    30453045}
    30463046
  • trunk/Source/WebCore/dom/Element.h

    r269027 r269587  
    401401
    402402    static AXTextStateChangeIntent defaultFocusTextStateChangeIntent() { return AXTextStateChangeIntent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, true }); }
    403     virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirection::None);
     403    virtual void focus(SelectionRestorationMode = SelectionRestorationMode::RestoreOrSelectAll, FocusDirection = FocusDirection::None);
    404404    void revealFocusedElement(SelectionRestorationMode);
    405405    virtual RefPtr<Element> focusAppearanceUpdateTarget();
  • trunk/Source/WebCore/history/CachedPage.cpp

    r267614 r269587  
    146146        }
    147147#endif
    148         element->updateFocusAppearance(SelectionRestorationMode::Restore);
     148        element->updateFocusAppearance(SelectionRestorationMode::RestoreOrSelectAll);
    149149#if PLATFORM(IOS_FAMILY)
    150150        if (frameView)
  • trunk/Source/WebCore/html/HTMLFormControlElement.cpp

    r268866 r269587  
    255255        if (frameView && frameView->layoutContext().isInLayout()) {
    256256            frameView->queuePostLayoutCallback([element] {
    257                 element->focus();
     257                element->focus(SelectionRestorationMode::PlaceCaretAtStart);
    258258            });
    259259        } else {
    260260            Style::queuePostResolutionCallback([element] {
    261                 element->focus();
     261                element->focus(SelectionRestorationMode::PlaceCaretAtStart);
    262262            });
    263263        }
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r269528 r269587  
    477477{
    478478    if (isTextField()) {
    479         if (restorationMode == SelectionRestorationMode::SetDefault || !hasCachedSelection())
    480             setDefaultSelectionAfterFocus(revealMode);
     479        if (restorationMode == SelectionRestorationMode::RestoreOrSelectAll && hasCachedSelection())
     480            restoreCachedSelection(revealMode);
    481481        else
    482             restoreCachedSelection(revealMode);
     482            setDefaultSelectionAfterFocus(restorationMode, revealMode);
    483483    } else
    484484        HTMLTextFormControlElement::updateFocusAppearance(restorationMode, revealMode);
    485485}
    486486
    487 void HTMLInputElement::setDefaultSelectionAfterFocus(SelectionRevealMode revealMode)
     487void HTMLInputElement::setDefaultSelectionAfterFocus(SelectionRestorationMode restorationMode, SelectionRevealMode revealMode)
    488488{
    489489    ASSERT(isTextField());
     
    495495        direction = SelectionHasForwardDirection;
    496496    }
    497     setSelectionRange(start, std::numeric_limits<int>::max(), direction, revealMode, Element::defaultFocusTextStateChangeIntent());
     497    int end = restorationMode == SelectionRestorationMode::PlaceCaretAtStart ? start : std::numeric_limits<int>::max();
     498    setSelectionRange(start, end, direction, revealMode, Element::defaultFocusTextStateChangeIntent());
    498499}
    499500
     
    619620
    620621    if (document().focusedElement() == this)
    621         updateFocusAppearance(SelectionRestorationMode::Restore, SelectionRevealMode::Reveal);
     622        updateFocusAppearance(SelectionRestorationMode::RestoreOrSelectAll, SelectionRevealMode::Reveal);
    622623
    623624    setChangedSinceLastFormControlChangeEvent(false);
     
    867868    if (document().focusedElement() == this) {
    868869        document().view()->queuePostLayoutCallback([protectedThis = makeRef(*this)] {
    869             protectedThis->updateFocusAppearance(SelectionRestorationMode::Restore, SelectionRevealMode::Reveal);
     870            protectedThis->updateFocusAppearance(SelectionRestorationMode::RestoreOrSelectAll, SelectionRevealMode::Reveal);
    870871        });
    871872    }
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r266114 r269587  
    456456    void removeFromRadioButtonGroup();
    457457
    458     void setDefaultSelectionAfterFocus(SelectionRevealMode);
     458    void setDefaultSelectionAfterFocus(SelectionRestorationMode, SelectionRevealMode);
    459459
    460460    AtomString m_name;
  • trunk/Source/WebCore/html/HTMLLabelElement.cpp

    r259687 r269587  
    173173}
    174174
    175 void HTMLLabelElement::focus(bool restorePreviousSelection, FocusDirection direction)
     175void HTMLLabelElement::focus(SelectionRestorationMode restorationMode, FocusDirection direction)
    176176{
    177177    Ref<HTMLLabelElement> protectedThis(*this);
     
    179179        document().updateLayout();
    180180        if (isFocusable()) {
    181             // The value of restorePreviousSelection is not used for label elements as it doesn't override updateFocusAppearance.
    182             Element::focus(restorePreviousSelection, direction);
     181            // The value of restorationMode is not used for label elements as it doesn't override updateFocusAppearance.
     182            Element::focus(restorationMode, direction);
    183183            return;
    184184        }
     
    187187    // To match other browsers, always restore previous selection.
    188188    if (auto element = control())
    189         element->focus(true, direction);
     189        element->focus(SelectionRestorationMode::RestoreOrSelectAll, direction);
    190190}
    191191
  • trunk/Source/WebCore/html/HTMLLabelElement.h

    r259687 r269587  
    5252    void defaultEventHandler(Event&) final;
    5353
    54     void focus(bool restorePreviousSelection, FocusDirection) final;
     54    void focus(SelectionRestorationMode, FocusDirection) final;
    5555
    5656    bool isInteractiveContent() const final { return true; }
  • trunk/Source/WebCore/html/HTMLLegendElement.cpp

    r259687 r269587  
    5858}
    5959
    60 void HTMLLegendElement::focus(bool restorePreviousSelection, FocusDirection direction)
     60void HTMLLegendElement::focus(SelectionRestorationMode restorationMode, FocusDirection direction)
    6161{
    6262    if (document().haveStylesheetsLoaded()) {
    6363        document().updateLayoutIgnorePendingStylesheets();
    6464        if (isFocusable()) {
    65             Element::focus(restorePreviousSelection, direction);
     65            Element::focus(restorationMode, direction);
    6666            return;
    6767        }
     
    7070    // To match other browsers' behavior, never restore previous selection.
    7171    if (auto control = associatedControl())
    72         control->focus(false, direction);
     72        control->focus(SelectionRestorationMode::SelectAll, direction);
    7373}
    7474
  • trunk/Source/WebCore/html/HTMLLegendElement.h

    r259687 r269587  
    4444
    4545    bool accessKeyAction(bool sendMouseEvents) final;
    46     void focus(bool restorePreviousSelection, FocusDirection) final;
     46    void focus(SelectionRestorationMode, FocusDirection) final;
    4747};
    4848
  • trunk/Source/WebCore/html/HTMLTextAreaElement.cpp

    r266026 r269587  
    269269void HTMLTextAreaElement::updateFocusAppearance(SelectionRestorationMode restorationMode, SelectionRevealMode revealMode)
    270270{
    271     if (restorationMode == SelectionRestorationMode::SetDefault || !hasCachedSelection()) {
     271    if (restorationMode == SelectionRestorationMode::RestoreOrSelectAll && hasCachedSelection())
     272        restoreCachedSelection(revealMode, Element::defaultFocusTextStateChangeIntent());
     273    else {
    272274        // If this is the first focus, set a caret at the beginning of the text. 
    273275        // This matches some browsers' behavior; see bug 11746 Comment #15.
    274276        // http://bugs.webkit.org/show_bug.cgi?id=11746#c15
    275277        setSelectionRange(0, 0, SelectionHasNoDirection, revealMode, Element::defaultFocusTextStateChangeIntent());
    276     } else
    277         restoreCachedSelection(revealMode, Element::defaultFocusTextStateChangeIntent());
     278    }
    278279}
    279280
  • trunk/Source/WebCore/html/InputType.cpp

    r266114 r269587  
    583583{
    584584    ASSERT(element());
    585     element()->focus(false);
     585    element()->focus(SelectionRestorationMode::SelectAll);
    586586    return false;
    587587}
  • trunk/Source/WebCore/page/EventHandler.cpp

    r269442 r269587  
    27542754
    27552755    if (element && m_mouseDownDelegatedFocus)
    2756         element->revealFocusedElement(SelectionRestorationMode::SetDefault);
     2756        element->revealFocusedElement(SelectionRestorationMode::SelectAll);
    27572757
    27582758    return true;
  • trunk/Source/WebCore/page/FocusController.cpp

    r269059 r269587  
    534534    }
    535535
    536     element->focus(false, direction);
     536    element->focus(SelectionRestorationMode::SelectAll, direction);
    537537    return true;
    538538}
     
    11081108    ASSERT(element);
    11091109
    1110     element->focus(false, direction);
     1110    element->focus(SelectionRestorationMode::SelectAll, direction);
    11111111    return true;
    11121112}
  • trunk/Source/WebKit/ChangeLog

    r269584 r269587  
     12020-11-09  Devin Rousso  <drousso@apple.com>
     2
     3        autofocus of text input should not select text
     4        https://bugs.webkit.org/show_bug.cgi?id=218585
     5        <rdar://problem/60130704>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * WebProcess/WebPage/WebPage.cpp:
     10        (WebKit::WebPage::restoreSelectionInFocusedEditableElement):
     11        Slightly rework `SelectionRestorationMode` to replace `SetDefault` with two new values:
     12         - `PlaceCaretAtStart` puts the caret at the start, regardless of any cached selection
     13         - `SelectAll` selects all text, regardless of any cached selection (existing behavior)
     14        In order to preserve existing behavior, the default `Restore` will have the same effect as
     15        `SelectAll` if there is no cached selection (and is renamed to `RestoreOrSelectAll` as such).
     16
    1172020-11-09  Per Arne Vollan  <pvollan@apple.com>
    218
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r269498 r269587  
    45714571    if (auto document = frame.document()) {
    45724572        if (auto element = document->focusedElement())
    4573             element->updateFocusAppearance(SelectionRestorationMode::Restore, SelectionRevealMode::DoNotReveal);
     4573            element->updateFocusAppearance(SelectionRestorationMode::RestoreOrSelectAll, SelectionRevealMode::DoNotReveal);
    45744574    }
    45754575}
Note: See TracChangeset for help on using the changeset viewer.