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 |