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