Chromium Code Reviews| 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 initialFocus = to->tree().parent() == from; | |
| 939 | |
| 940 return advanceFocusInDocumentOrder(to, start, type, initialFocus, | |
| 937 sourceCapabilities); | 941 sourceCapabilities); |
| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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. |
| 1006 setFocusedFrame(document->frame()); | |
| 1007 dispatchFocusEvent(*document, *element); | |
|
alexmos
2017/04/05 00:21:13
Sanity check: could this have any side effects (li
avallee
2017/04/05 15:13:00
It could mean an extra focus event, but I don't kn
alexmos
2017/04/05 18:08:33
Acknowledged.
| |
| 1002 return true; | 1008 return true; |
| 1003 } | 1009 } |
| 1004 | 1010 |
| 1005 if (element->isFrameOwnerElement() && | 1011 if (element->isFrameOwnerElement() && |
| 1006 (!isHTMLPlugInElement(*element) || !element->isKeyboardFocusable())) { | 1012 (!isHTMLPlugInElement(*element) || !element->isKeyboardFocusable())) { |
| 1007 // We focus frames rather than frame owners. | 1013 // We focus frames rather than frame owners. |
| 1008 // FIXME: We should not focus frames that have no scrollbars, as focusing | 1014 // FIXME: We should not focus frames that have no scrollbars, as focusing |
| 1009 // them isn't useful to the user. | 1015 // them isn't useful to the user. |
| 1010 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(element); | 1016 HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(element); |
| 1011 if (!owner->contentFrame()) | 1017 if (!owner->contentFrame()) |
| 1012 return false; | 1018 return false; |
| 1013 | 1019 |
| 1014 document->clearFocusedElement(); | 1020 document->clearFocusedElement(); |
| 1015 setFocusedFrame(owner->contentFrame()); | |
| 1016 | 1021 |
| 1017 // If contentFrame is remote, continue the search for focusable | 1022 // If contentFrame is remote, continue the search for focusable |
| 1018 // elements in that frame's process. | 1023 // elements in that frame's process. |
|
alexmos
2017/04/05 00:21:13
Might be worth also mentioning that contentFrame w
avallee
2017/04/05 15:13:00
Yes, it would either be set up above where your ot
| |
| 1019 // clearFocusedElement() fires events that might detach the | 1024 // clearFocusedElement() fires events that might detach the |
| 1020 // contentFrame, hence the need to null-check it again. | 1025 // contentFrame, hence the need to null-check it again. |
| 1021 if (owner->contentFrame() && owner->contentFrame()->isRemoteFrame()) | 1026 if (owner->contentFrame() && owner->contentFrame()->isRemoteFrame()) |
| 1022 toRemoteFrame(owner->contentFrame())->advanceFocus(type, frame); | 1027 toRemoteFrame(owner->contentFrame())->advanceFocus(type, frame); |
| 1028 else | |
| 1029 setFocusedFrame(owner->contentFrame()); | |
| 1023 | 1030 |
| 1024 return true; | 1031 return true; |
| 1025 } | 1032 } |
| 1026 | 1033 |
| 1027 DCHECK(element->isFocusable()); | 1034 DCHECK(element->isFocusable()); |
| 1028 | 1035 |
| 1029 // FIXME: It would be nice to just be able to call setFocusedElement(element) | 1036 // 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 | 1037 // here, but we can't do that because some elements (e.g. HTMLInputElement |
| 1031 // and HTMLTextAreaElement) do extra work in their focus() methods. | 1038 // and HTMLTextAreaElement) do extra work in their focus() methods. |
| 1032 Document& newDocument = element->document(); | 1039 Document& newDocument = element->document(); |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1418 it->focusedFrameChanged(); | 1425 it->focusedFrameChanged(); |
| 1419 } | 1426 } |
| 1420 | 1427 |
| 1421 DEFINE_TRACE(FocusController) { | 1428 DEFINE_TRACE(FocusController) { |
| 1422 visitor->trace(m_page); | 1429 visitor->trace(m_page); |
| 1423 visitor->trace(m_focusedFrame); | 1430 visitor->trace(m_focusedFrame); |
| 1424 visitor->trace(m_focusChangedObservers); | 1431 visitor->trace(m_focusChangedObservers); |
| 1425 } | 1432 } |
| 1426 | 1433 |
| 1427 } // namespace blink | 1434 } // namespace blink |
| OLD | NEW |