Title: [227092] trunk/Source/WebCore
Revision
227092
Author
rn...@webkit.org
Date
2018-01-17 15:19:45 -0800 (Wed, 17 Jan 2018)

Log Message

input and textarea elements should reveal selection in setSelection when focused
https://bugs.webkit.org/show_bug.cgi?id=181715
<rdar://problem/36570546>

Reviewed by Zalan Bujtas.

Made input and textarea elements reveal selection in FrameSelection::setSelection instead of by directly
invoking FrameSelection::revealSelection in their respective updateFocusAppearance to unify code paths.

Also added options to reveal selection up to the main frame to SetSelectionOption to be used in iOS.

* editing/FrameSelection.cpp:
(WebCore::FrameSelection::FrameSelection):
(WebCore::FrameSelection::moveWithoutValidationTo): Takes SelectionRevealMode as an argument and converts
sets appropriate selection options.
(WebCore::FrameSelection::setSelection): Reconstruct SelectionRevealMode out of selection option sets.
(WebCore::FrameSelection::updateAndRevealSelection):
* editing/FrameSelection.h:
(WebCore::FrameSelection): Added RevealSelectionUpToMainFrame as a SelectionRevealMode and replaced
m_shouldRevealSelection by m_selectionRevealMode.
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::updateFocusAppearance): Pass SelectionRevealMode to HTMLTextFormControlElement's
select and restoreCachedSelection instead of directly invoking FrameSelection::revealSelection.
* html/HTMLTextAreaElement.cpp:
(WebCore::HTMLTextAreaElement::updateFocusAppearance): Ditto.
* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::select):
(WebCore::HTMLTextFormControlElement::setSelectionRange):
(WebCore::HTMLTextFormControlElement::restoreCachedSelection):
* html/HTMLTextFormControlElement.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (227091 => 227092)


--- trunk/Source/WebCore/ChangeLog	2018-01-17 23:19:05 UTC (rev 227091)
+++ trunk/Source/WebCore/ChangeLog	2018-01-17 23:19:45 UTC (rev 227092)
@@ -1,3 +1,36 @@
+2018-01-17  Ryosuke Niwa  <rn...@webkit.org>
+
+        input and textarea elements should reveal selection in setSelection when focused
+        https://bugs.webkit.org/show_bug.cgi?id=181715
+        <rdar://problem/36570546>
+
+        Reviewed by Zalan Bujtas.
+
+        Made input and textarea elements reveal selection in FrameSelection::setSelection instead of by directly
+        invoking FrameSelection::revealSelection in their respective updateFocusAppearance to unify code paths.
+
+        Also added options to reveal selection up to the main frame to SetSelectionOption to be used in iOS.
+
+        * editing/FrameSelection.cpp:
+        (WebCore::FrameSelection::FrameSelection):
+        (WebCore::FrameSelection::moveWithoutValidationTo): Takes SelectionRevealMode as an argument and converts
+        sets appropriate selection options.
+        (WebCore::FrameSelection::setSelection): Reconstruct SelectionRevealMode out of selection option sets.
+        (WebCore::FrameSelection::updateAndRevealSelection):
+        * editing/FrameSelection.h:
+        (WebCore::FrameSelection): Added RevealSelectionUpToMainFrame as a SelectionRevealMode and replaced
+        m_shouldRevealSelection by m_selectionRevealMode.
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::updateFocusAppearance): Pass SelectionRevealMode to HTMLTextFormControlElement's
+        select and restoreCachedSelection instead of directly invoking FrameSelection::revealSelection.
+        * html/HTMLTextAreaElement.cpp:
+        (WebCore::HTMLTextAreaElement::updateFocusAppearance): Ditto.
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::select):
+        (WebCore::HTMLTextFormControlElement::setSelectionRange):
+        (WebCore::HTMLTextFormControlElement::restoreCachedSelection):
+        * html/HTMLTextFormControlElement.h:
+
 2018-01-17  Michael Catanzaro  <mcatanz...@igalia.com>
 
         WEBKIT_FRAMEWORK should not modify file-global include directories

Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (227091 => 227092)


--- trunk/Source/WebCore/editing/FrameSelection.cpp	2018-01-17 23:19:05 UTC (rev 227091)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp	2018-01-17 23:19:45 UTC (rev 227092)
@@ -132,7 +132,6 @@
     , m_focused(frame && frame->page() && frame->page()->focusController().focusedFrame() == frame)
     , m_shouldShowBlockCursor(false)
     , m_pendingSelectionUpdate(false)
