Title: [156252] trunk
Revision
156252
Author
[email protected]
Date
2013-09-22 16:19:14 -0700 (Sun, 22 Sep 2013)

Log Message

Hiding a focused element should unfocus it and fire a blur event
https://bugs.webkit.org/show_bug.cgi?id=29241

Patch by Arunprasad Rajkumar <[email protected]> on 2013-09-22
Reviewed by Darin Adler.

Source/WebCore:

Test: fast/dom/HTMLDocument/active-element-gets-unfocusable.html

We check whether the current focus element is really focusable after
the style recalculation and layout change. If it is not focusable then schedule a
timer to reset it asynchronously.

* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::recalcStyle): Check isFocusable() on the focus element after
style recalculation.
(WebCore::Document::updateLayout): Check isFocusable() on the focus element after
layout.
(WebCore::Document::resetHiddenFocusElementSoon):
(WebCore::Document::resetHiddenFocusElementTimer):
* dom/Document.h:

LayoutTests:

* fast/dom/HTMLDocument/active-element-gets-unfocusable-expected.txt: Added.
* fast/dom/HTMLDocument/active-element-gets-unfocusable.html: Added.

LayoutTest reused from https://chromium.googlesource.com/chromium/blink/+/c58f636fd18fc27944c42e27d6a92a36867c57e1
with little modification.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (156251 => 156252)


--- trunk/LayoutTests/ChangeLog	2013-09-22 22:11:37 UTC (rev 156251)
+++ trunk/LayoutTests/ChangeLog	2013-09-22 23:19:14 UTC (rev 156252)
@@ -1,3 +1,16 @@
+2013-09-22  Arunprasad Rajkumar  <[email protected]>
+
+        Hiding a focused element should unfocus it and fire a blur event
+        https://bugs.webkit.org/show_bug.cgi?id=29241
+
+        Reviewed by Darin Adler.
+
+        * fast/dom/HTMLDocument/active-element-gets-unfocusable-expected.txt: Added.
+        * fast/dom/HTMLDocument/active-element-gets-unfocusable.html: Added.
+
+        LayoutTest reused from https://chromium.googlesource.com/chromium/blink/+/c58f636fd18fc27944c42e27d6a92a36867c57e1
+        with little modification.
+
 2013-09-22  Darin Adler  <[email protected]>
 
         Fix accessibility-node-memory-management.html to use normal style for

Added: trunk/LayoutTests/fast/dom/HTMLDocument/active-element-gets-unfocusable-expected.txt (0 => 156252)


--- trunk/LayoutTests/fast/dom/HTMLDocument/active-element-gets-unfocusable-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDocument/active-element-gets-unfocusable-expected.txt	2013-09-22 23:19:14 UTC (rev 156252)
@@ -0,0 +1,19 @@
+Making a focused element invisible should make it blur.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+===> Setting display:none
+Event: blur
+PASS document.activeElement is document.body
+PASS The focusTarget element lost focus.
+
+===> Setting visibility:hidden
+Event: blur
+PASS document.activeElement is document.body
+PASS The focusTarget element lost focus.
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/HTMLDocument/active-element-gets-unfocusable.html (0 => 156252)


--- trunk/LayoutTests/fast/dom/HTMLDocument/active-element-gets-unfocusable.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/HTMLDocument/active-element-gets-unfocusable.html	2013-09-22 23:19:14 UTC (rev 156252)
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<body>
+<script src=""
+
+<div id="f1">
+  <div tabindex="1" id="div1"></div>
+</div>
+
+<script type="text/_javascript_">
+description('Making a focused element invisible should make it blur.');
+jsTestIsAsync = true;
+var focusTarget = document.getElementById('div1');
+var testStage = 0;
+var testTimeout = 0;
+
+document.body._onload_ = function() {
+    focusTarget.focus();
+
+    shouldBe('document.activeElement', 'focusTarget', true);
+    debug('===> Setting display:none');
+    setTimeout("f1.style.display = 'none'",0);
+
+    testTimeout = setTimeout(function() {
+        testFailed('Timeout: Didn\'t loose focus.');
+        finishJSTest();
+    }, 1000);
+};
+
+focusTarget.addEventListener('blur', function() {
+    debug('Event: blur');
+    shouldBe('document.activeElement', 'document.body');
+    testPassed('The focusTarget element lost focus.');
+
+    debug('');
+    if (testStage++ == 0) {
+        f1.style.display = 'block';
+        focusTarget.focus();
+        shouldBe('document.activeElement', 'focusTarget', true);
+        debug('===> Setting visibility:hidden');
+        setTimeout("f1.style.visibility = 'hidden'",0);
+    } else {
+        clearTimeout(testTimeout);
+        finishJSTest();
+    }
+}, false);
+
+</script>
+<script src=""
+</body>

Modified: trunk/Source/WebCore/ChangeLog (156251 => 156252)


