Title: [222230] branches/safari-604-branch

Diff

Modified: branches/safari-604-branch/LayoutTests/ChangeLog (222229 => 222230)


--- branches/safari-604-branch/LayoutTests/ChangeLog	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/LayoutTests/ChangeLog	2017-09-19 22:25:47 UTC (rev 222230)
@@ -1,3 +1,20 @@
+2017-09-19  Jason Marcell  <[email protected]>
+
+        Cherry-pick r222114. rdar://problem/34508510
+
+    2017-09-15  Wenson Hsieh  <[email protected]>
+
+            Avoid style recomputation when forwarding a focus event to an text field's input type
+            https://bugs.webkit.org/show_bug.cgi?id=176160
+            <rdar://problem/34184820>
+
+            Reviewed by Ryosuke Niwa.
+
+            Adds a new layout test verifying that we don't crash when changing the input type from within a focus event listener.
+
+            * fast/forms/change-input-type-in-focus-handler-expected.txt: Added.
+            * fast/forms/change-input-type-in-focus-handler.html: Added.
+
 2017-09-14  Jason Marcell  <[email protected]>
 
         Cherry-pick r222008. rdar://problem/34426473

Added: branches/safari-604-branch/LayoutTests/fast/forms/change-input-type-in-focus-handler-expected.txt (0 => 222230)


--- branches/safari-604-branch/LayoutTests/fast/forms/change-input-type-in-focus-handler-expected.txt	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/forms/change-input-type-in-focus-handler-expected.txt	2017-09-19 22:25:47 UTC (rev 222230)
@@ -0,0 +1 @@
+PASS

Added: branches/safari-604-branch/LayoutTests/fast/forms/change-input-type-in-focus-handler.html (0 => 222230)


--- branches/safari-604-branch/LayoutTests/fast/forms/change-input-type-in-focus-handler.html	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/forms/change-input-type-in-focus-handler.html	2017-09-19 22:25:47 UTC (rev 222230)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<div id="div">
+    <form id="form">
+        <input id="input" _onfocus_="focused()" type="tel"></input>
+    </form>
+</div>
+
+<script>
+function focused() {
+    if (input.autofocus) {
+        input.type = "checkbox";
+        document.body.innerHTML = "<code style='color: green'>PASS</code>";
+        return;
+    }
+
+    document.body.appendChild(input);
+    input.autofocus = true;
+}
+
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+input.focus();
+</script>
+</html>
\ No newline at end of file

Modified: branches/safari-604-branch/Source/WebCore/ChangeLog (222229 => 222230)


--- branches/safari-604-branch/Source/WebCore/ChangeLog	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/Source/WebCore/ChangeLog	2017-09-19 22:25:47 UTC (rev 222230)
@@ -1,3 +1,40 @@
+2017-09-19  Jason Marcell  <[email protected]>
+
+        Cherry-pick r222114. rdar://problem/34508510
+
+    2017-09-15  Wenson Hsieh  <[email protected]>
+
+            Avoid style recomputation when forwarding a focus event to an text field's input type
+            https://bugs.webkit.org/show_bug.cgi?id=176160
+            <rdar://problem/34184820>
+
+            Reviewed by Ryosuke Niwa.
+
+            Currently, TextFieldInputType::forwardEvent synchronously triggers style recomputation, for the purpose of
+            scrolling to the origin upon handling a blur event, and also for updating caps lock state after a blur or focus.
+            In synchronously triggering style recomputation, we may end up running arbitrary _javascript_, which may change
+            the HTMLInputElement's type and cause the current TextFieldInputType to be destroyed.
+
+            To mitigate this, we only update caps lock state when forwarding a focus or blur event to the InputType, and
+            instead scroll blurred text fields to the origin later, in HTMLInputElement::didBlur (invoked from
+            Document::setFocusedElement after blur and focusout events have fired). Instead of having the InputType update
+            style, lift the call to Document::updateStyleIfNeeded up into HTMLInputElement so that we gracefully handle the
+            case where the page destroys and sets a new InputType within the scope of this style update.
+
+            Test: fast/forms/change-input-type-in-focus-handler.html
+
+            * dom/Document.cpp:
+            (WebCore::Document::setFocusedElement):
+            * html/HTMLInputElement.cpp:
+            (WebCore::HTMLInputElement::didBlur):
+            * html/HTMLInputElement.h:
+            * html/InputType.h:
+            (WebCore::InputType::elementDidBlur):
+            * html/TextFieldInputType.cpp:
+            (WebCore::TextFieldInputType::forwardEvent):
+            (WebCore::TextFieldInputType::elementDidBlur):
+            * html/TextFieldInputType.h:
+
 2017-09-14  Jason Marcell  <[email protected]>
 
         Cherry-pick r222008. rdar://problem/34426473

Modified: branches/safari-604-branch/Source/WebCore/dom/Document.cpp (222229 => 222230)


--- branches/safari-604-branch/Source/WebCore/dom/Document.cpp	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/Source/WebCore/dom/Document.cpp	2017-09-19 22:25:47 UTC (rev 222230)
@@ -3797,6 +3797,9 @@
             else
                 view()->setFocus(false);
         }
