Skip to content
  • aestes@apple.com's avatar
    d7e71b72
    Focusing a new frame (via window.focus()) should blur the active element in the current frame · d7e71b72
    aestes@apple.com authored
    https://bugs.webkit.org/show_bug.cgi?id=110172
    
    Reviewed by Ryosuke Niwa.
    
    Source/WebCore:
    
    When a change in the focused node crosses a frame boundary, WebKit
    doesn't always succeed in blurring the old focused node before focusing
    the new one.
    
    Each document remembers its focused node, and a Page-scoped
    FocusController remembers the focused frame. If a new focused node is
    in a different frame than the focused frame, FocusController tells the
    old frame's document to clear its focused node before focusing the new
    one (and remembering the new frame).
    
    Unfortunately, web content can confuse FocusController by calling
    window.focus() at the wrong time. Since window.focus() changes
    FocusController's focused frame without focusing a new node,
    FocusController won't think that a frame boundary is being crossed if a
    node in this frame is later focused. Therefore it won't clear the old
    frame's focused node (it won't even know which frame contained the old
    focused node), causing at least two bugs:
    
    1) The node in the old frame will not receive a blur event.
    2) Calling document.activeElement on the main frame will return the
       previously focused node, but the HTML5 spec says it should return
       the frame owner element if a subframe has focus.
    
    Fix both of these bugs by explicitly clearing the current frame's
    focused node if window.focus() changes the focused frame. This fix
    carries some compatibility risk by changing a long-standing behavior
    of the engine (we've had this bug since the beginning of the project,
    AFAICT). On the upside, it matches the behavior of both Firefox and IE,
    matches what HTML5 says about subframe focus, and fixes at least one
    well-known enterprise web app.
    
    Tests: fast/dom/HTMLDocument/active-element-frames.html
           fast/frames/frame-focus-blurs-active-element.html
    
    * page/DOMWindow.cpp:
    (WebCore::DOMWindow::focus): If the frame being focused is not the same
    as the currently focused frame, clear the currently focused frame's
    focused node.
    
    LayoutTests:
    
    * fast/dom/HTMLDocument/active-element-frames-expected.txt:
    * fast/dom/HTMLDocument/active-element-frames.html: Modified to run the
    test a second time, focusing each element's frame before focusing the
    element itself.
    * fast/frames/frame-focus-blurs-active-element-expected.txt: Added.
    * fast/frames/frame-focus-blurs-active-element.html: Added a test that
    verifies a blur event is fired on the active element when a new frame
    is focused.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143299 268f45cc-cd09-0410-ab3c-d52691b4dbfc
    d7e71b72
    Focusing a new frame (via window.focus()) should blur the active element in the current frame
    aestes@apple.com authored
    https://bugs.webkit.org/show_bug.cgi?id=110172
    
    Reviewed by Ryosuke Niwa.
    
    Source/WebCore:
    
    When a change in the focused node crosses a frame boundary, WebKit
    doesn't always succeed in blurring the old focused node before focusing
    the new one.
    
    Each document remembers its focused node, and a Page-scoped
    FocusController remembers the focused frame. If a new focused node is
    in a different frame than the focused frame, FocusController tells the
    old frame's document to clear its focused node before focusing the new
    one (and remembering the new frame).
    
    Unfortunately, web content can confuse FocusController by calling
    window.focus() at the wrong time. Since window.focus() changes
    FocusController's focused frame without focusing a new node,
    FocusController won't think that a frame boundary is being crossed if a
    node in this frame is later focused. Therefore it won't clear the old
    frame's focused node (it won't even know which frame contained the old
    focused node), causing at least two bugs:
    
    1) The node in the old frame will not receive a blur event.
    2) Calling document.activeElement on the main frame will return the
       previously focused node, but the HTML5 spec says it should return
       the frame owner element if a subframe has focus.
    
    Fix both of these bugs by explicitly clearing the current frame's
    focused node if window.focus() changes the focused frame. This fix
    carries some compatibility risk by changing a long-standing behavior
    of the engine (we've had this bug since the beginning of the project,
    AFAICT). On the upside, it matches the behavior of both Firefox and IE,
    matches what HTML5 says about subframe focus, and fixes at least one
    well-known enterprise web app.
    
    Tests: fast/dom/HTMLDocument/active-element-frames.html
           fast/frames/frame-focus-blurs-active-element.html
    
    * page/DOMWindow.cpp:
    (WebCore::DOMWindow::focus): If the frame being focused is not the same
    as the currently focused frame, clear the currently focused frame's
    focused node.
    
    LayoutTests:
    
    * fast/dom/HTMLDocument/active-element-frames-expected.txt:
    * fast/dom/HTMLDocument/active-element-frames.html: Modified to run the
    test a second time, focusing each element's frame before focusing the
    element itself.
    * fast/frames/frame-focus-blurs-active-element-expected.txt: Added.
    * fast/frames/frame-focus-blurs-active-element.html: Added a test that
    verifies a blur event is fired on the active element when a new frame
    is focused.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143299 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Loading