--- trunk/Source/WebCore/ChangeLog	2013-09-22 22:11:37 UTC (rev 156251)
+++ trunk/Source/WebCore/ChangeLog	2013-09-22 23:19:14 UTC (rev 156252)
@@ -1,3 +1,26 @@
+2013-09-22  Arunprasad Rajkumar  <[email protected]>
+
+        Hiding a focused element should unfocus it and fire a blur event
+        https://bugs.webkit.org/show_bug.cgi?id=29241
+
+        Reviewed by Darin Adler.
+
+        Test: fast/dom/HTMLDocument/active-element-gets-unfocusable.html
+
+        We check whether the current focus element is really focusable after
+        the style recalculation and layout change. If it is not focusable then schedule a
+        timer to reset it asynchronously.
+
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::recalcStyle): Check isFocusable() on the focus element after
+        style recalculation.
+        (WebCore::Document::updateLayout): Check isFocusable() on the focus element after
+        layout.
+        (WebCore::Document::resetHiddenFocusElementSoon):
+        (WebCore::Document::resetHiddenFocusElementTimer):
+        * dom/Document.h:
+
 2013-09-22  Sam Weinig  <[email protected]>
 
         CTTE: StaticNodeLists often contain only Elements, we shouldn't store them as Vector<RefPtr<Node>> in those cases

Modified: trunk/Source/WebCore/dom/Document.cpp (156251 => 156252)


--- trunk/Source/WebCore/dom/Document.cpp	2013-09-22 22:11:37 UTC (rev 156251)
+++ trunk/Source/WebCore/dom/Document.cpp	2013-09-22 23:19:14 UTC (rev 156252)
@@ -440,6 +440,7 @@
     , m_titleSetExplicitly(false)
     , m_markers(adoptPtr(new DocumentMarkerController))
     , m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
+    , m_resetHiddenFocusElementTimer(this, &Document::resetHiddenFocusElementTimer)
     , m_cssTarget(0)
     , m_processingLoadEvent(false)
     , m_loadEventFinished(false)
@@ -1828,6 +1829,9 @@
     // to check if any other elements ended up under the mouse pointer due to re-layout.
     if (m_hoveredElement && !m_hoveredElement->renderer())
         frameView.frame().eventHandler().dispatchFakeMouseMoveEventSoon();
+
+    // Style change may reset the focus, e.g. display: none, visibility: hidden.
+    resetHiddenFocusElementSoon();
 }
 
 void Document::updateStyleIfNeeded()
@@ -1866,6 +1870,9 @@
     // Only do a layout if changes have occurred that make it necessary.      
     if (frameView && renderView() && (frameView->layoutPending() || renderView()->needsLayout()))
         frameView->layout();
+
+    // Active focus element's isFocusable() state may change after Layout. e.g. width: 0px or height: 0px.
+    resetHiddenFocusElementSoon();
 }
 
 // FIXME: This is a bad idea and needs to be removed eventually.
@@ -4690,6 +4697,12 @@
     m_updateFocusAppearanceTimer.stop();
 }
 
+void Document::resetHiddenFocusElementSoon()
+{
+    if (!m_resetHiddenFocusElementTimer.isActive() && m_focusedElement)
+        m_resetHiddenFocusElementTimer.startOneShot(0);
+}
+
 void Document::updateFocusAppearanceTimerFired(Timer<Document>*)
 {
     Element* element = focusedElement();
@@ -4701,6 +4714,15 @@
         element->updateFocusAppearance(m_updateFocusAppearanceRestoresSelection);
 }
 
+void Document::resetHiddenFocusElementTimer(Timer<Document>*)
+{
+    if (view() && view()->needsLayout())
+        return;
+
+    if (m_focusedElement && !m_focusedElement->isFocusable())
+        setFocusedElement(0);
+}
+
 void Document::attachRange(Range* range)
 {
     ASSERT(!m_ranges.contains(range));

Modified: trunk/Source/WebCore/dom/Document.h (156251 => 156252)


--- trunk/Source/WebCore/dom/Document.h	2013-09-22 22:11:37 UTC (rev 156251)
+++ trunk/Source/WebCore/dom/Document.h	2013-09-22 23:19:14 UTC (rev 156252)
@@ -919,7 +919,9 @@
 
     void updateFocusAppearanceSoon(bool restorePreviousSelection);
     void cancelFocusAppearanceUpdate();
-        
+
+    void resetHiddenFocusElementSoon();
+
     // Extension for manipulating canvas drawing contexts for use in CSS
     CanvasRenderingContext* getCSSCanvasContext(const String& type, const String& name, int width, int height);
     HTMLCanvasElement* getCSSCanvasElement(const String& name);
@@ -1226,6 +1228,8 @@
     void updateFocusAppearanceTimerFired(Timer<Document>*);
     void updateBaseURL();
 
+    void resetHiddenFocusElementTimer(Timer<Document>*);
+
     void buildAccessKeyMap(TreeScope* root);
 
     void createStyleResolver();
@@ -1377,6 +1381,7 @@
     const OwnPtr<DocumentMarkerController> m_markers;
     
     Timer<Document> m_updateFocusAppearanceTimer;
+    Timer<Document> m_resetHiddenFocusElementTimer;
 
     Element* m_cssTarget;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to