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 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1033 Document& newDocument = element->document(); | 1033 Document& newDocument = element->document(); |
| 1034 | 1034 |
| 1035 if (&newDocument != document) { | 1035 if (&newDocument != document) { |
| 1036 // Focus is going away from this document, so clear the focused element. | 1036 // Focus is going away from this document, so clear the focused element. |
| 1037 document->clearFocusedElement(); | 1037 document->clearFocusedElement(); |
| 1038 document->setSequentialFocusNavigationStartingPoint(nullptr); | 1038 document->setSequentialFocusNavigationStartingPoint(nullptr); |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 setFocusedFrame(newDocument.frame()); | 1041 setFocusedFrame(newDocument.frame()); |
| 1042 | 1042 |
| 1043 if (!element->isTextControl()) { | |
| 1044 // When tab-key makes focus jump from <input> to <button> (or to any other | |
| 1045 // non-editable element) we clear the <input>'s selection. When jumping to | |
| 1046 // an editable element, this clear() is not needed because clearing happens | |
| 1047 // when the new element takes and resets the selection. | |
| 1048 FrameSelection& selection = focusedFrame()->selection(); | |
|
yosin_UTC9
2017/02/13 08:09:00
I'm OK this if Firefox and Edge do so.
kochi@, wha
hugoh_UTC2
2017/02/13 09:18:52
Visually yes! That is why we cannot remove selecti
hugoh_UTC2
2017/02/13 09:55:52
Maybe a selection.hide() would be better here? Fir
yosin_UTC9
2017/02/13 10:18:55
If we don't paint selection if it doesn't have foc
hugoh_UTC2
2017/02/14 10:32:50
Good idea. I supposed you meant ||, not && ? That
| |
| 1049 selection.clear(); | |
| 1050 } | |
| 1043 element->focus( | 1051 element->focus( |
| 1044 FocusParams(SelectionBehaviorOnFocus::Reset, type, sourceCapabilities)); | 1052 FocusParams(SelectionBehaviorOnFocus::Reset, type, sourceCapabilities)); |
| 1045 return true; | 1053 return true; |
| 1046 } | 1054 } |
| 1047 | 1055 |
| 1048 Element* FocusController::findFocusableElement(WebFocusType type, | 1056 Element* FocusController::findFocusableElement(WebFocusType type, |
| 1049 Element& element) { | 1057 Element& element) { |
| 1050 // FIXME: No spacial navigation code yet. | 1058 // FIXME: No spacial navigation code yet. |
| 1051 DCHECK(type == WebFocusTypeForward || type == WebFocusTypeBackward); | 1059 DCHECK(type == WebFocusTypeForward || type == WebFocusTypeBackward); |
| 1052 ScopedFocusNavigation scope = ScopedFocusNavigation::createFor(element); | 1060 ScopedFocusNavigation scope = ScopedFocusNavigation::createFor(element); |
| 1053 return findFocusableElementAcrossFocusScopes(type, scope); | 1061 return findFocusableElementAcrossFocusScopes(type, scope); |
| 1054 } | 1062 } |
| 1055 | 1063 |
| 1056 Element* FocusController::findFocusableElementInShadowHost( | 1064 Element* FocusController::findFocusableElementInShadowHost( |
| 1057 const Element& shadowHost) { | 1065 const Element& shadowHost) { |
| 1058 DCHECK(shadowHost.authorShadowRoot()); | 1066 DCHECK(shadowHost.authorShadowRoot()); |
| 1059 ScopedFocusNavigation scope = | 1067 ScopedFocusNavigation scope = |
| 1060 ScopedFocusNavigation::ownedByShadowHost(shadowHost); | 1068 ScopedFocusNavigation::ownedByShadowHost(shadowHost); |
| 1061 return findFocusableElementAcrossFocusScopes(WebFocusTypeForward, scope); | 1069 return findFocusableElementAcrossFocusScopes(WebFocusTypeForward, scope); |
| 1062 } | 1070 } |
| 1063 | 1071 |
| 1064 static bool relinquishesEditingFocus(const Element& element) { | 1072 static bool relinquishesEditingFocus(const Element& element) { |
| 1065 DCHECK(hasEditableStyle(element)); | 1073 DCHECK(hasEditableStyle(element)); |
| 1066 return element.document().frame() && rootEditableElement(element); | 1074 return element.document().frame() && rootEditableElement(element); |
| 1067 } | 1075 } |
| 1068 | 1076 |
| 1069 static void clearSelectionIfNeeded(LocalFrame* oldFocusedFrame, | |
| 1070 LocalFrame* newFocusedFrame, | |
| 1071 Element* newFocusedElement) { | |
| 1072 if (!oldFocusedFrame || !newFocusedFrame) | |
| 1073 return; | |
| 1074 | |
| 1075 if (oldFocusedFrame->document() != newFocusedFrame->document()) | |
| 1076 return; | |
| 1077 | |
| 1078 FrameSelection& selection = oldFocusedFrame->selection(); | |
| 1079 if (selection.isNone()) | |
| 1080 return; | |
| 1081 | |
| 1082 Node* selectionStartNode = selection.selection().start().anchorNode(); | |
| 1083 if (selectionStartNode == newFocusedElement || | |
| 1084 selectionStartNode->isDescendantOf(newFocusedElement)) | |
| 1085 return; | |
| 1086 | |
| 1087 if (!enclosingTextControl(selectionStartNode)) | |
| 1088 return; | |
| 1089 | |
| 1090 if (selectionStartNode->isInShadowTree() && | |
| 1091 selectionStartNode->ownerShadowHost() == newFocusedElement) | |
| 1092 return; | |
| 1093 | |
| 1094 selection.clear(); | |
| 1095 } | |
| 1096 | |
| 1097 bool FocusController::setFocusedElement(Element* element, | 1077 bool FocusController::setFocusedElement(Element* element, |
| 1098 Frame* newFocusedFrame) { | 1078 Frame* newFocusedFrame) { |
| 1099 return setFocusedElement( | 1079 return setFocusedElement( |
| 1100 element, newFocusedFrame, | 1080 element, newFocusedFrame, |
| 1101 FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr)); | 1081 FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr)); |
| 1102 } | 1082 } |
| 1103 | 1083 |
| 1104 bool FocusController::setFocusedElement(Element* element, | 1084 bool FocusController::setFocusedElement(Element* element, |
| 1105 Frame* newFocusedFrame, | 1085 Frame* newFocusedFrame, |
| 1106 const FocusParams& params) { | 1086 const FocusParams& params) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1123 Document* newDocument = nullptr; | 1103 Document* newDocument = nullptr; |
| 1124 if (element) | 1104 if (element) |
| 1125 newDocument = &element->document(); | 1105 newDocument = &element->document(); |
| 1126 else if (newFocusedFrame && newFocusedFrame->isLocalFrame()) | 1106 else if (newFocusedFrame && newFocusedFrame->isLocalFrame()) |
| 1127 newDocument = toLocalFrame(newFocusedFrame)->document(); | 1107 newDocument = toLocalFrame(newFocusedFrame)->document(); |
| 1128 | 1108 |
| 1129 if (newDocument && oldDocument == newDocument && | 1109 if (newDocument && oldDocument == newDocument && |
| 1130 newDocument->focusedElement() == element) | 1110 newDocument->focusedElement() == element) |
| 1131 return true; | 1111 return true; |
| 1132 | 1112 |
| 1133 if (newFocusedFrame && newFocusedFrame->isLocalFrame()) | |
| 1134 clearSelectionIfNeeded(oldFocusedFrame, toLocalFrame(newFocusedFrame), | |
| 1135 element); | |
| 1136 | |
| 1137 if (oldDocument && oldDocument != newDocument) | 1113 if (oldDocument && oldDocument != newDocument) |
| 1138 oldDocument->clearFocusedElement(); | 1114 oldDocument->clearFocusedElement(); |
| 1139 | 1115 |
| 1140 if (newFocusedFrame && !newFocusedFrame->page()) { | 1116 if (newFocusedFrame && !newFocusedFrame->page()) { |
| 1141 setFocusedFrame(nullptr); | 1117 setFocusedFrame(nullptr); |
| 1142 return false; | 1118 return false; |
| 1143 } | 1119 } |
| 1144 setFocusedFrame(newFocusedFrame); | 1120 setFocusedFrame(newFocusedFrame); |
| 1145 | 1121 |
| 1146 if (newDocument) { | 1122 if (newDocument) { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1343 if (focusCandidate.isOffscreenAfterScrolling) { | 1319 if (focusCandidate.isOffscreenAfterScrolling) { |
| 1344 Node* container = focusCandidate.enclosingScrollableBox; | 1320 Node* container = focusCandidate.enclosingScrollableBox; |
| 1345 scrollInDirection(container, type); | 1321 scrollInDirection(container, type); |
| 1346 return true; | 1322 return true; |
| 1347 } | 1323 } |
| 1348 | 1324 |
| 1349 // We found a new focus node, navigate to it. | 1325 // We found a new focus node, navigate to it. |
| 1350 Element* element = toElement(focusCandidate.focusableNode); | 1326 Element* element = toElement(focusCandidate.focusableNode); |
| 1351 DCHECK(element); | 1327 DCHECK(element); |
| 1352 | 1328 |
| 1329 if (!element->isTextControl()) { | |
| 1330 // Spatial navigation, just as "tab navigation", clears the selection as it | |
| 1331 // moves focus. When jumping to an editable element, this clear() is not | |
| 1332 // needed because clearing happens when the new element takes and resets the | |
| 1333 // selection. | |
| 1334 FrameSelection& selection = focusedFrame()->selection(); | |
|
yosin_UTC9
2017/02/13 08:09:00
I'm OK this if Firefox and Edge do so.
kochi@, wha
hugoh_UTC2
2017/02/13 09:18:52
advanceFocusDirectionallyInContainer() only runs f
| |
| 1335 selection.clear(); | |
| 1336 } | |
| 1353 element->focus(FocusParams(SelectionBehaviorOnFocus::Reset, type, nullptr)); | 1337 element->focus(FocusParams(SelectionBehaviorOnFocus::Reset, type, nullptr)); |
| 1354 return true; | 1338 return true; |
| 1355 } | 1339 } |
| 1356 | 1340 |
| 1357 bool FocusController::advanceFocusDirectionally(WebFocusType type) { | 1341 bool FocusController::advanceFocusDirectionally(WebFocusType type) { |
| 1358 // FIXME: Directional focus changes don't yet work with RemoteFrames. | 1342 // FIXME: Directional focus changes don't yet work with RemoteFrames. |
| 1359 if (!focusedOrMainFrame()->isLocalFrame()) | 1343 if (!focusedOrMainFrame()->isLocalFrame()) |
| 1360 return false; | 1344 return false; |
| 1361 LocalFrame* curFrame = toLocalFrame(focusedOrMainFrame()); | 1345 LocalFrame* curFrame = toLocalFrame(focusedOrMainFrame()); |
| 1362 DCHECK(curFrame); | 1346 DCHECK(curFrame); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1414 it->focusedFrameChanged(); | 1398 it->focusedFrameChanged(); |
| 1415 } | 1399 } |
| 1416 | 1400 |
| 1417 DEFINE_TRACE(FocusController) { | 1401 DEFINE_TRACE(FocusController) { |
| 1418 visitor->trace(m_page); | 1402 visitor->trace(m_page); |
| 1419 visitor->trace(m_focusedFrame); | 1403 visitor->trace(m_focusedFrame); |
| 1420 visitor->trace(m_focusChangedObservers); | 1404 visitor->trace(m_focusChangedObservers); |
| 1421 } | 1405 } |
| 1422 | 1406 |
| 1423 } // namespace blink | 1407 } // namespace blink |
| OLD | NEW |