Title: [257839] trunk
Revision
257839
Author
an...@apple.com
Date
2020-03-04 04:11:13 -0800 (Wed, 04 Mar 2020)

Log Message

Avoid full style resolution on Element::focus()
https://bugs.webkit.org/show_bug.cgi?id=208504

Reviewed by Zalan Bujtas.

Source/WebCore:

Element::focus() currently triggers full style resolution both before (to compute element visibility)
and after (for no particular reason).

Resolving style can be costly if there are further DOM mutations that end up invalidating it again.
This patch adds a cheaper single-element way to computing visibility and uses it for focus().

This appears to be 3-4% Speedometer progression.

Test: fast/forms/focus-after-visibility-change.html

* accessibility/AXObjectCache.cpp:
(WebCore::AXObjectCache::focusedUIElementForPage):

AX code assumes renderers have exist for focused element so ensure style is up to date.

* dom/Document.cpp:
(WebCore::Document::setFocusedElement):

Remove style resolution.

* dom/Element.cpp:
(WebCore::Element::isFocusable const):

Use isVisibleWithoutResolvingFullStyle helper.

(WebCore::Element::focus):

Avoid style resolution if the element is in a subtree that doesn't have renderers yet.

(WebCore::Element::resolveComputedStyle):

Add a mode where we bail out when we figure out we are in display:none subtree.

(WebCore::Element::hasValidStyle const):

See if we already have valid style.

(WebCore::Element::isVisibleWithoutResolvingFullStyle const):

Use computed style mechanism for subtrees that have no renderers yet.

(WebCore::Element::computedStyle):
* dom/Element.h:
* html/HTMLAreaElement.cpp:
(WebCore::HTMLAreaElement::isFocusable const):

Use isVisibleWithoutResolvingFullStyle here too.

* html/HTMLSelectElement.cpp:
(WebCore::HTMLSelectElement::platformHandleKeydownEvent):
(WebCore::HTMLSelectElement::menuListDefaultEventHandler):

Update style after explicit focus() calls to keep the existing behavior.

* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::setRangeText):

Ensure the renderer is created.

* html/shadow/SpinButtonElement.cpp:
(WebCore::SpinButtonElement::forwardEvent):

Remove unneeded renderer test.

LayoutTests:

* fast/events/keypress-removed-node-expected.txt:
* fast/events/keypress-removed-node.html:

Modify the test so it is not sensitive to non-rendered whitespace changes
(caused by timing of render tree updates).

* fast/forms/autofocus-input-css-style-change.html:

Read the <input autofocus> :focus style in rAF as focusing happens asynchronously. This matches other browsers.

* fast/forms/focus-after-visibility-change-expected.txt: Added.
* fast/forms/focus-after-visibility-change.html: Added.

Add a simple test for visibility style change after renderer has already be created.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (257838 => 257839)


--- trunk/LayoutTests/ChangeLog	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/LayoutTests/ChangeLog	2020-03-04 12:11:13 UTC (rev 257839)
@@ -1,3 +1,25 @@
+2020-03-04  Antti Koivisto  <an...@apple.com>
+
+        Avoid full style resolution on Element::focus()
+        https://bugs.webkit.org/show_bug.cgi?id=208504
+
+        Reviewed by Zalan Bujtas.
+
+        * fast/events/keypress-removed-node-expected.txt:
+        * fast/events/keypress-removed-node.html:
+
+        Modify the test so it is not sensitive to non-rendered whitespace changes
+        (caused by timing of render tree updates).
+
+        * fast/forms/autofocus-input-css-style-change.html:
+
+        Read the <input autofocus> :focus style in rAF as focusing happens asynchronously. This matches other browsers.
+
+        * fast/forms/focus-after-visibility-change-expected.txt: Added.
+        * fast/forms/focus-after-visibility-change.html: Added.
+
+        Add a simple test for visibility style change after renderer has already be created.
+
 2020-03-04  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [GTK][WPE] Stop adding volume-box class to volume box element

Modified: trunk/LayoutTests/fast/events/keypress-removed-node-expected.txt (257838 => 257839)