-    , m_shouldRevealSelection(false)
     , m_alwaysAlignCursorOnScrollWhenRevealingSelection(false)
 #if PLATFORM(IOS)
     , m_updateAppearanceEnabled(false)
@@ -178,13 +177,26 @@
     setSelection(VisibleSelection(base, extent, affinity, selectionHasDirection), defaultSetSelectionOptions(userTriggered));
 }
 
-void FrameSelection::moveWithoutValidationTo(const Position& base, const Position& extent, bool selectionHasDirection, bool shouldSetFocus, const AXTextStateChangeIntent& intent)
+void FrameSelection::moveWithoutValidationTo(const Position& base, const Position& extent, bool selectionHasDirection, bool shouldSetFocus, SelectionRevealMode revealMode, const AXTextStateChangeIntent& intent)
 {
     VisibleSelection newSelection;
     newSelection.setWithoutValidation(base, extent);
     newSelection.setIsDirectional(selectionHasDirection);
     AXTextStateChangeIntent newIntent = intent.type == AXTextStateChangeTypeUnknown ? AXTextStateChangeIntent(AXTextStateChangeTypeSelectionMove, AXTextSelection { AXTextSelectionDirectionDiscontiguous, AXTextSelectionGranularityUnknown, false }) : intent;
-    setSelection(newSelection, defaultSetSelectionOptions() | (shouldSetFocus ? 0 : DoNotSetFocus), newIntent);
+    SetSelectionOptions options = defaultSetSelectionOptions();
+    if (!shouldSetFocus)
+        options |= DoNotSetFocus;
+    switch (revealMode) {
+    case SelectionRevealMode::DoNotReveal:
+        break;
+    case SelectionRevealMode::Reveal:
+        options |= RevealSelection;
+        break;
+    case SelectionRevealMode::RevealUpToMainFrame:
+        options |= RevealSelectionUpToMainFrame;
+        break;
+    }
+    setSelection(newSelection, options, newIntent);
 }
 
 void DragCaretController::setCaretPosition(const VisiblePosition& position)
@@ -354,7 +366,12 @@
     if (!document)
         return;
 
-    m_shouldRevealSelection = options & RevealSelection;
+    if (options & RevealSelectionUpToMainFrame)
+        m_selectionRevealMode = SelectionRevealMode::RevealUpToMainFrame;
+    else if (options & RevealSelection)
+        m_selectionRevealMode = SelectionRevealMode::Reveal;
+    else
+        m_selectionRevealMode = SelectionRevealMode::DoNotReveal;
     m_alwaysAlignCursorOnScrollWhenRevealingSelection = align == AlignCursorOnScrollAlways;
 
     m_pendingSelectionUpdate = true;
@@ -399,7 +416,7 @@
 
     updateAppearance();
 
-    if (m_shouldRevealSelection) {
+    if (m_selectionRevealMode != SelectionRevealMode::DoNotReveal) {
         ScrollAlignment alignment;
 
         if (m_frame->editor().behavior().shouldCenterAlignWhenSelectionIsRevealed())
@@ -407,7 +424,7 @@
         else
             alignment = m_alwaysAlignCursorOnScrollWhenRevealingSelection ? ScrollAlignment::alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded;
 
-        revealSelection(SelectionRevealMode::Reveal, alignment, RevealExtent);
+        revealSelection(m_selectionRevealMode, alignment, RevealExtent);
     }
 
     notifyAccessibilityForSelectionChange(intent);

Modified: trunk/Source/WebCore/editing/FrameSelection.h (227091 => 227092)


--- trunk/Source/WebCore/editing/FrameSelection.h	2018-01-17 23:19:05 UTC (rev 227091)
+++ trunk/Source/WebCore/editing/FrameSelection.h	2018-01-17 23:19:45 UTC (rev 227092)
@@ -125,8 +125,9 @@
         SpellCorrectionTriggered = 1 << 3,
         DoNotSetFocus = 1 << 4,
         DictationTriggered = 1 << 5,
-        RevealSelection = 1 << 6,
-        IsUserTriggered = 1 << 7,
+        IsUserTriggered = 1 << 6,
+        RevealSelection = 1 << 7,
+        RevealSelectionUpToMainFrame = 1 << 8,
     };
     typedef unsigned SetSelectionOptions; // Union of values in SetSelectionOption and EUserTriggered
     static inline SetSelectionOptions defaultSetSelectionOptions(EUserTriggered userTriggered = NotUserTriggered)
