[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

victorw at chromium.org victorw at chromium.org
Thu Feb 4 21:32:49 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit 7c40131c0f52dd1f592b0b414fa412f1c2d58d35
Author: victorw at chromium.org <victorw at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Jan 29 23:39:41 2010 +0000

    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@54082 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 9ae4669..9492c16 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,26 @@
+2010-01-29  Victor Wang  <victorw at chromium.org>
+
+        Reviewed by darin at apple.com.
+
+        Fix the issue that both main frome and iframe are
+        focused if window.onblur calls window.focus.
+        https://bugs.webkit.org/show_bug.cgi?id=31692
+
+        The problem is caused by the focused frame in FocusController
+        is messed up if window.onblur calls window.focus:
+        When user clicks iframe to switch focus from main frame to iframe,
+        FocusController::setFocusedFrame fires onblur event, which calls
+        window.focus and then calls setFocusedFrame again to switch back.
+        This messes up the old focused frame and new focused frame and
+        leaves the FocusController confused. As a result, controlls
+        in both main frame and iframe look like get focused.
+
+        To fix it, add a flag to FocusController and do no switch the focused
+        frame when FocusController is in the middle of changing the focused frame. 
+
+        * fast/events/change-frame-focus-expected.txt: Added.
+        * fast/events/change-frame-focus.html: Added.
+
 2010-01-28  Jon Honeycutt  <jhoneycutt at apple.com>
 
         MSAA: Crash when posting a notification for a detached object
diff --git a/LayoutTests/fast/events/change-frame-focus-expected.txt b/LayoutTests/fast/events/change-frame-focus-expected.txt
new file mode 100644
index 0000000..82efc4e
--- /dev/null
+++ b/LayoutTests/fast/events/change-frame-focus-expected.txt
@@ -0,0 +1,55 @@
+  
+Test the focus controller working properly when switching focused frame. Here are the cases tested: 
+
+-. Correct frame is focused when switching focus from one frame to another: 
+1. main frame -> iframe 
+2. iframe to main frame 
+3. iframe 1 to iframe 2 
+
+-. New setting focus request will be ignored if the focus controller is in the middle of switching focused frame (onblur, onfocus events): 
+1. iframe 1 onblur sets iframe 2 focus. 
+2. iframe 1 onblur sets iframe 1 focus. 
+3. iframe 1 onfocus sets iframe 2 focus. 
+4. iframe 1 onfocus sets iframe 1 focus.
+
+
+Test: main frame to iframe.
+main frame blurred.
+iframe1 focused.
+
+Test: iframe to main frame.
+iframe1 blurred.
+main frame focused.
+
+Test: iframe1 to iframe2.
+main frame blurred.
+iframe1 focused.
+iframe1 blurred.
+iframe2 focused.
+iframe2 blurred.
+iframe1 focused.
+
+Test: iframe1 onblur sets iframe2 focus.
+iframe1 blurred.
+main frame focused.
+main frame blurred.
+iframe1 focused.
+iframe1 blurred.
+main frame focused.
+
+Test: iframe1 onblur sets iframe1 focus.
+main frame blurred.
+iframe1 focused.
+iframe1 blurred.
+main frame focused.
+
+Test: iframe1 onfocus sets iframe2 focus.
+main frame blurred.
+iframe1 focused.
+
+Test: iframe1 onfocus sets iframe1 focus.
+iframe1 blurred.
+main frame focused.
+main frame blurred.
+iframe1 focused.
+
diff --git a/LayoutTests/fast/events/change-frame-focus.html b/LayoutTests/fast/events/change-frame-focus.html
new file mode 100755
index 0000000..4bbabaf
--- /dev/null
+++ b/LayoutTests/fast/events/change-frame-focus.html
@@ -0,0 +1,201 @@
+<html>
+<head>
+    <script>
+        function log(msg)
+        {
+            document.getElementById("log").appendChild(
+                document.createTextNode(msg + "\n"));
+        }
+        
+        function setFrameHandler(frameId)
+        {
+            if (frameId == "") {
+                window.onfocus = function()
+                {
+                    log("main frame focused.");
+                }
+            
+                window.onblur = function()
+                {
+                    log("main frame blurred.");
+                }
+            } else {
+                var frameWin = document.getElementById(frameId).contentWindow;
+                frameWin.onfocus = function()
+                {
+                    log(frameId + " focused.");
+                }
+
+                frameWin.onblur = function()
+                {
+                    log(frameId + " blurred.");
+                }
+            }
+        }
+
+        function setFrameFocus(frameId)
+        {
+            if (frameId == "") {
+                window.focus();
+            } else {
+                var frameWin = document.getElementById(frameId).contentWindow;
+                frameWin.focus();
+            }
+        }
+
+        function testMainFrameToIFrameFocus()
+        {
+            log("\nTest: main frame to iframe.");
+            setFrameFocus("");
+            setFrameFocus("iframe1");
+        }
+
+        function testIFrameToMainFrameFocus()
+        {
+            log("\nTest: iframe to main frame.");
+            setFrameFocus("iframe1");
+            setFrameFocus("");
+        }
+
+        function testIFrameToIFrameFocus()
+        {
+            log("\nTest: iframe1 to iframe2.");
+            setFrameFocus("iframe1");
+            setFrameFocus("iframe2");
+            setFrameFocus("iframe1");
+        }
+
+        function testFrame1OnBlurSetFrame2Focus()
+        {
+            var frameWin1 = document.getElementById("iframe1").contentWindow;
+            frameWin1.onfocus = function()
+            {
+                log("iframe1 focused.");
+            }
+
+            frameWin1.onblur = function()
+            {
+                log("iframe1 blurred.");
+                // This set focus request will be ignored because the FocusController
+                // is in the middle of changing focused frame.
+                setFrameFocus("iframe2");
+            }
+
+            log("\nTest: iframe1 onblur sets iframe2 focus.");
+            setFrameFocus("");
+            setFrameFocus("iframe1");
+            setFrameFocus("");
+        }
+
+        function testFrame1OnBlurSetFrame1Focus()
+        {
+            var frameWin1 = document.getElementById("iframe1").contentWindow;
+            frameWin1.onfocus = function()
+            {
+                log("iframe1 focused.");
+            }
+
+            frameWin1.onblur = function()
+            {
+                log("iframe1 blurred.");
+                // This set focus request will be ignored because the FocusController
+                // is in the middle of changing focused frame.
+                setFrameFocus("iframe1");
+            }
+
+            log("\nTest: iframe1 onblur sets iframe1 focus.");
+            setFrameFocus("");
+            setFrameFocus("iframe1");
+            setFrameFocus("");
+        }
+
+        function testFrame1OnFocusSetFrame2Focus()
+        {
+            var frameWin1 = document.getElementById("iframe1").contentWindow;
+            frameWin1.onfocus = function()
+            {
+                log("iframe1 focused.");
+                // This set focus request will be ignored because the FocusController
+                // is in the middle of changing focused frame.
+                setFrameFocus("iframe2");
+            }
+
+            frameWin1.onblur = function()
+            {
+                log("iframe1 blurred.");
+            }
+
+            log("\nTest: iframe1 onfocus sets iframe2 focus.");
+            setFrameFocus("");
+            setFrameFocus("iframe1");
+        }
+
+        function testFrame1OnFocusSetFrame1Focus()
+        {
+            var frameWin1 = document.getElementById("iframe1").contentWindow;
+            frameWin1.onfocus = function()
+            {
+                log("iframe1 focused.");
+                // This set focus request will be ignored because the FocusController
+                // is in the middle of changing focused frame.
+                setFrameFocus("iframe1");
+            }
+
+            frameWin1.onblur = function()
+            {
+                log("iframe1 blurred.");
+            }
+
+            log("\nTest: iframe1 onfocus sets iframe1 focus.");
+            setFrameFocus("");
+            setFrameFocus("iframe1");
+        }
+
+        function test()
+        {
+            if (window.layoutTestController) {
+                layoutTestController.dumpAsText();
+            }
+
+            setFrameHandler("");
+            setFrameHandler("iframe1");
+            setFrameHandler("iframe2");
+
+            // Test the correct frame is focused when switching focus from
+            // one frame to another.
+            testMainFrameToIFrameFocus();
+            testIFrameToMainFrameFocus();
+            testIFrameToIFrameFocus();
+            
+            // New setting focus request will be ignored if the focus controller
+            // is in the middle of switching focused frame (onblur, onfocus events).
+            testFrame1OnBlurSetFrame2Focus();
+            testFrame1OnBlurSetFrame1Focus();
+            testFrame1OnFocusSetFrame2Focus();
+            testFrame1OnFocusSetFrame1Focus();
+            
+            // Restore iframe1 onfocus and onblur handlers.
+            setFrameHandler("iframe1");
+        }
+
+    </script>
+</head>
+<body onload="test()">
+    <iframe id="iframe1" style="width: 100px; height: 100px;"></iframe>
+    <iframe id="iframe2" style="width: 100px; height: 100px;"></iframe>
+    <p>Test the focus controller working properly when switching focused frame. Here are the cases tested:
+    <br>
+    <br>-. Correct frame is focused when switching focus from one frame to another:
+    <br>1. main frame -> iframe
+    <br>2. iframe to main frame
+    <br>3. iframe 1 to iframe 2
+    <br>
+    <br>-. New setting focus request will be ignored if the focus controller is in the middle of switching focused frame (onblur, onfocus events):
+    <br>1. iframe 1 onblur sets iframe 2 focus.
+    <br>2. iframe 1 onblur sets iframe 1 focus.
+    <br>3. iframe 1 onfocus sets iframe 2 focus.
+    <br>4. iframe 1 onfocus sets iframe 1 focus.
+    </p>
+    <pre id="log"></pre>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 9529bc7..e3dfaf9 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,33 @@
+2010-01-29  Victor Wang  <victorw at chromium.org>
+
+        Reviewed by darin at apple.com.
+
+        Fix the issue that both main frome and iframe are
+        focused if window.onblur calls window.focus.
+        https://bugs.webkit.org/show_bug.cgi?id=31692
+
+        The problem is caused by the focused frame in FocusController
+        is messed up if window.onblur calls window.focus:
+        When user clicks iframe to switch focus from main frame to iframe,
+        FocusController::setFocusedFrame fires onblur event, which calls
+        window.focus and then calls setFocusedFrame again to switch back.
+        This messes up the old focused frame and new focused frame and
+        leaves the FocusController confused. As a result, controlls
+        in both main frame and iframe look like get focused.
+
+        To fix it, add a flag to FocusController and do no switch the focused
+        frame when FocusController is in the middle of changing the focused frame. 
+
+        Test: fast/events/change-frame-focus.html
+
+        * page/FocusController.cpp:
+        (WebCore::FocusController::FocusController):
+        (WebCore::FocusController::setFocusedFrame):
+        * page/FocusController.h:
+        (WebCore::FocusController::focusedFrame):
+        (WebCore::FocusController::isActive):
+        (WebCore::FocusController::isFocused):
+
 2010-01-29  Alexey Proskuryakov  <ap at apple.com>
 
         Reviewed by Dan Bernstein.
diff --git a/WebCore/page/FocusController.cpp b/WebCore/page/FocusController.cpp
index 5e78c7d..bdd3151 100644
--- a/WebCore/page/FocusController.cpp
+++ b/WebCore/page/FocusController.cpp
@@ -38,8 +38,8 @@
 #include "EventNames.h"
 #include "ExceptionCode.h"
 #include "Frame.h"
-#include "FrameView.h"
 #include "FrameTree.h"
+#include "FrameView.h"
 #include "HTMLFrameOwnerElement.h"
 #include "HTMLNames.h"
 #include "KeyboardEvent.h"
@@ -72,14 +72,17 @@ FocusController::FocusController(Page* page)
     : m_page(page)
     , m_isActive(false)
     , m_isFocused(false)
+    , m_isChangingFocusedFrame(false)
 {
 }
 
 void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
 {
-    if (m_focusedFrame == frame)
+    if (m_focusedFrame == frame || m_isChangingFocusedFrame)
         return;
 
+    m_isChangingFocusedFrame = true;
+
     RefPtr<Frame> oldFrame = m_focusedFrame;
     RefPtr<Frame> newFrame = frame;
 
@@ -95,6 +98,8 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
         newFrame->selection()->setFocused(true);
         newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false));
     }