--- trunk/LayoutTests/fast/events/keypress-removed-node-expected.txt	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/LayoutTests/fast/events/keypress-removed-node-expected.txt	2020-03-04 12:11:13 UTC (rev 257839)
@@ -1,3 +1,3 @@
 This test verifies that a node does not retain keyboard focus after it has been removed from the DOM.
 
- PASS: did not get keyboard event.
+PASS: did not get keyboard event.

Modified: trunk/LayoutTests/fast/events/keypress-removed-node.html (257838 => 257839)


--- trunk/LayoutTests/fast/events/keypress-removed-node.html	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/LayoutTests/fast/events/keypress-removed-node.html	2020-03-04 12:11:13 UTC (rev 257839)
@@ -1,8 +1,6 @@
 <p>This test verifies that a node does not retain keyboard focus after it has
 been removed from the DOM.</p>
-<hr>
-<input type="text">
-<pre id="console">PASS: did not get keyboard event.</pre>
+<hr><input type="text"><pre id="console">PASS: did not get keyboard event.</pre>
 
 <script>
 if (window.testRunner)

Modified: trunk/LayoutTests/fast/forms/autofocus-input-css-style-change.html (257838 => 257839)


--- trunk/LayoutTests/fast/forms/autofocus-input-css-style-change.html	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/LayoutTests/fast/forms/autofocus-input-css-style-change.html	2020-03-04 12:11:13 UTC (rev 257839)
@@ -13,9 +13,11 @@
     testRunner.dumpAsText();
 }
 
-var test = document.getElementById("test");
-if (document.defaultView.getComputedStyle(test, null).getPropertyValue('background-color') == "rgb(0, 128, 0)")
-    result.innerHTML = "PASS";
+requestAnimationFrame(()=>{
+    if (getComputedStyle(test, null).getPropertyValue('background-color') == "rgb(0, 128, 0)")
+        result.innerHTML = "PASS";
+});
+
 </script>
 </body>
 </html>

Added: trunk/LayoutTests/fast/forms/focus-after-visibility-change-expected.txt (0 => 257839)


--- trunk/LayoutTests/fast/forms/focus-after-visibility-change-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/focus-after-visibility-change-expected.txt	2020-03-04 12:11:13 UTC (rev 257839)
@@ -0,0 +1,2 @@
+PASS
+

Added: trunk/LayoutTests/fast/forms/focus-after-visibility-change.html (0 => 257839)


--- trunk/LayoutTests/fast/forms/focus-after-visibility-change.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/focus-after-visibility-change.html	2020-03-04 12:11:13 UTC (rev 257839)
@@ -0,0 +1,9 @@
+<div id=log>PASS</div>
+<input id=input _onfocus_="log.textContent = 'FAIL';">
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+document.body.offsetLeft;
+input.style.visibility="hidden";
+input.focus();
+</script>

Modified: trunk/Source/WebCore/ChangeLog (257838 => 257839)