@@ -143,7 +144,7 @@
     WEBCORE_EXPORT void moveTo(const VisiblePosition&, const VisiblePosition&, EUserTriggered = NotUserTriggered);
     void moveTo(const Position&, EAffinity, EUserTriggered = NotUserTriggered);
     void moveTo(const Position&, const Position&, EAffinity, EUserTriggered = NotUserTriggered);
-    void moveWithoutValidationTo(const Position&, const Position&, bool selectionHasDirection, bool shouldSetFocus, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
+    void moveWithoutValidationTo(const Position&, const Position&, bool selectionHasDirection, bool shouldSetFocus, SelectionRevealMode, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
 
     const VisibleSelection& selection() const { return m_selection; }
     WEBCORE_EXPORT void setSelection(const VisibleSelection&, SetSelectionOptions = defaultSetSelectionOptions(), AXTextStateChangeIntent = AXTextStateChangeIntent(), CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity);
@@ -344,6 +345,9 @@
     Timer m_appearanceUpdateTimer;
     // The painted bounds of the caret in absolute coordinates
     IntRect m_absCaretBounds;
+
+    SelectionRevealMode m_selectionRevealMode { SelectionRevealMode::DoNotReveal };
+
     bool m_caretInsidePositionFixed : 1;
     bool m_absCaretBoundsDirty : 1;
     bool m_caretPaint : 1;
@@ -351,7 +355,6 @@
     bool m_focused : 1;
     bool m_shouldShowBlockCursor : 1;
     bool m_pendingSelectionUpdate : 1;
-    bool m_shouldRevealSelection : 1;
     bool m_alwaysAlignCursorOnScrollWhenRevealingSelection : 1;
 
 #if PLATFORM(IOS)

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (227091 => 227092)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2018-01-17 23:19:05 UTC (rev 227091)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2018-01-17 23:19:45 UTC (rev 227092)
@@ -444,11 +444,9 @@
 {
     if (isTextField()) {
         if (restorationMode == SelectionRestorationMode::SetDefault || !hasCachedSelection())
-            select(Element::defaultFocusTextStateChangeIntent());
+            select(revealMode, Element::defaultFocusTextStateChangeIntent());
         else
-            restoreCachedSelection();
-        if (document().frame())
-            document().frame()->selection().revealSelection(revealMode);
+            restoreCachedSelection(revealMode);
     } else
         HTMLTextFormControlElement::updateFocusAppearance(restorationMode, revealMode);
 }

Modified: trunk/Source/WebCore/html/HTMLTextAreaElement.cpp (227091 => 227092)


--- trunk/Source/WebCore/html/HTMLTextAreaElement.cpp	2018-01-17 23:19:05 UTC (rev 227091)
+++ trunk/Source/WebCore/html/HTMLTextAreaElement.cpp	2018-01-17 23:19:45 UTC (rev 227092)
@@ -260,12 +260,9 @@
         // If this is the first focus, set a caret at the beginning of the text.  
         // This matches some browsers' behavior; see bug 11746 Comment #15.
         // http://bugs.webkit.org/show_bug.cgi?id=11746#c15
-        setSelectionRange(0, 0, SelectionHasNoDirection, Element::defaultFocusTextStateChangeIntent());
+        setSelectionRange(0, 0, SelectionHasNoDirection, revealMode, Element::defaultFocusTextStateChangeIntent());
     } else
-        restoreCachedSelection(Element::defaultFocusTextStateChangeIntent());
-
-    if (document().frame())
-        document().frame()->selection().revealSelection(revealMode);
+        restoreCachedSelection(revealMode, Element::defaultFocusTextStateChangeIntent());
 }
 
 void HTMLTextAreaElement::defaultEventHandler(Event& event)

Modified: trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp (227091 => 227092)


--- trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp	2018-01-17 23:19:05 UTC (rev 227091)
+++ trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp	2018-01-17 23:19:45 UTC (rev 227092)
@@ -184,15 +184,15 @@
     setSelectionRange(selectionStart(), selectionEnd(), direction);
 }
 
