Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: third_party/WebKit/Source/core/page/FocusController.cpp

Issue 1500873002: Implement sequential focus navigation for OOPIF. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleanup and test fix Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nuanti Ltd. 3 * Copyright (C) 2008 Nuanti Ltd.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 25 matching lines...) Expand all
36 #include "core/dom/Range.h" 36 #include "core/dom/Range.h"
37 #include "core/dom/shadow/ElementShadow.h" 37 #include "core/dom/shadow/ElementShadow.h"
38 #include "core/dom/shadow/ShadowRoot.h" 38 #include "core/dom/shadow/ShadowRoot.h"
39 #include "core/editing/EditingUtilities.h" // For firstPositionInOrBeforeNode 39 #include "core/editing/EditingUtilities.h" // For firstPositionInOrBeforeNode
40 #include "core/editing/Editor.h" 40 #include "core/editing/Editor.h"
41 #include "core/editing/FrameSelection.h" 41 #include "core/editing/FrameSelection.h"
42 #include "core/events/Event.h" 42 #include "core/events/Event.h"
43 #include "core/frame/FrameView.h" 43 #include "core/frame/FrameView.h"
44 #include "core/frame/LocalDOMWindow.h" 44 #include "core/frame/LocalDOMWindow.h"
45 #include "core/frame/LocalFrame.h" 45 #include "core/frame/LocalFrame.h"
46 #include "core/frame/RemoteFrame.h"
46 #include "core/frame/Settings.h" 47 #include "core/frame/Settings.h"
47 #include "core/html/HTMLAreaElement.h" 48 #include "core/html/HTMLAreaElement.h"
48 #include "core/html/HTMLImageElement.h" 49 #include "core/html/HTMLImageElement.h"
49 #include "core/html/HTMLPlugInElement.h" 50 #include "core/html/HTMLPlugInElement.h"
50 #include "core/html/HTMLShadowElement.h" 51 #include "core/html/HTMLShadowElement.h"
51 #include "core/html/HTMLTextFormControlElement.h" 52 #include "core/html/HTMLTextFormControlElement.h"
52 #include "core/input/EventHandler.h" 53 #include "core/input/EventHandler.h"
53 #include "core/page/ChromeClient.h" 54 #include "core/page/ChromeClient.h"
54 #include "core/page/FrameTree.h" 55 #include "core/page/FrameTree.h"
55 #include "core/page/Page.h" 56 #include "core/page/Page.h"
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 cache->handleInitialFocus(); 684 cache->handleInitialFocus();
684 } 685 }
685 686
686 return didAdvanceFocus; 687 return didAdvanceFocus;
687 } 688 }
688 689
689 bool FocusController::advanceFocus(WebFocusType type, bool initialFocus, InputDe viceCapabilities* sourceCapabilities) 690 bool FocusController::advanceFocus(WebFocusType type, bool initialFocus, InputDe viceCapabilities* sourceCapabilities)
690 { 691 {
691 switch (type) { 692 switch (type) {
692 case WebFocusTypeForward: 693 case WebFocusTypeForward:
693 case WebFocusTypeBackward: 694 case WebFocusTypeBackward: {
694 return advanceFocusInDocumentOrder(type, initialFocus, sourceCapabilitie s); 695 // We should never hit this when a RemoteFrame is focused, since the key
696 // event that initiated focus advancement should've been routed to that
697 // frame's process from the beginning.
698 LocalFrame* startingFrame = toLocalFrame(focusedOrMainFrame());
699 return advanceFocusInDocumentOrder(startingFrame, nullptr, type, initial Focus, sourceCapabilities);
700 }
695 case WebFocusTypeLeft: 701 case WebFocusTypeLeft:
696 case WebFocusTypeRight: 702 case WebFocusTypeRight:
697 case WebFocusTypeUp: 703 case WebFocusTypeUp:
698 case WebFocusTypeDown: 704 case WebFocusTypeDown:
699 return advanceFocusDirectionally(type); 705 return advanceFocusDirectionally(type);
700 default: 706 default:
701 ASSERT_NOT_REACHED(); 707 ASSERT_NOT_REACHED();
702 } 708 }
703 709
704 return false; 710 return false;
705 } 711 }
706 712
707 bool FocusController::advanceFocusInDocumentOrder(WebFocusType type, bool initia lFocus, InputDeviceCapabilities* sourceCapabilities) 713 bool FocusController::advanceFocusAcrossFrames(WebFocusType type, RemoteFrame* f rom, LocalFrame* to, InputDeviceCapabilities* sourceCapabilities)
708 { 714 {
709 // FIXME: Focus advancement won't work with externally rendered frames until after 715 // If we are shifting focus from a child frame to its parent, the
710 // inter-frame focus control is moved out of Blink. 716 // child frame has no more focusable elements, and we should continue
711 if (!focusedOrMainFrame()->isLocalFrame()) 717 // looking for focusable elements in the parent, starting from the <iframe>
712 return false; 718 // element of the child frame.
713 LocalFrame* frame = toLocalFrame(focusedOrMainFrame()); 719 Node* startingNode = nullptr;
720 if (from->tree().parent() == to) {
721 ASSERT(from->owner()->isLocal());
722 startingNode = toHTMLFrameOwnerElement(from->owner());
723 }
724
725 return advanceFocusInDocumentOrder(to, startingNode, type, false, sourceCapa bilities);
726 }
727
728 bool FocusController::advanceFocusInDocumentOrder(LocalFrame* frame, Node* start ingNode, WebFocusType type, bool initialFocus, InputDeviceCapabilities* sourceCa pabilities)
729 {
714 ASSERT(frame); 730 ASSERT(frame);
715 Document* document = frame->document(); 731 Document* document = frame->document();
716 732
717 Node* currentNode = document->focusedElement(); 733 Node* currentNode = startingNode;
734 if (!currentNode)
735 currentNode = document->focusedElement();
736
718 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself 737 // FIXME: Not quite correct when it comes to focus transitions leaving/enter ing the WebView itself
719 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled(); 738 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEn abled();
720 739
721 if (caretBrowsing && !currentNode) 740 if (caretBrowsing && !currentNode)
722 currentNode = frame->selection().start().anchorNode(); 741 currentNode = frame->selection().start().anchorNode();
723 742
724 document->updateLayoutIgnorePendingStylesheets(); 743 document->updateLayoutIgnorePendingStylesheets();
725 744
726 RefPtrWillBeRawPtr<Element> element = findFocusableElementAcrossFocusScopes( type, FocusNavigationScope::focusNavigationScopeOf(currentNode ? *currentNode : *document), currentNode); 745 RefPtrWillBeRawPtr<Element> element = findFocusableElementAcrossFocusScopes( type, FocusNavigationScope::focusNavigationScopeOf(currentNode ? *currentNode : *document), currentNode);
727 746
728 if (!element) { 747 if (!element) {
748 // If there's a RemoteFrame on the ancestor chain, we need to continue
749 // searching for focusable elements there.
750 if (frame->localFrameRoot() != frame->tree().top()) {
751 document->clearFocusedElement();
752 toRemoteFrame(frame->localFrameRoot()->tree().parent())->advanceFocu s(type, frame->localFrameRoot());
753 return true;
754 }
755
729 // We didn't find an element to focus, so we should try to pass focus to Chrome. 756 // We didn't find an element to focus, so we should try to pass focus to Chrome.
730 if (!initialFocus && m_page->chromeClient().canTakeFocus(type)) { 757 if (!initialFocus && m_page->chromeClient().canTakeFocus(type)) {
731 document->clearFocusedElement(); 758 document->clearFocusedElement();
732 setFocusedFrame(nullptr); 759 setFocusedFrame(nullptr);
733 m_page->chromeClient().takeFocus(type); 760 m_page->chromeClient().takeFocus(type);
734 return true; 761 return true;
735 } 762 }
736 763
737 // Chrome doesn't want focus, so we should wrap focus. 764 // Chrome doesn't want focus, so we should wrap focus.
738 if (!m_page->mainFrame()->isLocalFrame()) 765 if (!m_page->mainFrame()->isLocalFrame())
(...skipping 14 matching lines...) Expand all
753 780
754 if (element->isFrameOwnerElement() && (!isHTMLPlugInElement(*element) || !el ement->isKeyboardFocusable())) { 781 if (element->isFrameOwnerElement() && (!isHTMLPlugInElement(*element) || !el ement->isKeyboardFocusable())) {
755 // We focus frames rather than frame owners. 782 // We focus frames rather than frame owners.
756 // FIXME: We should not focus frames that have no scrollbars, as focusin g them isn't useful to the user. 783 // FIXME: We should not focus frames that have no scrollbars, as focusin g them isn't useful to the user.
757 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(element); 784 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(element);
758 if (!owner->contentFrame()) 785 if (!owner->contentFrame())
759 return false; 786 return false;
760 787
761 document->clearFocusedElement(); 788 document->clearFocusedElement();
762 setFocusedFrame(owner->contentFrame()); 789 setFocusedFrame(owner->contentFrame());
790
791 // If contentFrame is remote, continue the search for focusable
792 // elements in that frame's process.
793 // clearFocusedElement() fires events that might detach the
794 // contentFrame, hence the need to null-check it again.
795 if (owner->contentFrame() && owner->contentFrame()->isRemoteFrame())
796 toRemoteFrame(owner->contentFrame())->advanceFocus(type, frame);
797
763 return true; 798 return true;
764 } 799 }
765 800
766 // FIXME: It would be nice to just be able to call setFocusedElement(node) 801 // FIXME: It would be nice to just be able to call setFocusedElement(node)
767 // here, but we can't do that because some elements (e.g. HTMLInputElement 802 // here, but we can't do that because some elements (e.g. HTMLInputElement
768 // and HTMLTextAreaElement) do extra work in their focus() methods. 803 // and HTMLTextAreaElement) do extra work in their focus() methods.
769 Document& newDocument = element->document(); 804 Document& newDocument = element->document();
770 805
771 if (&newDocument != document) { 806 if (&newDocument != document) {
772 // Focus is going away from this document, so clear the focused node. 807 // Focus is going away from this document, so clear the focused node.
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 return consumed; 1121 return consumed;
1087 } 1122 }
1088 1123
1089 DEFINE_TRACE(FocusController) 1124 DEFINE_TRACE(FocusController)
1090 { 1125 {
1091 visitor->trace(m_page); 1126 visitor->trace(m_page);
1092 visitor->trace(m_focusedFrame); 1127 visitor->trace(m_focusedFrame);
1093 } 1128 }
1094 1129
1095 } // namespace blink 1130 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698