OLD | NEW |
---|---|
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 915 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
926 // If we are shifting focus from a child frame to its parent, the | 926 // If we are shifting focus from a child frame to its parent, the |
927 // child frame has no more focusable elements, and we should continue | 927 // child frame has no more focusable elements, and we should continue |
928 // looking for focusable elements in the parent, starting from the <iframe> | 928 // looking for focusable elements in the parent, starting from the <iframe> |
929 // element of the child frame. | 929 // element of the child frame. |
930 Element* start = nullptr; | 930 Element* start = nullptr; |
931 if (from->Tree().Parent() == to) { | 931 if (from->Tree().Parent() == to) { |
932 DCHECK(from->Owner()->IsLocal()); | 932 DCHECK(from->Owner()->IsLocal()); |
933 start = ToHTMLFrameOwnerElement(from->Owner()); | 933 start = ToHTMLFrameOwnerElement(from->Owner()); |
934 } | 934 } |
935 | 935 |
936 return AdvanceFocusInDocumentOrder(to, start, type, false, | 936 // If we're coming from a parent frame, we need to restart from the first or |
937 // last focusable element. | |
938 bool initial_focus = to->Tree().Parent() == from; | |
939 | |
940 return AdvanceFocusInDocumentOrder(to, start, type, initial_focus, | |
937 source_capabilities); | 941 source_capabilities); |
938 } | 942 } |
939 | 943 |
940 #if DCHECK_IS_ON() | 944 #if DCHECK_IS_ON() |
941 inline bool IsNonFocusableShadowHost(const Element& element) { | 945 inline bool IsNonFocusableShadowHost(const Element& element) { |
942 return IsShadowHostWithoutCustomFocusLogic(element) && !element.IsFocusable(); | 946 return IsShadowHostWithoutCustomFocusLogic(element) && !element.IsFocusable(); |
943 } | 947 } |
944 #endif | 948 #endif |
945 | 949 |
946 bool FocusController::AdvanceFocusInDocumentOrder( | 950 bool FocusController::AdvanceFocusInDocumentOrder( |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
991 *ToLocalFrame(page_->MainFrame())->GetDocument()); | 995 *ToLocalFrame(page_->MainFrame())->GetDocument()); |
992 element = FindFocusableElementRecursively(type, scope); | 996 element = FindFocusableElementRecursively(type, scope); |
993 element = | 997 element = |
994 FindFocusableElementDescendingDownIntoFrameDocument(type, element); | 998 FindFocusableElementDescendingDownIntoFrameDocument(type, element); |
995 | 999 |
996 if (!element) | 1000 if (!element) |
997 return false; | 1001 return false; |
998 } | 1002 } |
999 | 1003 |
1000 if (element == document->FocusedElement()) { | 1004 if (element == document->FocusedElement()) { |
1001 // Focus wrapped around to the same element. | 1005 // Focus wrapped around to the same element. |
Nico
2017/04/19 16:53:16
The last time you landed the change, you removed t
avallee
2017/04/19 16:58:50
Done.
| |
1006 // Focus is either coming from a remote frame or has wrapped around. | |
1007 if (FocusedFrame() != document->GetFrame()) { | |
1008 SetFocusedFrame(document->GetFrame()); | |
1009 DispatchFocusEvent(*document, *element); | |
1010 } | |
1002 return true; | 1011 return true; |
1003 } | 1012 } |
1004 | 1013 |
1005 if (element->IsFrameOwnerElement() && | 1014 if (element->IsFrameOwnerElement() && |
1006 (!IsHTMLPlugInElement(*element) || !element->IsKeyboardFocusable())) { | 1015 (!IsHTMLPlugInElement(*element) || !element->IsKeyboardFocusable())) { |
1007 // We focus frames rather than frame owners. | 1016 // We focus frames rather than frame owners. |
1008 // FIXME: We should not focus frames that have no scrollbars, as focusing | 1017 // FIXME: We should not focus frames that have no scrollbars, as focusing |
1009 // them isn't useful to the user. | 1018 // them isn't useful to the user. |
1010 HTMLFrameOwnerElement* owner = ToHTMLFrameOwnerElement(element); | 1019 HTMLFrameOwnerElement* owner = ToHTMLFrameOwnerElement(element); |
1011 if (!owner->ContentFrame()) | 1020 if (!owner->ContentFrame()) |
1012 return false; | 1021 return false; |
1013 | 1022 |
1014 document->ClearFocusedElement(); | 1023 document->ClearFocusedElement(); |
1015 SetFocusedFrame(owner->ContentFrame()); | |
1016 | 1024 |
1017 // If contentFrame is remote, continue the search for focusable | 1025 // If ContentFrame is remote, continue the search for focusable elements in |
1018 // elements in that frame's process. | 1026 // that frame's process. The target contentFrame's process will grab focus |
1019 // clearFocusedElement() fires events that might detach the | 1027 // from inside AdvanceFocusInDocumentOrder(). |
1020 // contentFrame, hence the need to null-check it again. | 1028 // |
1029 // ClearFocusedElement() fires events that might detach the contentFrame, | |
alexmos
2017/04/19 16:57:33
nit: s/contentFrame/ContentFrame/
avallee
2017/04/19 16:58:51
Done.
| |
1030 // hence the need to null-check it again. | |
1021 if (owner->ContentFrame() && owner->ContentFrame()->IsRemoteFrame()) | 1031 if (owner->ContentFrame() && owner->ContentFrame()->IsRemoteFrame()) |
1022 ToRemoteFrame(owner->ContentFrame())->AdvanceFocus(type, frame); | 1032 ToRemoteFrame(owner->ContentFrame())->AdvanceFocus(type, frame); |
1033 else | |
1034 SetFocusedFrame(owner->ContentFrame()); | |
1023 | 1035 |
1024 return true; | 1036 return true; |
1025 } | 1037 } |
1026 | 1038 |
1027 DCHECK(element->IsFocusable()); | 1039 DCHECK(element->IsFocusable()); |
1028 | 1040 |
1029 // FIXME: It would be nice to just be able to call setFocusedElement(element) | 1041 // FIXME: It would be nice to just be able to call setFocusedElement(element) |
1030 // here, but we can't do that because some elements (e.g. HTMLInputElement | 1042 // here, but we can't do that because some elements (e.g. HTMLInputElement |
1031 // and HTMLTextAreaElement) do extra work in their focus() methods. | 1043 // and HTMLTextAreaElement) do extra work in their focus() methods. |
1032 Document& new_document = element->GetDocument(); | 1044 Document& new_document = element->GetDocument(); |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1396 it->FocusedFrameChanged(); | 1408 it->FocusedFrameChanged(); |
1397 } | 1409 } |
1398 | 1410 |
1399 DEFINE_TRACE(FocusController) { | 1411 DEFINE_TRACE(FocusController) { |
1400 visitor->Trace(page_); | 1412 visitor->Trace(page_); |
1401 visitor->Trace(focused_frame_); | 1413 visitor->Trace(focused_frame_); |
1402 visitor->Trace(focus_changed_observers_); | 1414 visitor->Trace(focus_changed_observers_); |
1403 } | 1415 } |
1404 | 1416 |
1405 } // namespace blink | 1417 } // namespace blink |
OLD | NEW |