Title: [266739] trunk
Revision
266739
Author
[email protected]
Date
2020-09-08 12:22:49 -0700 (Tue, 08 Sep 2020)

Log Message

[macOS] Date/time inputs should preserve focus on value change
https://bugs.webkit.org/show_bug.cgi?id=216272

Reviewed by Wenson Hsieh.

Source/WebCore:

When the value of a date/time input is changed programmatically, the
inner elements of the input are rebuilt. Removing an inner element
that is focused results in the document's activeElement being nulled
out, and the date/time input loses focus.

To fix this issue, check to see whether the input has a focused field
prior to rebuilding. If there is a focused field, make an attempt to
focus the new field with the matching pseudo identifier. This ensures
that the focused field is preserved. If no matching identifier is found,
focus the first field to ensure the date/time input retains focus. The
second case can occur when the new value has different fields than the
old value, for example the presence/lack of a millisecond field in a
time input.

Test: fast/forms/date/date-preserve-focus-value-change.html

* html/shadow/DateTimeEditElement.cpp:
(WebCore::DateTimeEditElement::focusedFieldElement const):
(WebCore::DateTimeEditElement::layout):
* html/shadow/DateTimeEditElement.h:

LayoutTests:

* fast/forms/date/date-preserve-focus-value-change-expected.txt: Added.
* fast/forms/date/date-preserve-focus-value-change.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (266738 => 266739)


--- trunk/LayoutTests/ChangeLog	2020-09-08 19:11:57 UTC (rev 266738)
+++ trunk/LayoutTests/ChangeLog	2020-09-08 19:22:49 UTC (rev 266739)
@@ -1,3 +1,13 @@
+2020-09-08  Aditya Keerthi  <[email protected]>
+
+        [macOS] Date/time inputs should preserve focus on value change
+        https://bugs.webkit.org/show_bug.cgi?id=216272
+
+        Reviewed by Wenson Hsieh.
+
+        * fast/forms/date/date-preserve-focus-value-change-expected.txt: Added.
+        * fast/forms/date/date-preserve-focus-value-change.html: Added.
+
 2020-09-08  Youenn Fablet  <[email protected]>
 
         Fix Internals::supportsVCPEncoder on BigSur

Added: trunk/LayoutTests/fast/forms/date/date-preserve-focus-value-change-expected.txt (0 => 266739)


--- trunk/LayoutTests/fast/forms/date/date-preserve-focus-value-change-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/date/date-preserve-focus-value-change-expected.txt	2020-09-08 19:22:49 UTC (rev 266739)
@@ -0,0 +1,13 @@
+Test that changing the value of a focused date input preserves focus.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS document.activeElement is date
+PASS document.activeElement is date
+PASS document.activeElement is date
+PASS document.activeElement is text
+PASS successfullyParsed is true
+
+TEST COMPLETE
+ 

Added: trunk/LayoutTests/fast/forms/date/date-preserve-focus-value-change.html (0 => 266739)


--- trunk/LayoutTests/fast/forms/date/date-preserve-focus-value-change.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/date/date-preserve-focus-value-change.html	2020-09-08 19:22:49 UTC (rev 266739)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<input id="date" type="date">
+<input id="text" type="text">
+
+<script>
+
+description("Test that changing the value of a focused date input preserves focus.");
+
+date.focus();
+shouldBe("document.activeElement", "date");
+date.value = "2020-09-17";
+shouldBe("document.activeElement", "date");
+date.value = "";
+shouldBe("document.activeElement", "date");
+text.focus();
+shouldBe("document.activeElement", "text");
+
+</script>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (266738 => 266739)


