Changeset 21467 in webkit


Ignore:
Timestamp:
May 14, 2007 2:37:04 PM (17 years ago)
Author:
justing
Message:

LayoutTests:

Reviewed by darin


<rdar://problem/5136696> Selection is removed when focusing a node in another frame

Demonstrates bug:

  • editing/selection/5136696-expected.checksum: Added.
  • editing/selection/5136696-expected.png: Added.
  • editing/selection/5136696-expected.txt: Added.
  • editing/selection/5136696.html: Added.

WebCore:

Reviewed by darin


<rdar://problem/5136696> Selection is removed when focusing a node in another frame
<rdar://problem/5192388> WordPress: Can't insert links/images


Don't clear a selection when changing focus if the new
focus node is in a different frame than the old selection.

  • dom/Document.cpp: (WebCore::Document::setFocusedNode): Moved code to clear selections to the FocusController, since it is Page level and will know about the frame/document that contained the old selection. Moved code to call shouldEndEditing to the FocusController because selections are now cleared before calling Document::setFocusedNode and shouldEndEditing must be called before selections are cleared.
  • dom/Element.cpp: (WebCore::Element::blur): Call FocusController::setFocusNode instead of Document::setFocusNode, if possible.
  • page/EventHandler.cpp: (WebCore::EventHandler::dispatchMouseEvent): Ditto.
  • page/FocusController.cpp: (WebCore::relinquishesEditingFocus): Moved from Document.cpp. (WebCore::clearSelectionIfNeeded): Ditto. Don't clear if the old selection is in a frame that's different than the one that contains the new focus node. (WebCore::FocusController::setFocusedNode): Moved code here from Document::setFocusedNode.
  • page/Frame.cpp: (WebCore::Frame::setFocusedNodeIfNeeded): Call FocusController::setFocusNode.