+
+        if (is<HTMLInputElement>(oldFocusedElement.get()))
+            downcast<HTMLInputElement>(*oldFocusedElement).didBlur();
     }
 
     if (newFocusedElement && newFocusedElement->isFocusable()) {

Modified: branches/safari-604-branch/Source/WebCore/html/HTMLInputElement.cpp (222229 => 222230)


--- branches/safari-604-branch/Source/WebCore/html/HTMLInputElement.cpp	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/Source/WebCore/html/HTMLInputElement.cpp	2017-09-19 22:25:47 UTC (rev 222230)
@@ -1117,6 +1117,14 @@
     m_inputType->didDispatchClick(&event, state);
 }
 
+void HTMLInputElement::didBlur()
+{
+    // We need to update style here, rather than in InputType itself, since style recomputation may fire events
+    // that could change the input's type.
+    document().updateStyleIfNeeded();
+    m_inputType->elementDidBlur();
+}
+
 void HTMLInputElement::defaultEventHandler(Event& event)
 {
     if (is<MouseEvent>(event) && event.type() == eventNames().clickEvent && downcast<MouseEvent>(event).button() == LeftButton) {

Modified: branches/safari-604-branch/Source/WebCore/html/HTMLInputElement.h (222229 => 222230)


--- branches/safari-604-branch/Source/WebCore/html/HTMLInputElement.h	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/Source/WebCore/html/HTMLInputElement.h	2017-09-19 22:25:47 UTC (rev 222230)
@@ -213,6 +213,8 @@
     void willDispatchEvent(Event&, InputElementClickState&);
     void didDispatchClickEvent(Event&, const InputElementClickState&);
 
+    void didBlur();
+
     int maxResults() const { return m_maxResults; }
 
     WEBCORE_EXPORT String defaultValue() const;

Modified: branches/safari-604-branch/Source/WebCore/html/InputType.h (222229 => 222230)


--- branches/safari-604-branch/Source/WebCore/html/InputType.h	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/Source/WebCore/html/InputType.h	2017-09-19 22:25:47 UTC (rev 222230)
@@ -203,6 +203,8 @@
     virtual void subtreeHasChanged();
     virtual void blur();
 
+    virtual void elementDidBlur() { }
+
 #if ENABLE(TOUCH_EVENTS)
     virtual bool hasTouchEventHandler() const;
 #endif

Modified: branches/safari-604-branch/Source/WebCore/html/TextFieldInputType.cpp (222229 => 222230)


--- branches/safari-604-branch/Source/WebCore/html/TextFieldInputType.cpp	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/Source/WebCore/html/TextFieldInputType.cpp	2017-09-19 22:25:47 UTC (rev 222230)
@@ -188,29 +188,31 @@
             return;
     }
 
-    if (event.isMouseEvent()
-        || event.type() == eventNames().blurEvent
-        || event.type() == eventNames().focusEvent)
-    {
-        element().document().updateStyleIfNeeded();
+    bool isFocusEvent = event.type() == eventNames().focusEvent;
+    bool isBlurEvent = event.type() == eventNames().blurEvent;
+    if (isFocusEvent || isBlurEvent)
+        capsLockStateMayHaveChanged();
+    if (event.isMouseEvent() || isFocusEvent || isBlurEvent)
+        element().forwardEvent(event);
+}
 
-        auto* renderer = element().renderer();
-        if (element().renderer()) {
-            if (event.type() == eventNames().blurEvent) {
-                if (auto* innerTextRenderer = innerTextElement()->renderer()) {
-                    if (auto* innerLayer = innerTextRenderer->layer()) {
-                        bool isLeftToRightDirection = downcast<RenderTextControlSingleLine>(*renderer).style().isLeftToRightDirection();
-                        ScrollOffset scrollOffset(isLeftToRightDirection ? 0 : innerLayer->scrollWidth(), 0);
-                        innerLayer->scrollToOffset(scrollOffset, RenderLayer::ScrollOffsetClamped);
-                    }
-                }
-                capsLockStateMayHaveChanged();
-            } else if (event.type() == eventNames().focusEvent)
-                capsLockStateMayHaveChanged();
+void TextFieldInputType::elementDidBlur()
+{
+    auto* renderer = element().renderer();
+    if (!renderer)
+        return;
 
-            element().forwardEvent(event);
-        }
-    }
+    auto* innerTextRenderer = innerTextElement()->renderer();
+    if (!innerTextRenderer)
+        return;
+
+    auto* innerLayer = innerTextRenderer->layer();
+    if (!innerLayer)
+        return;
+
+    bool isLeftToRightDirection = downcast<RenderTextControlSingleLine>(*renderer).style().isLeftToRightDirection();
+    ScrollOffset scrollOffset(isLeftToRightDirection ? 0 : innerLayer->scrollWidth(), 0);
+    innerLayer->scrollToOffset(scrollOffset, RenderLayer::ScrollOffsetClamped);
 }
 
 void TextFieldInputType::handleFocusEvent(Node* oldFocusedNode, FocusDirection)

Modified: branches/safari-604-branch/Source/WebCore/html/TextFieldInputType.h (222229 => 222230)


--- branches/safari-604-branch/Source/WebCore/html/TextFieldInputType.h	2017-09-19 22:17:58 UTC (rev 222229)
+++ branches/safari-604-branch/Source/WebCore/html/TextFieldInputType.h	2017-09-19 22:25:47 UTC (rev 222230)
@@ -90,6 +90,7 @@
     void subtreeHasChanged() final;
     void capsLockStateMayHaveChanged() final;
     void updateAutoFillButton() final;
+    void elementDidBlur() final;
 
     // SpinButtonElement::SpinButtonOwner functions.
     void focusAndSelectSpinButtonOwner() final;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to