6f59e13e5f90a40ab4d7de5f00c230f2f8a1771b
[WebKit-https.git] / Source / WebCore / page / FocusController.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Nuanti Ltd.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "FocusController.h"
29
30 #include "AXObjectCache.h"
31 #include "Chrome.h"
32 #include "Document.h"
33 #include "Editor.h"
34 #include "EditorClient.h"
35 #include "Element.h"
36 #include "ElementShadow.h"
37 #include "Event.h"
38 #include "EventHandler.h"
39 #include "EventNames.h"
40 #include "ExceptionCode.h"
41 #include "Frame.h"
42 #include "FrameSelection.h"
43 #include "FrameTree.h"
44 #include "FrameView.h"
45 #include "HTMLAreaElement.h"
46 #include "HTMLImageElement.h"
47 #include "HTMLNames.h"
48 #include "HitTestResult.h"
49 #include "KeyboardEvent.h"
50 #include "NodeRenderingTraversal.h"
51 #include "NodeTraversal.h"
52 #include "Page.h"
53 #include "Range.h"
54 #include "RenderObject.h"
55 #include "RenderWidget.h"
56 #include "ScrollAnimator.h"
57 #include "Settings.h"
58 #include "ShadowRoot.h"
59 #include "SpatialNavigation.h"
60 #include "Widget.h"
61 #include "htmlediting.h" // For firstPositionInOrBeforeNode
62 #include <limits>
63
64 namespace WebCore {
65
66 using namespace HTMLNames;
67 using namespace std;
68
69 FocusNavigationScope::FocusNavigationScope(TreeScope* treeScope)
70     : m_rootTreeScope(treeScope)
71 {
72     ASSERT(treeScope);
73     ASSERT(!treeScope->rootNode()->isShadowRoot() || toShadowRoot(treeScope->rootNode())->isYoungest());
74 }
75
76 Node* FocusNavigationScope::rootNode() const
77 {
78     return m_rootTreeScope->rootNode();
79 }
80
81 Element* FocusNavigationScope::owner() const
82 {
83     Node* root = rootNode();
84     if (root->isShadowRoot())
85         return toShadowRoot(root)->host();
86     if (Frame* frame = root->document()->frame())
87         return frame->ownerElement();
88     return 0;
89 }
90
91 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOf(Node* node)
92 {
93     ASSERT(node);
94     Node* root = node;
95     for (Node* n = node; n; n = NodeRenderingTraversal::parentInScope(n))
96         root = n;
97     // The result is not always a ShadowRoot nor a DocumentNode since
98     // a starting node is in an orphaned tree in composed shadow tree.
99     return FocusNavigationScope(root->treeScope());
100 }
101
102 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOwnedByShadowHost(Node* node)
103 {
104     ASSERT(isShadowHost(node));
105     return FocusNavigationScope(toElement(node)->shadow()->youngestShadowRoot());
106 }
107
108 FocusNavigationScope FocusNavigationScope::focusNavigationScopeOwnedByIFrame(HTMLFrameOwnerElement* frame)
109 {
110     ASSERT(frame && frame->contentFrame());
111     return FocusNavigationScope(frame->contentFrame()->document());
112 }
113
114 static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool focused)
115 {
116     // If we have a focused node we should dispatch blur on it before we blur the window.
117     // If we have a focused node we should dispatch focus on it after we focus the window.
118     // https://bugs.webkit.org/show_bug.cgi?id=27105
119
120     // Do not fire events while modal dialogs are up.  See https://bugs.webkit.org/show_bug.cgi?id=33962
121     if (Page* page = document->page()) {
122         if (page->defersLoading())
123             return;
124     }
125
126     if (!focused && document->focusedNode())
127         document->focusedNode()->dispatchBlurEvent(0);
128     document->dispatchWindowEvent(Event::create(focused ? eventNames().focusEvent : eventNames().blurEvent, false, false));
129     if (focused && document->focusedNode())
130         document->focusedNode()->dispatchFocusEvent(0, FocusDirectionNone);
131 }
132
133 static inline bool hasCustomFocusLogic(Node* node)
134 {
135     return node->isHTMLElement() && toHTMLElement(node)->hasCustomFocusLogic();
136 }
137
138 static inline bool isNonFocusableShadowHost(Node* node, KeyboardEvent* event)
139 {
140     ASSERT(node);
141     return !node->isKeyboardFocusable(event) && isShadowHost(node) && !hasCustomFocusLogic(node);
142 }
143
144 static inline bool isFocusableShadowHost(Node* node, KeyboardEvent* event)
145 {
146     ASSERT(node);
147     return node->isKeyboardFocusable(event) && isShadowHost(node) && !hasCustomFocusLogic(node);
148 }
149
150 static inline int adjustedTabIndex(Node* node, KeyboardEvent* event)
151 {
152     ASSERT(node);
153     return isNonFocusableShadowHost(node, event) ? 0 : node->tabIndex();
154 }
155
156 static inline bool shouldVisit(Node* node, KeyboardEvent* event)
157 {
158     ASSERT(node);
159     return node->isKeyboardFocusable(event) || isNonFocusableShadowHost(node, event);
160 }
161
162 FocusController::FocusController(Page* page)
163     : m_page(page)
164     , m_isActive(false)
165     , m_isFocused(false)
166     , m_isChangingFocusedFrame(false)
167     , m_containingWindowIsVisible(false)
168 {
169 }
170
171 PassOwnPtr<FocusController> FocusController::create(Page* page)
172 {
173     return adoptPtr(new FocusController(page));
174 }
175
176 void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
177 {
178     ASSERT(!frame || frame->page() == m_page);
179     if (m_focusedFrame == frame || m_isChangingFocusedFrame)
180         return;
181
182     m_isChangingFocusedFrame = true;
183
184     RefPtr<Frame> oldFrame = m_focusedFrame;
185     RefPtr<Frame> newFrame = frame;
186
187     m_focusedFrame = newFrame;
188
189     // Now that the frame is updated, fire events and update the selection focused states of both frames.
190     if (oldFrame && oldFrame->view()) {
191         oldFrame->selection()->setFocused(false);
192         oldFrame->document()->dispatchWindowEvent(Event::create(eventNames().blurEvent, false, false));
193     }
194
195     if (newFrame && newFrame->view() && isFocused()) {
196         newFrame->selection()->setFocused(true);
197         newFrame->document()->dispatchWindowEvent(Event::create(eventNames().focusEvent, false, false));
198     }
199
200     m_page->chrome()->focusedFrameChanged(newFrame.get());
201
202     m_isChangingFocusedFrame = false;
203 }
204
205 Frame* FocusController::focusedOrMainFrame() const
206 {
207     if (Frame* frame = focusedFrame())
208         return frame;
209     return m_page->mainFrame();
210 }
211
212 void FocusController::setFocused(bool focused)
213 {
214     if (isFocused() == focused)
215         return;
216     
217     m_isFocused = focused;
218
219     if (!m_isFocused)
220         focusedOrMainFrame()->eventHandler()->stopAutoscrollTimer();
221
222     if (!m_focusedFrame)
223         setFocusedFrame(m_page->mainFrame());
224
225     if (m_focusedFrame->view()) {
226         m_focusedFrame->selection()->setFocused(focused);
227         dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), focused);
228     }
229 }
230
231 Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusDirection direction, Node* node, KeyboardEvent* event)
232 {
233     // The node we found might be a HTMLFrameOwnerElement, so descend down the tree until we find either:
234     // 1) a focusable node, or
235     // 2) the deepest-nested HTMLFrameOwnerElement.
236     while (node && node->isFrameOwnerElement()) {
237         HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(node);
238         if (!owner->contentFrame())
239             break;
240         Node* foundNode = findFocusableNode(direction, FocusNavigationScope::focusNavigationScopeOwnedByIFrame(owner), 0, event);
241         if (!foundNode)
242             break;
243         ASSERT(node != foundNode);
244         node = foundNode;
245     }
246     return node;
247 }
248
249 bool FocusController::setInitialFocus(FocusDirection direction, KeyboardEvent* event)
250 {
251     bool didAdvanceFocus = advanceFocus(direction, event, true);
252     
253     // If focus is being set initially, accessibility needs to be informed that system focus has moved 
254     // into the web area again, even if focus did not change within WebCore. PostNotification is called instead
255     // of handleFocusedUIElementChanged, because this will send the notification even if the element is the same.
256     if (AXObjectCache::accessibilityEnabled())
257         focusedOrMainFrame()->document()->axObjectCache()->postNotification(focusedOrMainFrame()->document(), AXObjectCache::AXFocusedUIElementChanged, true);
258
259     return didAdvanceFocus;
260 }
261
262 bool FocusController::advanceFocus(FocusDirection direction, KeyboardEvent* event, bool initialFocus)
263 {
264     switch (direction) {
265     case FocusDirectionForward:
266     case FocusDirectionBackward:
267         return advanceFocusInDocumentOrder(direction, event, initialFocus);
268     case FocusDirectionLeft:
269     case FocusDirectionRight:
270     case FocusDirectionUp:
271     case FocusDirectionDown:
272         return advanceFocusDirectionally(direction, event);
273     default:
274         ASSERT_NOT_REACHED();
275     }
276
277     return false;
278 }
279
280 bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, KeyboardEvent* event, bool initialFocus)
281 {
282     Frame* frame = focusedOrMainFrame();
283     ASSERT(frame);
284     Document* document = frame->document();
285
286     Node* currentNode = document->focusedNode();
287     // FIXME: Not quite correct when it comes to focus transitions leaving/entering the WebView itself
288     bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
289
290     if (caretBrowsing && !currentNode)
291         currentNode = frame->selection()->start().deprecatedNode();
292
293     document->updateLayoutIgnorePendingStylesheets();
294
295     RefPtr<Node> node = findFocusableNodeAcrossFocusScope(direction, FocusNavigationScope::focusNavigationScopeOf(currentNode ? currentNode : document), currentNode, event);
296
297     if (!node) {
298         // We didn't find a node to focus, so we should try to pass focus to Chrome.
299         if (!initialFocus && m_page->chrome()->canTakeFocus(direction)) {
300             document->setFocusedNode(0);
301             setFocusedFrame(0);
302             m_page->chrome()->takeFocus(direction);
303             return true;
304         }
305
306         // Chrome doesn't want focus, so we should wrap focus.
307         node = findFocusableNodeRecursively(direction, FocusNavigationScope::focusNavigationScopeOf(m_page->mainFrame()->document()), 0, event);
308         node = findFocusableNodeDecendingDownIntoFrameDocument(direction, node.get(), event);
309
310         if (!node)
311             return false;
312     }
313
314     ASSERT(node);
315
316     if (node == document->focusedNode())
317         // Focus wrapped around to the same node.
318         return true;
319
320     if (!node->isElementNode())
321         // FIXME: May need a way to focus a document here.
322         return false;
323
324     if (node->isFrameOwnerElement() && (!node->isPluginElement() || !node->isKeyboardFocusable(event))) {
325         // We focus frames rather than frame owners.
326         // FIXME: We should not focus frames that have no scrollbars, as focusing them isn't useful to the user.
327         HTMLFrameOwnerElement* owner = static_cast<HTMLFrameOwnerElement*>(node.get());
328         if (!owner->contentFrame())
329             return false;
330
331         document->setFocusedNode(0);
332         setFocusedFrame(owner->contentFrame());
333         return true;
334     }
335     
336     // FIXME: It would be nice to just be able to call setFocusedNode(node) here, but we can't do
337     // that because some elements (e.g. HTMLInputElement and HTMLTextAreaElement) do extra work in
338     // their focus() methods.
339
340     Document* newDocument = node->document();
341
342     if (newDocument != document)
343         // Focus is going away from this document, so clear the focused node.
344         document->setFocusedNode(0);
345
346     if (newDocument)
347         setFocusedFrame(newDocument->frame());
348
349     if (caretBrowsing) {
350         Position position = firstPositionInOrBeforeNode(node.get());
351         VisibleSelection newSelection(position, position, DOWNSTREAM);
352         if (frame->selection()->shouldChangeSelection(newSelection))
353             frame->selection()->setSelection(newSelection);
354     }
355
356     static_cast<Element*>(node.get())->focus(false, direction);
357     return true;
358 }
359
360 Node* FocusController::findFocusableNodeAcrossFocusScope(FocusDirection direction, FocusNavigationScope scope, Node* currentNode, KeyboardEvent* event)
361 {
362     ASSERT(!currentNode || !isNonFocusableShadowHost(currentNode, event));
363     Node* found;
364     if (currentNode && direction == FocusDirectionForward && isFocusableShadowHost(currentNode, event)) {
365         Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::focusNavigationScopeOwnedByShadowHost(currentNode), 0, event);
366         found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRecursively(direction, scope, currentNode, event);
367     } else
368         found = findFocusableNodeRecursively(direction, scope, currentNode, event);
369
370     // If there's no focusable node to advance to, move up the focus scopes until we find one.
371     while (!found) {
372         Node* owner = scope.owner();
373         if (!owner)
374             break;
375         scope = FocusNavigationScope::focusNavigationScopeOf(owner);
376         if (direction == FocusDirectionBackward && isFocusableShadowHost(owner, event)) {
377             found = owner;
378             break;
379         }
380         found = findFocusableNodeRecursively(direction, scope, owner, event);
381     }
382     found = findFocusableNodeDecendingDownIntoFrameDocument(direction, found, event);
383     return found;
384 }
385
386 Node* FocusController::findFocusableNodeRecursively(FocusDirection direction, FocusNavigationScope scope, Node* start, KeyboardEvent* event)
387 {
388     // Starting node is exclusive.
389     Node* found = findFocusableNode(direction, scope, start, event);
390     if (!found)
391         return 0;
392     if (direction == FocusDirectionForward) {
393         if (!isNonFocusableShadowHost(found, event))
394             return found;
395         Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::focusNavigationScopeOwnedByShadowHost(found), 0, event);
396         return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRecursively(direction, scope, found, event);
397     }
398     ASSERT(direction == FocusDirectionBackward);
399     if (isFocusableShadowHost(found, event)) {
400         Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::focusNavigationScopeOwnedByShadowHost(found), 0, event);
401         return foundInInnerFocusScope ? foundInInnerFocusScope : found;
402     }
403     if (isNonFocusableShadowHost(found, event)) {
404         Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::focusNavigationScopeOwnedByShadowHost(found), 0, event);
405         return foundInInnerFocusScope ? foundInInnerFocusScope :findFocusableNodeRecursively(direction, scope, found, event);
406     }
407     return found;
408 }
409
410 Node* FocusController::findFocusableNode(FocusDirection direction, FocusNavigationScope scope, Node* node, KeyboardEvent* event)
411 {
412     return (direction == FocusDirectionForward)
413         ? nextFocusableNode(scope, node, event)
414         : previousFocusableNode(scope, node, event);
415 }
416
417 Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, KeyboardEvent* event, FocusDirection direction)
418 {
419     // Search is inclusive of start
420     using namespace NodeRenderingTraversal;
421     for (Node* node = start; node; node = direction == FocusDirectionForward ? nextInScope(node) : previousInScope(node)) {
422         if (shouldVisit(node, event) && adjustedTabIndex(node, event) == tabIndex)
423             return node;
424     }
425     return 0;
426 }
427
428 static Node* nextNodeWithGreaterTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
429 {
430     // Search is inclusive of start
431     int winningTabIndex = std::numeric_limits<short>::max() + 1;
432     Node* winner = 0;
433     for (Node* node = start; node; node = NodeRenderingTraversal::nextInScope(node)) {
434         if (shouldVisit(node, event) && node->tabIndex() > tabIndex && node->tabIndex() < winningTabIndex) {
435             winner = node;
436             winningTabIndex = node->tabIndex();
437         }
438     }
439
440     return winner;
441 }
442
443 static Node* previousNodeWithLowerTabIndex(Node* start, int tabIndex, KeyboardEvent* event)
444 {
445     // Search is inclusive of start
446     int winningTabIndex = 0;
447     Node* winner = 0;
448     for (Node* node = start; node; node = NodeRenderingTraversal::previousInScope(node)) {
449         int currentTabIndex = adjustedTabIndex(node, event);
450         if ((shouldVisit(node, event) || isNonFocusableShadowHost(node, event)) && currentTabIndex < tabIndex && currentTabIndex > winningTabIndex) {
451             winner = node;
452             winningTabIndex = currentTabIndex;
453         }
454     }
455     return winner;
456 }
457
458 Node* FocusController::nextFocusableNode(FocusNavigationScope scope, Node* start, KeyboardEvent* event)
459 {
460     using namespace NodeRenderingTraversal;
461
462     if (start) {
463         int tabIndex = adjustedTabIndex(start, event);
464         // If a node is excluded from the normal tabbing cycle, the next focusable node is determined by tree order
465         if (tabIndex < 0) {
466             for (Node* node = nextInScope(start); node; node = nextInScope(node)) {
467                 if (shouldVisit(node, event) && adjustedTabIndex(node, event) >= 0)
468                     return node;
469             }
470         }
471
472         // First try to find a node with the same tabindex as start that comes after start in the scope.
473         if (Node* winner = findNodeWithExactTabIndex(nextInScope(start), tabIndex, event, FocusDirectionForward))
474             return winner;
475
476         if (!tabIndex)
477             // We've reached the last node in the document with a tabindex of 0. This is the end of the tabbing order.
478             return 0;
479     }
480
481     // Look for the first node in the scope that:
482     // 1) has the lowest tabindex that is higher than start's tabindex (or 0, if start is null), and
483     // 2) comes first in the scope, if there's a tie.
484     if (Node* winner = nextNodeWithGreaterTabIndex(scope.rootNode(), start ? adjustedTabIndex(start, event) : 0, event))
485         return winner;
486
487     // There are no nodes with a tabindex greater than start's tabindex,
488     // so find the first node with a tabindex of 0.
489     return findNodeWithExactTabIndex(scope.rootNode(), 0, event, FocusDirectionForward);
490 }
491
492 Node* FocusController::previousFocusableNode(FocusNavigationScope scope, Node* start, KeyboardEvent* event)
493 {
494     using namespace NodeRenderingTraversal;
495
496     Node* last = 0;
497     for (Node* node = scope.rootNode(); node; node = lastChildInScope(node))
498         last = node;
499     ASSERT(last);
500
501     // First try to find the last node in the scope that comes before start and has the same tabindex as start.
502     // If start is null, find the last node in the scope with a tabindex of 0.
503     Node* startingNode;
504     int startingTabIndex;
505     if (start) {
506         startingNode = previousInScope(start);
507         startingTabIndex = adjustedTabIndex(start, event);
508     } else {
509         startingNode = last;
510         startingTabIndex = 0;
511     }
512
513     // However, if a node is excluded from the normal tabbing cycle, the previous focusable node is determined by tree order
514     if (startingTabIndex < 0) {
515         for (Node* node = startingNode; node; node = previousInScope(node)) {
516             if (shouldVisit(node, event) && adjustedTabIndex(node, event) >= 0)
517                 return node;
518         }
519     }
520
521     if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIndex, event, FocusDirectionBackward))
522         return winner;
523
524     // There are no nodes before start with the same tabindex as start, so look for a node that:
525     // 1) has the highest non-zero tabindex (that is less than start's tabindex), and
526     // 2) comes last in the scope, if there's a tie.
527     startingTabIndex = (start && startingTabIndex) ? startingTabIndex : std::numeric_limits<short>::max();
528     return previousNodeWithLowerTabIndex(last, startingTabIndex, event);
529 }
530
531 static bool relinquishesEditingFocus(Node *node)
532 {
533     ASSERT(node);
534     ASSERT(node->rendererIsEditable());
535
536     Node* root = node->rootEditableElement();
537     Frame* frame = node->document()->frame();
538     if (!frame || !root)
539         return false;
540
541     return frame->editor()->shouldEndEditing(rangeOfContents(root).get());
542 }
543
544 static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFrame, Node* newFocusedNode)
545 {
546     if (!oldFocusedFrame || !newFocusedFrame)
547         return;
548         
549     if (oldFocusedFrame->document() != newFocusedFrame->document())
550         return;
551     
552     FrameSelection* s = oldFocusedFrame->selection();
553     if (s->isNone())
554         return;
555
556     bool caretBrowsing = oldFocusedFrame->settings()->caretBrowsingEnabled();
557     if (caretBrowsing)
558         return;
559
560     Node* selectionStartNode = s->selection().start().deprecatedNode();
561     if (selectionStartNode == newFocusedNode || selectionStartNode->isDescendantOf(newFocusedNode) || selectionStartNode->deprecatedShadowAncestorNode() == newFocusedNode)
562         return;
563         
564     if (Node* mousePressNode = newFocusedFrame->eventHandler()->mousePressNode()) {
565         if (mousePressNode->renderer() && !mousePressNode->canStartSelection()) {
566             // Don't clear the selection for contentEditable elements, but do clear it for input and textarea. See bug 38696.
567             Node * root = s->rootEditableElement();
568             if (!root)
569                 return;
570
571             if (Node* shadowAncestorNode = root->deprecatedShadowAncestorNode()) {
572                 if (!shadowAncestorNode->hasTagName(inputTag) && !shadowAncestorNode->hasTagName(textareaTag))
573                     return;
574             }
575         }
576     }
577     
578     s->clear();
579 }
580
581 bool FocusController::setFocusedNode(Node* node, PassRefPtr<Frame> newFocusedFrame, FocusDirection direction)
582 {
583     RefPtr<Frame> oldFocusedFrame = focusedFrame();
584     RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
585     
586     Node* oldFocusedNode = oldDocument ? oldDocument->focusedNode() : 0;
587     if (oldFocusedNode == node)
588         return true;
589
590     // FIXME: Might want to disable this check for caretBrowsing
591     if (oldFocusedNode && oldFocusedNode->isRootEditableElement() && !relinquishesEditingFocus(oldFocusedNode))
592         return false;
593
594     m_page->editorClient()->willSetInputMethodState();
595
596     clearSelectionIfNeeded(oldFocusedFrame.get(), newFocusedFrame.get(), node);
597
598     if (!node) {
599         if (oldDocument)
600             oldDocument->setFocusedNode(0);
601         m_page->editorClient()->setInputMethodState(false);
602         return true;
603     }
604
605     RefPtr<Document> newDocument = node->document();
606
607     if (newDocument && newDocument->focusedNode() == node) {
608         m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod());
609         return true;
610     }
611     
612     if (oldDocument && oldDocument != newDocument)
613         oldDocument->setFocusedNode(0);
614     
615     setFocusedFrame(newFocusedFrame);
616
617     // Setting the focused node can result in losing our last reft to node when JS event handlers fire.
618     RefPtr<Node> protect = node;
619     if (newDocument) {
620         bool successfullyFocused = newDocument->setFocusedNode(node, direction);
621         if (!successfullyFocused)
622             return false;
623     }
624
625     if (newDocument->focusedNode() == node)
626         m_page->editorClient()->setInputMethodState(node->shouldUseInputMethod());
627
628     return true;
629 }
630
631 void FocusController::setActive(bool active)
632 {
633     if (m_isActive == active)
634         return;
635
636     m_isActive = active;
637
638     if (FrameView* view = m_page->mainFrame()->view()) {
639         if (!view->platformWidget()) {
640             view->updateLayoutAndStyleIfNeededRecursive();
641             view->updateControlTints();
642         }
643     }
644
645     focusedOrMainFrame()->selection()->pageActivationChanged();
646     
647     if (m_focusedFrame && isFocused())
648         dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), active);
649 }
650
651 static void contentAreaDidShowOrHide(ScrollableArea* scrollableArea, bool didShow)
652 {
653     if (didShow)
654         scrollableArea->contentAreaDidShow();
655     else
656         scrollableArea->contentAreaDidHide();
657 }
658
659 void FocusController::setContainingWindowIsVisible(bool containingWindowIsVisible)
660 {
661     if (m_containingWindowIsVisible == containingWindowIsVisible)
662         return;
663
664     m_containingWindowIsVisible = containingWindowIsVisible;
665
666     FrameView* view = m_page->mainFrame()->view();
667     if (!view)
668         return;
669
670     contentAreaDidShowOrHide(view, containingWindowIsVisible);
671
672     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
673         FrameView* frameView = frame->view();
674         if (!frameView)
675             continue;
676
677         const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
678         if (!scrollableAreas)
679             continue;
680
681         for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
682             ScrollableArea* scrollableArea = *it;
683             ASSERT(scrollableArea->scrollbarsCanBeActive() || m_page->shouldSuppressScrollbarAnimations());
684
685             contentAreaDidShowOrHide(scrollableArea, containingWindowIsVisible);
686         }
687     }
688 }
689
690 static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate, FocusCandidate& closest)
691 {
692     ASSERT(candidate.visibleNode->isElementNode());
693     ASSERT(candidate.visibleNode->renderer());
694
695     // Ignore iframes that don't have a src attribute
696     if (frameOwnerElement(candidate) && (!frameOwnerElement(candidate)->contentFrame() || candidate.rect.isEmpty()))
697         return;
698
699     // Ignore off screen child nodes of containers that do not scroll (overflow:hidden)
700     if (candidate.isOffscreen && !canBeScrolledIntoView(direction, candidate))
701         return;
702
703     distanceDataForNode(direction, current, candidate);
704     if (candidate.distance == maxDistance())
705         return;
706
707     if (candidate.isOffscreenAfterScrolling && candidate.alignment < Full)
708         return;
709
710     if (closest.isNull()) {
711         closest = candidate;
712         return;
713     }
714
715     LayoutRect intersectionRect = intersection(candidate.rect, closest.rect);
716     if (!intersectionRect.isEmpty() && !areElementsOnSameLine(closest, candidate)) {
717         // If 2 nodes are intersecting, do hit test to find which node in on top.
718         LayoutUnit x = intersectionRect.x() + intersectionRect.width() / 2;
719         LayoutUnit y = intersectionRect.y() + intersectionRect.height() / 2;
720         HitTestResult result = candidate.visibleNode->document()->page()->mainFrame()->eventHandler()->hitTestResultAtPoint(IntPoint(x, y), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping);
721         if (candidate.visibleNode->contains(result.innerNode())) {
722             closest = candidate;
723             return;
724         }
725         if (closest.visibleNode->contains(result.innerNode()))
726             return;
727     }
728
729     if (candidate.alignment == closest.alignment) {
730         if (candidate.distance < closest.distance)
731             closest = candidate;
732         return;
733     }
734
735     if (candidate.alignment > closest.alignment)
736         closest = candidate;
737 }
738
739 void FocusController::findFocusCandidateInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event, FocusCandidate& closest)
740 {
741     ASSERT(container);
742     Node* focusedNode = (focusedFrame() && focusedFrame()->document()) ? focusedFrame()->document()->focusedNode() : 0;
743
744     Element* element = ElementTraversal::firstWithin(container);
745     FocusCandidate current;
746     current.rect = startingRect;
747     current.focusableNode = focusedNode;
748     current.visibleNode = focusedNode;
749
750     for (; element; element = (element->isFrameOwnerElement() || canScrollInDirection(element, direction))
751         ? ElementTraversal::nextSkippingChildren(element, container)
752         : ElementTraversal::next(element, container)) {
753         if (element == focusedNode)
754             continue;
755
756         if (!element->isKeyboardFocusable(event) && !element->isFrameOwnerElement() && !canScrollInDirection(element, direction))
757             continue;
758
759         FocusCandidate candidate = FocusCandidate(element, direction);
760         if (candidate.isNull())
761             continue;
762
763         candidate.enclosingScrollableBox = container;
764         updateFocusCandidateIfNeeded(direction, current, candidate, closest);
765     }
766 }
767
768 bool FocusController::advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction, KeyboardEvent* event)
769 {
770     if (!container || !container->document())
771         return false;
772
773     LayoutRect newStartingRect = startingRect;
774
775     if (startingRect.isEmpty())
776         newStartingRect = virtualRectForDirection(direction, nodeRectInAbsoluteCoordinates(container));
777
778     // Find the closest node within current container in the direction of the navigation.
779     FocusCandidate focusCandidate;
780     findFocusCandidateInContainer(container, newStartingRect, direction, event, focusCandidate);
781
782     if (focusCandidate.isNull()) {
783         // Nothing to focus, scroll if possible.
784         // NOTE: If no scrolling is performed (i.e. scrollInDirection returns false), the
785         // spatial navigation algorithm will skip this container.
786         return scrollInDirection(container, direction);
787     }
788
789     if (HTMLFrameOwnerElement* frameElement = frameOwnerElement(focusCandidate)) {
790         // If we have an iframe without the src attribute, it will not have a contentFrame().
791         // We ASSERT here to make sure that
792         // updateFocusCandidateIfNeeded() will never consider such an iframe as a candidate.
793         ASSERT(frameElement->contentFrame());
794
795         if (focusCandidate.isOffscreenAfterScrolling) {
796             scrollInDirection(focusCandidate.visibleNode->document(), direction);
797             return true;
798         }
799         // Navigate into a new frame.
800         LayoutRect rect;
801         Node* focusedNode = focusedOrMainFrame()->document()->focusedNode();
802         if (focusedNode && !hasOffscreenRect(focusedNode))
803             rect = nodeRectInAbsoluteCoordinates(focusedNode, true /* ignore border */);
804         frameElement->contentFrame()->document()->updateLayoutIgnorePendingStylesheets();
805         if (!advanceFocusDirectionallyInContainer(frameElement->contentFrame()->document(), rect, direction, event)) {
806             // The new frame had nothing interesting, need to find another candidate.
807             return advanceFocusDirectionallyInContainer(container, nodeRectInAbsoluteCoordinates(focusCandidate.visibleNode, true), direction, event);
808         }
809         return true;
810     }
811
812     if (canScrollInDirection(focusCandidate.visibleNode, direction)) {
813         if (focusCandidate.isOffscreenAfterScrolling) {
814             scrollInDirection(focusCandidate.visibleNode, direction);
815             return true;
816         }
817         // Navigate into a new scrollable container.
818         LayoutRect startingRect;
819         Node* focusedNode = focusedOrMainFrame()->document()->focusedNode();
820         if (focusedNode && !hasOffscreenRect(focusedNode))
821             startingRect = nodeRectInAbsoluteCoordinates(focusedNode, true);
822         return advanceFocusDirectionallyInContainer(focusCandidate.visibleNode, startingRect, direction, event);
823     }
824     if (focusCandidate.isOffscreenAfterScrolling) {
825         Node* container = focusCandidate.enclosingScrollableBox;
826         scrollInDirection(container, direction);
827         return true;
828     }
829
830     // We found a new focus node, navigate to it.
831     Element* element = toElement(focusCandidate.focusableNode);
832     ASSERT(element);
833
834     element->focus(false, direction);
835     return true;
836 }
837
838 bool FocusController::advanceFocusDirectionally(FocusDirection direction, KeyboardEvent* event)
839 {
840     Frame* curFrame = focusedOrMainFrame();
841     ASSERT(curFrame);
842
843     Document* focusedDocument = curFrame->document();
844     if (!focusedDocument)
845         return false;
846
847     Node* focusedNode = focusedDocument->focusedNode();
848     Node* container = focusedDocument;
849
850     if (container->isDocumentNode())
851         static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets();
852         
853     // Figure out the starting rect.
854     LayoutRect startingRect;
855     if (focusedNode) {
856         if (!hasOffscreenRect(focusedNode)) {
857             container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, focusedNode);
858             startingRect = nodeRectInAbsoluteCoordinates(focusedNode, true /* ignore border */);
859         } else if (focusedNode->hasTagName(areaTag)) {
860             HTMLAreaElement* area = static_cast<HTMLAreaElement*>(focusedNode);
861             container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, area->imageElement());
862             startingRect = virtualRectForAreaElementAndDirection(area, direction);
863         }
864     }
865
866     bool consumed = false;
867     do {
868         consumed = advanceFocusDirectionallyInContainer(container, startingRect, direction, event);
869         startingRect = nodeRectInAbsoluteCoordinates(container, true /* ignore border */);
870         container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, container);
871         if (container && container->isDocumentNode())
872             static_cast<Document*>(container)->updateLayoutIgnorePendingStylesheets();
873     } while (!consumed && container);
874
875     return consumed;
876 }
877
878 } // namespace WebCore