-void HTMLTextFormControlElement::select(const AXTextStateChangeIntent& intent)
+void HTMLTextFormControlElement::select(SelectionRevealMode revealMode, const AXTextStateChangeIntent& intent)
 {
     // FIXME: We should abstract the selection behavior into an EditingBehavior function instead
     // of hardcoding the behavior using a macro define.
 #if PLATFORM(IOS)
     // We don't want to select all the text on iOS. Instead use the standard textfield behavior of going to the end of the line.
-    setSelectionRange(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), SelectionHasForwardDirection, intent);
+    setSelectionRange(std::numeric_limits<int>::max(), std::numeric_limits<int>::max(), SelectionHasForwardDirection, revealMode, intent);
 #else
-    setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection, intent);
+    setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection, revealMode, intent);
 #endif
 }
 
@@ -279,10 +279,10 @@
     else if (directionString == "backward")
         direction = SelectionHasBackwardDirection;
 
-    return setSelectionRange(start, end, direction, intent);
+    return setSelectionRange(start, end, direction, SelectionRevealMode::DoNotReveal, intent);
 }
 
-void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction, const AXTextStateChangeIntent& intent)
+void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextFieldSelectionDirection direction, SelectionRevealMode revealMode, const AXTextStateChangeIntent& intent)
 {
     if (!isTextField())
         return;
@@ -321,7 +321,7 @@
     }
 
     if (RefPtr<Frame> frame = document().frame())
-        frame->selection().moveWithoutValidationTo(startPosition, endPosition, direction != SelectionHasNoDirection, !hasFocus, intent);
+        frame->selection().moveWithoutValidationTo(startPosition, endPosition, direction != SelectionHasNoDirection, !hasFocus, revealMode, intent);
 }
 
 int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& position) const
@@ -472,9 +472,9 @@
     return Range::create(document(), startNode, start, endNode, end);
 }
 
-void HTMLTextFormControlElement::restoreCachedSelection(const AXTextStateChangeIntent& intent)
+void HTMLTextFormControlElement::restoreCachedSelection(SelectionRevealMode revealMode, const AXTextStateChangeIntent& intent)
 {
-    setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, cachedSelectionDirection(), intent);
+    setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, cachedSelectionDirection(), revealMode, intent);
 }
 
 void HTMLTextFormControlElement::selectionChanged(bool shouldFireSelectEvent)

Modified: trunk/Source/WebCore/html/HTMLTextFormControlElement.h (227091 => 227092)


--- trunk/Source/WebCore/html/HTMLTextFormControlElement.h	2018-01-17 23:19:05 UTC (rev 227091)
+++ trunk/Source/WebCore/html/HTMLTextFormControlElement.h	2018-01-17 23:19:45 UTC (rev 227092)
@@ -69,11 +69,11 @@
     WEBCORE_EXPORT void setSelectionStart(int);
     WEBCORE_EXPORT void setSelectionEnd(int);
     WEBCORE_EXPORT void setSelectionDirection(const String&);
-    WEBCORE_EXPORT void select(const AXTextStateChangeIntent& = AXTextStateChangeIntent());
+    WEBCORE_EXPORT void select(SelectionRevealMode = SelectionRevealMode::DoNotReveal, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
     WEBCORE_EXPORT virtual ExceptionOr<void> setRangeText(const String& replacement);
     WEBCORE_EXPORT virtual ExceptionOr<void> setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode);
     void setSelectionRange(int start, int end, const String& direction, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
-    WEBCORE_EXPORT void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
+    WEBCORE_EXPORT void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection, SelectionRevealMode = SelectionRevealMode::DoNotReveal, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
     RefPtr<Range> selection() const;
     String selectedText() const;
 
@@ -116,7 +116,7 @@
         m_cachedSelectionDirection = direction;
     }
 
-    void restoreCachedSelection(const AXTextStateChangeIntent& = AXTextStateChangeIntent());
+    void restoreCachedSelection(SelectionRevealMode, const AXTextStateChangeIntent& = AXTextStateChangeIntent());
     bool hasCachedSelection() const { return m_cachedSelectionStart >= 0; }
 
     virtual void subtreeHasChanged() = 0;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to