--- trunk/Source/WebCore/ChangeLog	2020-09-08 19:11:57 UTC (rev 266738)
+++ trunk/Source/WebCore/ChangeLog	2020-09-08 19:22:49 UTC (rev 266739)
@@ -1,3 +1,31 @@
+2020-09-08  Aditya Keerthi  <[email protected]>
+
+        [macOS] Date/time inputs should preserve focus on value change
+        https://bugs.webkit.org/show_bug.cgi?id=216272
+
+        Reviewed by Wenson Hsieh.
+
+        When the value of a date/time input is changed programmatically, the
+        inner elements of the input are rebuilt. Removing an inner element
+        that is focused results in the document's activeElement being nulled
+        out, and the date/time input loses focus.
+
+        To fix this issue, check to see whether the input has a focused field
+        prior to rebuilding. If there is a focused field, make an attempt to
+        focus the new field with the matching pseudo identifier. This ensures
+        that the focused field is preserved. If no matching identifier is found,
+        focus the first field to ensure the date/time input retains focus. The
+        second case can occur when the new value has different fields than the
+        old value, for example the presence/lack of a millisecond field in a
+        time input.
+
+        Test: fast/forms/date/date-preserve-focus-value-change.html
+
+        * html/shadow/DateTimeEditElement.cpp:
+        (WebCore::DateTimeEditElement::focusedFieldElement const):
+        (WebCore::DateTimeEditElement::layout):
+        * html/shadow/DateTimeEditElement.h:
+
 2020-09-08  Megan Gardner  <[email protected]>
 
         Switch from deprecated secondarySelectedControlColor to unemphasizedSelectedContentBackgroundColor.

Modified: trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp (266738 => 266739)


--- trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp	2020-09-08 19:11:57 UTC (rev 266738)
+++ trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp	2020-09-08 19:22:49 UTC (rev 266739)
@@ -162,6 +162,19 @@
     });
 }
 
+DateTimeFieldElement* DateTimeEditElement::focusedFieldElement() const
+{
+    auto* focusedElement = document().focusedElement();
+    auto fieldIndex = m_fields.findMatching([&] (auto& field) {
+        return field.ptr() == focusedElement;
+    });
+
+    if (fieldIndex == notFound)
+        return nullptr;
+
+    return m_fields[fieldIndex].ptr();
+}
+
 Ref<DateTimeEditElement> DateTimeEditElement::create(Document& document, EditControlOwner& editControlOwner)
 {
     return adoptRef(*new DateTimeEditElement(document, editControlOwner));
@@ -178,6 +191,7 @@
     }
 
     Element& fieldsWrapper = fieldsWrapperElement();
+    auto* focusedField = focusedFieldElement();
 
     DateTimeEditBuilder builder(*this, layoutParameters);
     Node* lastChildToBeRemoved = fieldsWrapper.lastChild();
@@ -186,6 +200,22 @@
         builder.build(layoutParameters.fallbackDateTimeFormat);
     }
 
+    if (focusedField) {
+        auto& focusedFieldId = focusedField->shadowPseudoId();
+
+        auto foundFieldToFocus = false;
+        for (auto& field : m_fields) {
+            if (field->shadowPseudoId() == focusedFieldId) {
+                foundFieldToFocus = true;
+                field->focus();
+                break;
+            }
+        }
+
+        if (!foundFieldToFocus)
+            focusOnNextFocusableField(0);
+    }
+
     if (lastChildToBeRemoved) {
         while (auto* childNode = fieldsWrapper.firstChild()) {
             fieldsWrapper.removeChild(*childNode);

Modified: trunk/Source/WebCore/html/shadow/DateTimeEditElement.h (266738 => 266739)


--- trunk/Source/WebCore/html/shadow/DateTimeEditElement.h	2020-09-08 19:11:57 UTC (rev 266738)
+++ trunk/Source/WebCore/html/shadow/DateTimeEditElement.h	2020-09-08 19:22:49 UTC (rev 266739)
@@ -88,6 +88,7 @@
     DateTimeEditElement(Document&, EditControlOwner&);
 
     size_t fieldIndexOf(const DateTimeFieldElement&) const;
+    DateTimeFieldElement* focusedFieldElement() const;
     void layout(const LayoutParameters&);
     DateTimeFieldsState valueAsDateTimeFieldsState() const;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to