--- trunk/Source/WebCore/ChangeLog	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/ChangeLog	2020-03-04 12:11:13 UTC (rev 257839)
@@ -1,3 +1,74 @@
+2020-03-04  Antti Koivisto  <an...@apple.com>
+
+        Avoid full style resolution on Element::focus()
+        https://bugs.webkit.org/show_bug.cgi?id=208504
+
+        Reviewed by Zalan Bujtas.
+
+        Element::focus() currently triggers full style resolution both before (to compute element visibility)
+        and after (for no particular reason).
+
+        Resolving style can be costly if there are further DOM mutations that end up invalidating it again.
+        This patch adds a cheaper single-element way to computing visibility and uses it for focus().
+
+        This appears to be 3-4% Speedometer progression.
+
+        Test: fast/forms/focus-after-visibility-change.html
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::focusedUIElementForPage):
+
+        AX code assumes renderers have exist for focused element so ensure style is up to date.
+
+        * dom/Document.cpp:
+        (WebCore::Document::setFocusedElement):
+
+        Remove style resolution.
+
+        * dom/Element.cpp:
+        (WebCore::Element::isFocusable const):
+
+        Use isVisibleWithoutResolvingFullStyle helper.
+
+        (WebCore::Element::focus):
+
+        Avoid style resolution if the element is in a subtree that doesn't have renderers yet.
+
+        (WebCore::Element::resolveComputedStyle):
+
+        Add a mode where we bail out when we figure out we are in display:none subtree.
+
+        (WebCore::Element::hasValidStyle const):
+
+        See if we already have valid style.
+
+        (WebCore::Element::isVisibleWithoutResolvingFullStyle const):
+
+        Use computed style mechanism for subtrees that have no renderers yet.
+
+        (WebCore::Element::computedStyle):
+        * dom/Element.h:
+        * html/HTMLAreaElement.cpp:
+        (WebCore::HTMLAreaElement::isFocusable const):
+
+        Use isVisibleWithoutResolvingFullStyle here too.
+
+        * html/HTMLSelectElement.cpp:
+        (WebCore::HTMLSelectElement::platformHandleKeydownEvent):
+        (WebCore::HTMLSelectElement::menuListDefaultEventHandler):
+
+        Update style after explicit focus() calls to keep the existing behavior.
+
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::setRangeText):
+
+        Ensure the renderer is created.
+
+        * html/shadow/SpinButtonElement.cpp:
+        (WebCore::SpinButtonElement::forwardEvent):
+
+        Remove unneeded renderer test.
+
 2020-03-04  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [GTK][WPE] Use restore view icon for exit fullscreen button in media controls

Modified: trunk/Source/WebCore/accessibility/AXObjectCache.cpp (257838 => 257839)


--- trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/accessibility/AXObjectCache.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -427,6 +427,8 @@
     if (!focusedDocument)
         return nullptr;
 
+    focusedDocument->updateStyleIfNeeded();
+
 #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
     if (clientSupportsIsolatedTree())
         return isolatedTreeFocusedObject(*focusedDocument);

Modified: trunk/Source/WebCore/dom/Document.cpp (257838 => 257839)


--- trunk/Source/WebCore/dom/Document.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/dom/Document.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -4275,11 +4275,12 @@
     if (backForwardCacheState() != NotInBackForwardCache)
         return false;
 
-    bool focusChangeBlocked = false;
     RefPtr<Element> oldFocusedElement = WTFMove(m_focusedElement);
 
     // Remove focus from the existing focus node (if any)
     if (oldFocusedElement) {
+        bool focusChangeBlocked = false;
+
         oldFocusedElement->setFocus(false);
         setFocusNavigationStartingNode(nullptr);
 
@@ -4332,23 +4333,21 @@
         if (is<HTMLInputElement>(oldFocusedElement)) {
             // HTMLInputElement::didBlur just scrolls text fields back to the beginning.
             // FIXME: This could be done asynchronusly.
-            // Updating style may dispatch events due to PostResolutionCallback
-            if (eventsMode == FocusRemovalEventsMode::Dispatch)
-                updateStyleIfNeeded();
             downcast<HTMLInputElement>(*oldFocusedElement).didBlur();
         }
+
+        if (focusChangeBlocked)
+            return false;
     }
 
     if (newFocusedElement && newFocusedElement->isFocusable()) {
         if (&newFocusedElement->document() != this) {
             // Bluring oldFocusedElement may have moved newFocusedElement across documents.
-            focusChangeBlocked = true;
-            goto SetFocusedNodeDone;
+            return false;
         }
         if (newFocusedElement->isRootEditableElement() && !acceptsEditingFocus(*newFocusedElement)) {
             // delegate blocks focus change
-            focusChangeBlocked = true;
-            goto SetFocusedNodeDone;
+            return false;
         }
         // Set focus on the new node
         m_focusedElement = newFocusedElement;
@@ -4359,8 +4358,7 @@
 
         if (m_focusedElement != newFocusedElement) {
             // handler shifted focus
-            focusChangeBlocked = true;
-            goto SetFocusedNodeDone;
+            return false;
         }
 
         m_focusedElement->dispatchFocusInEvent(eventNames().focusinEvent, oldFocusedElement.copyRef()); // DOM level 3 bubbling focus event.
@@ -4367,8 +4365,7 @@
 
         if (m_focusedElement != newFocusedElement) {
             // handler shifted focus
-            focusChangeBlocked = true;
-            goto SetFocusedNodeDone;
+            return false;
         }
 
         // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
@@ -4377,8 +4374,7 @@
 
         if (m_focusedElement != newFocusedElement) {
             // handler shifted focus
-            focusChangeBlocked = true;
-            goto SetFocusedNodeDone;
+            return false;
         }
 
         m_focusedElement->setFocus(true);
@@ -4386,8 +4382,7 @@
         // The setFocus call triggers a blur and a focus event. Event handlers could cause the focused element to be cleared.
         if (m_focusedElement != newFocusedElement) {
             // handler shifted focus
-            focusChangeBlocked = true;
-            goto SetFocusedNodeDone;
+            return false;
         }
 
         if (m_focusedElement->isRootEditableElement())
@@ -4412,21 +4407,16 @@
         }
     }
 
