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

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

Issue 2616623002: Do not send redundant selectionchange-events (decouple focus) (Closed)
Patch Set: Move isSelectionInDocument() and selectionHasFocus() to EditingUtilities Created 3 years, 9 months 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 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
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() && !hasEditableStyle(*element->toNode())) {
1044 // TODO(blink-editing): Remove this clear(), crbug.com/692898.
yosin_UTC9 2017/03/21 06:49:59 nit: s/blink-editing/editing-dev/
hugoh_UTC2 2017/03/22 02:54:47 Done.
1045 focusedFrame()->selection().clear();
1046 }
1043 element->focus( 1047 element->focus(
1044 FocusParams(SelectionBehaviorOnFocus::Reset, type, sourceCapabilities)); 1048 FocusParams(SelectionBehaviorOnFocus::Reset, type, sourceCapabilities));
1045 return true; 1049 return true;
1046 } 1050 }
1047 1051
1048 Element* FocusController::findFocusableElement(WebFocusType type, 1052 Element* FocusController::findFocusableElement(WebFocusType type,
1049 Element& element) { 1053 Element& element) {
1050 // FIXME: No spacial navigation code yet. 1054 // FIXME: No spacial navigation code yet.
1051 DCHECK(type == WebFocusTypeForward || type == WebFocusTypeBackward); 1055 DCHECK(type == WebFocusTypeForward || type == WebFocusTypeBackward);
1052 ScopedFocusNavigation scope = ScopedFocusNavigation::createFor(element); 1056 ScopedFocusNavigation scope = ScopedFocusNavigation::createFor(element);
1053 return findFocusableElementAcrossFocusScopes(type, scope); 1057 return findFocusableElementAcrossFocusScopes(type, scope);
1054 } 1058 }
1055 1059
1056 Element* FocusController::findFocusableElementInShadowHost( 1060 Element* FocusController::findFocusableElementInShadowHost(
1057 const Element& shadowHost) { 1061 const Element& shadowHost) {
1058 DCHECK(shadowHost.authorShadowRoot()); 1062 DCHECK(shadowHost.authorShadowRoot());
1059 ScopedFocusNavigation scope = 1063 ScopedFocusNavigation scope =
1060 ScopedFocusNavigation::ownedByShadowHost(shadowHost); 1064 ScopedFocusNavigation::ownedByShadowHost(shadowHost);
1061 return findFocusableElementAcrossFocusScopes(WebFocusTypeForward, scope); 1065 return findFocusableElementAcrossFocusScopes(WebFocusTypeForward, scope);
1062 } 1066 }
1063 1067
1064 static bool relinquishesEditingFocus(const Element& element) { 1068 static bool relinquishesEditingFocus(const Element& element) {
1065 DCHECK(hasEditableStyle(element)); 1069 DCHECK(hasEditableStyle(element));
1066 return element.document().frame() && rootEditableElement(element); 1070 return element.document().frame() && rootEditableElement(element);
1067 } 1071 }
1068 1072
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 const SelectionInDOMTree& selectionInDOMTree = selection.selectionInDOMTree();
1080 if (selectionInDOMTree.isNone())
1081 return;
1082
1083 Node* selectionStartNode = selectionInDOMTree.base().anchorNode();
1084 if (selectionStartNode == newFocusedElement ||
1085 selectionStartNode->isDescendantOf(newFocusedElement))
1086 return;
1087
1088 if (!enclosingTextControl(selectionStartNode))
1089 return;
1090
1091 if (selectionStartNode->isInShadowTree() &&
1092 selectionStartNode->ownerShadowHost() == newFocusedElement)
1093 return;
1094
1095 selection.clear();
1096 }
1097
1098 bool FocusController::setFocusedElement(Element* element, 1073 bool FocusController::setFocusedElement(Element* element,
1099 Frame* newFocusedFrame) { 1074 Frame* newFocusedFrame) {
1100 return setFocusedElement( 1075 return setFocusedElement(
1101 element, newFocusedFrame, 1076 element, newFocusedFrame,
1102 FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr)); 1077 FocusParams(SelectionBehaviorOnFocus::None, WebFocusTypeNone, nullptr));
1103 } 1078 }
1104 1079
1105 bool FocusController::setFocusedElement(Element* element, 1080 bool FocusController::setFocusedElement(Element* element,
1106 Frame* newFocusedFrame, 1081 Frame* newFocusedFrame,
1107 const FocusParams& params) { 1082 const FocusParams& params) {
(...skipping 16 matching lines...) Expand all
1124 Document* newDocument = nullptr; 1099 Document* newDocument = nullptr;
1125 if (element) 1100 if (element)
1126 newDocument = &element->document(); 1101 newDocument = &element->document();
1127 else if (newFocusedFrame && newFocusedFrame->isLocalFrame()) 1102 else if (newFocusedFrame && newFocusedFrame->isLocalFrame())
1128 newDocument = toLocalFrame(newFocusedFrame)->document(); 1103 newDocument = toLocalFrame(newFocusedFrame)->document();
1129 1104
1130 if (newDocument && oldDocument == newDocument && 1105 if (newDocument && oldDocument == newDocument &&
1131 newDocument->focusedElement() == element) 1106 newDocument->focusedElement() == element)
1132 return true; 1107 return true;
1133 1108
1134 if (newFocusedFrame && newFocusedFrame->isLocalFrame())
1135 clearSelectionIfNeeded(oldFocusedFrame, toLocalFrame(newFocusedFrame),
1136 element);
1137
1138 if (oldDocument && oldDocument != newDocument) 1109 if (oldDocument && oldDocument != newDocument)
1139 oldDocument->clearFocusedElement(); 1110 oldDocument->clearFocusedElement();
1140 1111
1141 if (newFocusedFrame && !newFocusedFrame->page()) { 1112 if (newFocusedFrame && !newFocusedFrame->page()) {
1142 setFocusedFrame(nullptr); 1113 setFocusedFrame(nullptr);
1143 return false; 1114 return false;
1144 } 1115 }
1145 setFocusedFrame(newFocusedFrame); 1116 setFocusedFrame(newFocusedFrame);
1146 1117
1147 if (newDocument) { 1118 if (newDocument) {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1344 if (focusCandidate.isOffscreenAfterScrolling) { 1315 if (focusCandidate.isOffscreenAfterScrolling) {
1345 Node* container = focusCandidate.enclosingScrollableBox; 1316 Node* container = focusCandidate.enclosingScrollableBox;
1346 scrollInDirection(container, type); 1317 scrollInDirection(container, type);
1347 return true; 1318 return true;
1348 } 1319 }
1349 1320
1350 // We found a new focus node, navigate to it. 1321 // We found a new focus node, navigate to it.
1351 Element* element = toElement(focusCandidate.focusableNode); 1322 Element* element = toElement(focusCandidate.focusableNode);
1352 DCHECK(element); 1323 DCHECK(element);
1353 1324
1325 if (!element->isTextControl() && !hasEditableStyle(*element->toNode())) {
1326 // TODO(blink-editing): Remove this clear(), crbug.com/692898.
1327 focusedFrame()->selection().clear();
1328 }
1354 element->focus(FocusParams(SelectionBehaviorOnFocus::Reset, type, nullptr)); 1329 element->focus(FocusParams(SelectionBehaviorOnFocus::Reset, type, nullptr));
1355 return true; 1330 return true;
1356 } 1331 }
1357 1332
1358 bool FocusController::advanceFocusDirectionally(WebFocusType type) { 1333 bool FocusController::advanceFocusDirectionally(WebFocusType type) {
1359 // FIXME: Directional focus changes don't yet work with RemoteFrames. 1334 // FIXME: Directional focus changes don't yet work with RemoteFrames.
1360 if (!focusedOrMainFrame()->isLocalFrame()) 1335 if (!focusedOrMainFrame()->isLocalFrame())
1361 return false; 1336 return false;
1362 LocalFrame* curFrame = toLocalFrame(focusedOrMainFrame()); 1337 LocalFrame* curFrame = toLocalFrame(focusedOrMainFrame());
1363 DCHECK(curFrame); 1338 DCHECK(curFrame);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 it->focusedFrameChanged(); 1390 it->focusedFrameChanged();
1416 } 1391 }
1417 1392
1418 DEFINE_TRACE(FocusController) { 1393 DEFINE_TRACE(FocusController) {
1419 visitor->trace(m_page); 1394 visitor->trace(m_page);
1420 visitor->trace(m_focusedFrame); 1395 visitor->trace(m_focusedFrame);
1421 visitor->trace(m_focusChangedObservers); 1396 visitor->trace(m_focusChangedObservers);
1422 } 1397 }
1423 1398
1424 } // namespace blink 1399 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698