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