-    if (!focusChangeBlocked && m_focusedElement) {
+    if (m_focusedElement) {
         // Create the AXObject cache in a focus change because GTK relies on it.
         if (AXObjectCache* cache = axObjectCache())
             cache->deferFocusedUIElementChangeIfNeeded(oldFocusedElement.get(), newFocusedElement.get());
     }
 
-    if (!focusChangeBlocked && page())
+    if (page())
         page()->chrome().focusedElementChanged(m_focusedElement.get());
 
-SetFocusedNodeDone:
-    // Updating style may dispatch events due to PostResolutionCallback
-    // FIXME: Why is synchronous style update needed here at all?
-    if (eventsMode == FocusRemovalEventsMode::Dispatch)
-        updateStyleIfNeeded();
-    return !focusChangeBlocked;
+    return true;
 }
 
 static bool shouldResetFocusNavigationStartingNode(Node& node)

Modified: trunk/Source/WebCore/dom/Element.cpp (257838 => 257839)


--- trunk/Source/WebCore/dom/Element.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/dom/Element.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -607,23 +607,13 @@
         return false;
 
     if (!renderer()) {
-        // If the node is in a display:none tree it might say it needs style recalc but
-        // the whole document is actually up to date.
-        // FIXME: We should be able to assert !needsStyleRecalc() || !document().childNeedsStyleRecalc()
-        // but it hits too frequently on websites like Gmail and Microsoft Exchange.
-
         // Elements in canvas fallback content are not rendered, but they are allowed to be
         // focusable as long as their canvas is displayed and visible.
         if (auto* canvas = ancestorsOfType<HTMLCanvasElement>(*this).first())
-            return canvas->renderer() && canvas->renderer()->style().visibility() == Visibility::Visible;
+            return canvas->isVisibleWithoutResolvingFullStyle();
     }
 
-    // FIXME: Even if we are not visible, we might have a child that is visible.
-    // Hyatt wants to fix that some day with a "has visible content" flag or the like.
-    if (!renderer() || renderer()->style().visibility() != Visibility::Visible)
-        return false;
-
-    return true;
+    return isVisibleWithoutResolvingFullStyle();
 }
 
 bool Element::isUserActionElementInActiveChain() const
@@ -2985,7 +2975,10 @@
     }
 
     RefPtr<Element> newTarget = this;
-    if (document->haveStylesheetsLoaded())
+
+    // If we don't have renderer yet, isFocusable will compute it without style update.
+    // FIXME: Expand it to avoid style update in all cases.
+    if (renderer() && document->haveStylesheetsLoaded())
         document->updateStyleIfNeeded();
 
     if (&newTarget->document() != document.ptr())
@@ -3290,7 +3283,7 @@
     return nullptr;
 }
 
-const RenderStyle& Element::resolveComputedStyle()
+const RenderStyle* Element::resolveComputedStyle(ResolveComputedStyleMode mode)
 {
     ASSERT(isConnected());
     ASSERT(!existingComputedStyle());
@@ -3314,11 +3307,56 @@
         computedStyle = style.get();
         ElementRareData& rareData = element->ensureElementRareData();
         rareData.setComputedStyle(WTFMove(style));
+
+        if (mode == ResolveComputedStyleMode::RenderedOnly && computedStyle->display() == DisplayType::None)
+            return nullptr;
     }
 