Location:
trunk
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r21453 r21467  
     12007-05-14  Justin Garcia  <justin.garcia@apple.com>
     2
     3        Reviewed by darin
     4       
     5        <rdar://problem/5136696> Selection is removed when focusing a node in another frame
     6
     7        Demonstrates bug:
     8        * editing/selection/5136696-expected.checksum: Added.
     9        * editing/selection/5136696-expected.png: Added.
     10        * editing/selection/5136696-expected.txt: Added.
     11        * editing/selection/5136696.html: Added.
     12
    1132007-05-14  Kimmo Kinnunen  <kimmok@iki.fi>
    214
  • trunk/WebCore/ChangeLog

    r21464 r21467  
     12007-05-14  Justin Garcia  <justin.garcia@apple.com>
     2
     3        Reviewed by darin
     4       
     5        <rdar://problem/5136696> Selection is removed when focusing a node in another frame
     6        <rdar://problem/5192388> WordPress: Can't insert links/images
     7       
     8        Don't clear a selection when changing focus if the new
     9        focus node is in a different frame than the old selection.
     10
     11        * dom/Document.cpp:
     12        (WebCore::Document::setFocusedNode): Moved code to clear
     13        selections to the FocusController, since it is Page level
     14        and will know about the frame/document that contained the
     15        old selection. Moved code to call shouldEndEditing to the
     16        FocusController because selections are now cleared before
     17        calling Document::setFocusedNode and shouldEndEditing must
     18        be called before selections are cleared.
     19        * dom/Element.cpp:
     20        (WebCore::Element::blur): Call FocusController::setFocusNode
     21        instead of Document::setFocusNode, if possible.
     22        * page/EventHandler.cpp:
     23        (WebCore::EventHandler::dispatchMouseEvent): Ditto.
     24        * page/FocusController.cpp:
     25        (WebCore::relinquishesEditingFocus): Moved from Document.cpp.
     26        (WebCore::clearSelectionIfNeeded): Ditto.  Don't clear if
     27        the old selection is in a frame that's different than the
     28        one that contains the new focus node.
     29        (WebCore::FocusController::setFocusedNode): Moved code
     30        here from Document::setFocusedNode.
     31        * page/Frame.cpp:
     32        (WebCore::Frame::setFocusedNodeIfNeeded): Call
     33        FocusController::setFocusNode.
     34
    1352007-05-14  Geoffrey Garen  <ggaren@apple.com>
    236
  • trunk/WebCore/dom/Document.cpp

    r21430 r21467  
    229229}
    230230
    231 static bool relinquishesEditingFocus(Node *node)
     231static bool acceptsEditingFocus(Node *node)
    232232{
    233233    ASSERT(node);
     
    239239        return false;
    240240
    241     return frame->editor()->shouldEndEditing(rangeOfContents(root).get());
    242 }
    243 
    244 static bool acceptsEditingFocus(Node *node)
    245 {
    246     ASSERT(node);
    247     ASSERT(node->isContentEditable());
    248 
    249     Node *root = node->rootEditableElement();
    250     Frame* frame = node->document()->frame();
    251     if (!frame || !root)
    252         return false;
    253 
    254241    return frame->editor()->shouldBeginEditing(rangeOfContents(root).get());
    255 }
    256 
    257 static void clearSelectionIfNeeded(Frame* frame, Node* newFocusedNode)
    258 {
    259     if (!frame)
    260         return;
    261 
    262     // Clear the selection when changing the focus node to null or to a node that is not
    263     // contained by the current selection.
    264     Node* startContainer = frame->selectionController()->start().node();
    265     if (!newFocusedNode || (startContainer && startContainer != newFocusedNode && !(startContainer->isDescendantOf(newFocusedNode)) && startContainer->shadowAncestorNode() != newFocusedNode))
    266         frame->selectionController()->clear();
    267242}
    268243
     
    21522127    if (m_focusedNode == newFocusedNode)
    21532128        return true;
    2154 
    2155     if (m_focusedNode && m_focusedNode.get() == m_focusedNode->rootEditableElement() && !relinquishesEditingFocus(m_focusedNode.get()))
    2156           return false;
    21572129       
    21582130    bool focusChangeBlocked = false;
    21592131    RefPtr<Node> oldFocusedNode = m_focusedNode;
    21602132    m_focusedNode = 0;
    2161     clearSelectionIfNeeded(frame(), newFocusedNode.get());
    21622133
    21632134    // Remove focus from the existing focus node (if any)
     
    21842155            newFocusedNode = 0;
    21852156        }
    2186         clearSelectionIfNeeded(frame(), newFocusedNode.get());
    21872157        EventTargetNodeCast(oldFocusedNode.get())->dispatchUIEvent(DOMFocusOutEvent);
    21882158        if (m_focusedNode) {
     
    21912161            newFocusedNode = 0;
    21922162        }
    2193         clearSelectionIfNeeded(frame(), newFocusedNode.get());
    21942163        if ((oldFocusedNode.get() == this) && oldFocusedNode->hasOneRef())
    21952164            return true;
  • trunk/WebCore/dom/Element.cpp

    r21278 r21467  
    10131013    stopUpdateFocusAppearanceTimer();
    10141014    Document* doc = document();
    1015     if (doc->focusedNode() == this)
    1016         doc->setFocusedNode(0);
     1015    if (doc->focusedNode() == this) {
     1016        if (doc->frame())
     1017            doc->frame()->page()->focusController()->setFocusedNode(0);
     1018        else
     1019            doc->setFocusedNode(0);
     1020    }
    10171021}
    10181022
  • trunk/WebCore/page/EventHandler.cpp

    r21445 r21467  
    11881188        // if the page already set it (e.g., by canceling default behavior).
    11891189        if (node && node->isMouseFocusable()) {
    1190             if (!m_frame->document()->setFocusedNode(node))
     1190            if (!m_frame->page()->focusController()->setFocusedNode(node))
    11911191                swallowEvent = true;
    11921192        } else if (!node || !node->focused()) {
  • trunk/WebCore/page/FocusController.cpp

    r20072 r21467  
    208208}
    209209
     210static bool relinquishesEditingFocus(Node *node)
     211{
     212    ASSERT(node);
     213    ASSERT(node->isContentEditable());
     214
     215    Node* root = node->rootEditableElement();
     216    Frame* frame = node->document()->frame();
     217    if (!frame || !root)
     218        return false;
     219
     220    return frame->editor()->shouldEndEditing(rangeOfContents(root).get());
     221}
     222
     223static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Node* newFocusedNode)
     224{
     225    if (!oldFocusedFrame)
     226        return;
     227       
     228    if (newFocusedNode && oldFocusedFrame->document() != newFocusedNode->document())
     229        return;
     230   
     231    SelectionController* s = oldFocusedFrame->selectionController();
     232    if (s->isNone())
     233        return;
     234   
     235    Node* selectionStartNode = s->selection().start().node();
     236    if (selectionStartNode == newFocusedNode || selectionStartNode->isDescendantOf(newFocusedNode) || selectionStartNode->shadowAncestorNode() == newFocusedNode)
     237        return;
     238   
     239    s->clear();
     240}
     241
    210242bool FocusController::setFocusedNode(Node* node)
    211243{
    212244    RefPtr<Frame> oldFocusedFrame = focusedFrame();
    213245    RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
     246   
     247    Node* oldFocusedNode = oldDocument ? oldDocument->focusedNode() : 0;
     248    if (oldFocusedNode == node)
     249        return true;
     250       
     251    if (oldFocusedNode && oldFocusedNode->rootEditableElement() == oldFocusedNode && !relinquishesEditingFocus(oldFocusedNode))
     252        return false;
     253       
     254    clearSelectionIfNeeded(oldFocusedFrame.get(), node);
    214255   
    215256    if (!node) {
  • trunk/WebCore/page/Frame.cpp

    r21454 r21467  
    614614            // work in the long term, but this is the safest fix at this time.
    615615            if (target && target->isMouseFocusable() && !isFrameElement(target)) {
    616                 document()->setFocusedNode(target);
     616                page()->focusController()->setFocusedNode(target);
    617617                return;
    618618            }
Note: See TracChangeset for help on using the changeset viewer.