+
+    m_isChangingFocusedFrame = false;
 }
 
 Frame* FocusController::focusedOrMainFrame()
diff --git a/WebCore/page/FocusController.h b/WebCore/page/FocusController.h
index d86408a..32d4060 100644
--- a/WebCore/page/FocusController.h
+++ b/WebCore/page/FocusController.h
@@ -33,36 +33,37 @@
 
 namespace WebCore {
 
-    class Frame;
-    class KeyboardEvent;
-    class Node;
-    class Page;
+class Frame;
+class KeyboardEvent;
+class Node;
+class Page;
 
-    class FocusController : public Noncopyable {
-    public:
-        FocusController(Page*);
+class FocusController : public Noncopyable {
+public:
+    FocusController(Page*);
 
-        void setFocusedFrame(PassRefPtr<Frame>);
-        Frame* focusedFrame() const { return m_focusedFrame.get(); }
-        Frame* focusedOrMainFrame();
+    void setFocusedFrame(PassRefPtr<Frame>);
+    Frame* focusedFrame() const { return m_focusedFrame.get(); }
+    Frame* focusedOrMainFrame();
 
-        bool setInitialFocus(FocusDirection, KeyboardEvent*);
-        bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false);
+    bool setInitialFocus(FocusDirection, KeyboardEvent*);
+    bool advanceFocus(FocusDirection, KeyboardEvent*, bool initialFocus = false);
         
-        bool setFocusedNode(Node*, PassRefPtr<Frame>);
+    bool setFocusedNode(Node*, PassRefPtr<Frame>);
 
-        void setActive(bool);
-        bool isActive() const { return m_isActive; }
+    void setActive(bool);
+    bool isActive() const { return m_isActive; }
 
-        void setFocused(bool);
-        bool isFocused() const { return m_isFocused; }
+    void setFocused(bool);
+    bool isFocused() const { return m_isFocused; }
 
-    private:
-        Page* m_page;
-        RefPtr<Frame> m_focusedFrame;
-        bool m_isActive;
-        bool m_isFocused;
-    };
+private:
+    Page* m_page;
+    RefPtr<Frame> m_focusedFrame;
+    bool m_isActive;
+    bool m_isFocused;
+    bool m_isChangingFocusedFrame;
+};
 
 } // namespace WebCore
     

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list