-    return *computedStyle;
+    return computedStyle;
 }
 
+bool Element::hasValidStyle() const
+{
+    if (!document().needsStyleRecalc())
+        return true;
+
+    if (document().hasPendingFullStyleRebuild())
+        return false;
+    
+    for (auto& element : lineageOfType<Element>(*this)) {
+        if (element.styleValidity() != Style::Validity::Valid)
+            return false;
+    }
+    return true;
+}
+
+bool Element::isVisibleWithoutResolvingFullStyle() const
+{
+    if (renderStyle() || hasValidStyle())
+        return renderStyle() && renderStyle()->visibility() == Visibility::Visible;
+
+    // Compute style in yet unstyled subtree.
+    auto* style = existingComputedStyle();
+    if (!style)
+        style = const_cast<Element&>(*this).resolveComputedStyle(ResolveComputedStyleMode::RenderedOnly);
+
+    if (!style)
+        return false;
+
+    if (style->display() == DisplayType::None || style->display() == DisplayType::Contents)
+        return false;
+
+    if (style->visibility() != Visibility::Visible)
+        return false;
+
+    for (auto& element : ancestorsOfType<Element>(*this)) {
+        if (element.existingComputedStyle()->display() == DisplayType::None)
+            return false;
+    }
+
+    return true;
+}
+
 const RenderStyle& Element::resolvePseudoElementStyle(PseudoId pseudoElementSpecifier)
 {
     ASSERT(!isPseudoElement());
@@ -3349,7 +3387,7 @@
 
     auto* style = existingComputedStyle();
     if (!style)
-        style = &resolveComputedStyle();
+        style = resolveComputedStyle();
 
     if (pseudoElementSpecifier != PseudoId::None) {
         if (auto* cachedPseudoStyle = style->getCachedPseudoStyle(pseudoElementSpecifier))

Modified: trunk/Source/WebCore/dom/Element.h (257838 => 257839)


--- trunk/Source/WebCore/dom/Element.h	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/dom/Element.h	2020-03-04 12:11:13 UTC (rev 257839)
@@ -343,6 +343,9 @@
 
     bool needsStyleInvalidation() const;
 
+    bool hasValidStyle() const;
+    bool isVisibleWithoutResolvingFullStyle() const;
+
     // Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
     bool styleAffectedByActive() const { return hasStyleFlag(ElementStyleFlag::StyleAffectedByActive); }
     bool styleAffectedByEmpty() const { return hasStyleFlag(ElementStyleFlag::StyleAffectedByEmpty); }
@@ -692,7 +695,8 @@
 
     void removeShadowRoot();
 
-    const RenderStyle& resolveComputedStyle();
+    enum class ResolveComputedStyleMode { Normal, RenderedOnly };
+    const RenderStyle* resolveComputedStyle(ResolveComputedStyleMode = ResolveComputedStyleMode::Normal);
     const RenderStyle& resolvePseudoElementStyle(PseudoId);
 
     unsigned rareDataChildIndex() const;

Modified: trunk/Source/WebCore/editing/FrameSelection.cpp (257838 => 257839)


--- trunk/Source/WebCore/editing/FrameSelection.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/editing/FrameSelection.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -369,8 +369,13 @@
 
     setCaretRectNeedsUpdate();
 
-    if (!newSelection.isNone() && !(options & DoNotSetFocus))
+    if (!newSelection.isNone() && !(options & DoNotSetFocus)) {
+        auto* oldFocusedElement = m_frame->document()->focusedElement();
         setFocusedElementIfNeeded();
+        // FIXME: Should not be needed.
+        if (m_frame->document()->focusedElement() != oldFocusedElement)
+            m_frame->document()->updateStyleIfNeeded();
+    }
 
     // Always clear the x position used for vertical arrow navigation.
     // It will be restored by the vertical arrow navigation code if necessary.

Modified: trunk/Source/WebCore/html/HTMLAreaElement.cpp (257838 => 257839)


--- trunk/Source/WebCore/html/HTMLAreaElement.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/html/HTMLAreaElement.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -210,7 +210,7 @@
 bool HTMLAreaElement::isFocusable() const
 {
     RefPtr<HTMLImageElement> image = imageElement();
-    if (!image || !image->renderer() || image->renderer()->style().visibility() != Visibility::Visible)
+    if (!image || !image->isVisibleWithoutResolvingFullStyle())
         return false;
 
     return supportsFocus() && tabIndexSetExplicitly().valueOr(0) >= 0;

Modified: trunk/Source/WebCore/html/HTMLSelectElement.cpp (257838 => 257839)


--- trunk/Source/WebCore/html/HTMLSelectElement.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/html/HTMLSelectElement.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -1100,6 +1100,7 @@
     if (!isSpatialNavigationEnabled(document().frame())) {
         if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up") {
             focus();
+            document().updateStyleIfNeeded();
             // Calling focus() may cause us to lose our renderer. Return true so
             // that our caller doesn't process the event further, but don't set
             // the event as handled.
@@ -1198,6 +1199,7 @@
         if (RenderTheme::singleton().popsMenuBySpaceOrReturn()) {
             if (keyCode == ' ' || keyCode == '\r') {
                 focus();
+                document().updateStyleIfNeeded();
 
                 // Calling focus() may remove the renderer or change the renderer type.
                 auto* renderer = this->renderer();
@@ -1215,6 +1217,7 @@
         } else if (RenderTheme::singleton().popsMenuByArrowKeys()) {
             if (keyCode == ' ') {
                 focus();
+                document().updateStyleIfNeeded();
 
                 // Calling focus() may remove the renderer or change the renderer type.
                 auto* renderer = this->renderer();
@@ -1243,6 +1246,8 @@
     if (event.type() == eventNames().mousedownEvent && is<MouseEvent>(event) && downcast<MouseEvent>(event).button() == LeftButton) {
         focus();
 #if !PLATFORM(IOS_FAMILY)
+        document().updateStyleIfNeeded();
+
         auto* renderer = this->renderer();
         if (is<RenderMenuList>(renderer)) {
             auto& menuList = downcast<RenderMenuList>(*renderer);
@@ -1326,6 +1331,7 @@
 
     if (event.type() == eventNames().mousedownEvent && is<MouseEvent>(event) && downcast<MouseEvent>(event).button() == LeftButton) {
         focus();
+        document().updateStyleIfNeeded();
 
         // Calling focus() may remove or change our renderer, in which case we don't want to handle the event further.
         auto* renderer = this->renderer();

Modified: trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp (257838 => 257839)


--- trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/html/HTMLTextFormControlElement.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -242,8 +242,11 @@
 
     setInnerTextValue(text);
 
-    // FIXME: What should happen to the value (as in value()) if there's no renderer?
+    // FIXME: This shouldn't need synchronous style update, or renderer at all.
     if (!renderer())
+        document().updateStyleIfNeeded();
+
+    if (!renderer())
         return { };
 
     subtreeHasChanged();

Modified: trunk/Source/WebCore/html/shadow/SpinButtonElement.cpp (257838 => 257839)


--- trunk/Source/WebCore/html/shadow/SpinButtonElement.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/html/shadow/SpinButtonElement.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -157,9 +157,6 @@
 
 void SpinButtonElement::forwardEvent(Event& event)
 {
-    if (!renderBox())
-        return;
-
     if (!is<WheelEvent>(event))
         return;
 

Modified: trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp (257838 => 257839)


--- trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp	2020-03-04 11:47:32 UTC (rev 257838)
+++ trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp	2020-03-04 12:11:13 UTC (rev 257839)
@@ -225,6 +225,8 @@
         input->focus();
         input->select();
 #if !PLATFORM(IOS_FAMILY)
+        document().updateStyleIfNeeded();
+
         if (auto* renderer = input->renderer()) {
             auto& searchFieldRenderer = downcast<RenderSearchField>(*renderer);
             if (searchFieldRenderer.popupIsVisible())
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to