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

Side by Side Diff: third_party/WebKit/Source/core/editing/FrameSelection.cpp

Issue 2201853002: Blink handle selection handle visibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixing nits and context menu Created 4 years, 1 month 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) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 Element* const editable = rootEditableElement(); 160 Element* const editable = rootEditableElement();
161 if (!editable) 161 if (!editable)
162 return; 162 return;
163 163
164 const VisiblePosition position = 164 const VisiblePosition position =
165 visiblePositionForContentsPoint(point, frame()); 165 visiblePositionForContentsPoint(point, frame());
166 SelectionInDOMTree::Builder builder; 166 SelectionInDOMTree::Builder builder;
167 builder.setIsDirectional(selection().isDirectional()); 167 builder.setIsDirectional(selection().isDirectional());
168 if (position.isNotNull()) 168 if (position.isNotNull())
169 builder.collapse(position.toPositionWithAffinity()); 169 builder.collapse(position.toPositionWithAffinity());
170 setSelection(builder.build(), CloseTyping | ClearTypingStyle | UserTriggered); 170 setSelection(builder.build(),
171 CloseTyping | ClearTypingStyle | UserTriggered | HandleVisible);
171 } 172 }
172 173
173 // TODO(xiaochengh): We should not use reference to return value. 174 // TODO(xiaochengh): We should not use reference to return value.
174 template <typename Strategy> 175 template <typename Strategy>
175 static void adjustEndpointsAtBidiBoundary( 176 static void adjustEndpointsAtBidiBoundary(
176 VisiblePositionTemplate<Strategy>& visibleBase, 177 VisiblePositionTemplate<Strategy>& visibleBase,
177 VisiblePositionTemplate<Strategy>& visibleExtent) { 178 VisiblePositionTemplate<Strategy>& visibleExtent) {
178 DCHECK(visibleBase.isValid()); 179 DCHECK(visibleBase.isValid());
179 DCHECK(visibleExtent.isValid()); 180 DCHECK(visibleExtent.isValid());
180 181
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) { 220 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) {
220 visibleExtent = createVisiblePosition(fromPositionInDOMTree<Strategy>( 221 visibleExtent = createVisiblePosition(fromPositionInDOMTree<Strategy>(
221 extent.positionAtRightBoundaryOfBiDiRun())); 222 extent.positionAtRightBoundaryOfBiDiRun()));
222 return; 223 return;
223 } 224 }
224 } 225 }
225 226
226 void FrameSelection::setNonDirectionalSelectionIfNeeded( 227 void FrameSelection::setNonDirectionalSelectionIfNeeded(
227 const VisibleSelectionInFlatTree& passedNewSelection, 228 const VisibleSelectionInFlatTree& passedNewSelection,
228 TextGranularity granularity, 229 TextGranularity granularity,
229 EndPointsAdjustmentMode endpointsAdjustmentMode) { 230 EndPointsAdjustmentMode endpointsAdjustmentMode,
231 HandleVisibility handleVisibility) {
230 VisibleSelectionInFlatTree newSelection = passedNewSelection; 232 VisibleSelectionInFlatTree newSelection = passedNewSelection;
231 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) || 233 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) ||
232 newSelection.isDirectional(); 234 newSelection.isDirectional();
233 235
234 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 236 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
235 // needs to be audited. See http://crbug.com/590369 for more details. 237 // needs to be audited. See http://crbug.com/590369 for more details.
236 document().updateStyleAndLayoutIgnorePendingStylesheets(); 238 document().updateStyleAndLayoutIgnorePendingStylesheets();
237 239
238 const PositionInFlatTree basePosition = 240 const PositionInFlatTree basePosition =
239 m_originalBaseInFlatTree.deepEquivalent(); 241 m_originalBaseInFlatTree.deepEquivalent();
(...skipping 17 matching lines...) Expand all
257 newSelection.setExtent(newExtent); 259 newSelection.setExtent(newExtent);
258 } else if (originalBase.isNotNull()) { 260 } else if (originalBase.isNotNull()) {
259 if (visibleSelection<EditingInFlatTreeStrategy>().base() == 261 if (visibleSelection<EditingInFlatTreeStrategy>().base() ==
260 newSelection.base()) 262 newSelection.base())
261 newSelection.setBase(originalBase); 263 newSelection.setBase(originalBase);
262 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); 264 m_originalBaseInFlatTree = VisiblePositionInFlatTree();
263 } 265 }
264 266
265 // Adjusting base and extent will make newSelection always directional 267 // Adjusting base and extent will make newSelection always directional
266 newSelection.setIsDirectional(isDirectional); 268 newSelection.setIsDirectional(isDirectional);
267 if (visibleSelection<EditingInFlatTreeStrategy>() == newSelection) 269 if (visibleSelection<EditingInFlatTreeStrategy>() == newSelection &&
270 m_handleVisibility == handleVisibility)
268 return; 271 return;
269 272
270 const SetSelectionOptions options = CloseTyping | ClearTypingStyle; 273 SetSelectionOptions options = CloseTyping | ClearTypingStyle;
274 if (handleVisibility == HandleVisibility::Visible)
275 options |= HandleVisible;
271 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded, 276 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
272 granularity); 277 granularity);
273 } 278 }
274 279
275 template <typename Strategy> 280 template <typename Strategy>
276 void FrameSelection::setSelectionAlgorithm( 281 void FrameSelection::setSelectionAlgorithm(
277 const VisibleSelectionTemplate<Strategy>& newSelection, 282 const VisibleSelectionTemplate<Strategy>& newSelection,
278 SetSelectionOptions options, 283 SetSelectionOptions options,
279 CursorAlignOnScroll align, 284 CursorAlignOnScroll align,
280 TextGranularity granularity) { 285 TextGranularity granularity) {
281 DCHECK(isAvailable()); 286 DCHECK(isAvailable());
282 DCHECK(newSelection.isValidFor(document())); 287 DCHECK(newSelection.isValidFor(document()));
283 const Document& currentDocument = document(); 288 const Document& currentDocument = document();
284 if (m_granularityStrategy && 289 if (m_granularityStrategy &&
285 (options & FrameSelection::DoNotClearStrategy) == 0) 290 (options & FrameSelection::DoNotClearStrategy) == 0)
286 m_granularityStrategy->Clear(); 291 m_granularityStrategy->Clear();
287 bool closeTyping = options & CloseTyping; 292 bool closeTyping = options & CloseTyping;
288 bool shouldClearTypingStyle = options & ClearTypingStyle; 293 bool shouldClearTypingStyle = options & ClearTypingStyle;
294 const HandleVisibility handleVisibility = options & HandleVisible
295 ? HandleVisibility::Visible
296 : HandleVisibility::NotVisible;
289 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); 297 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options);
290 298
291 // TODO(editing-dev): We should rename variable |s| to another name to avoid 299 // TODO(editing-dev): We should rename variable |s| to another name to avoid
292 // using one letter variable name. 300 // using one letter variable name.
293 VisibleSelectionTemplate<Strategy> s = newSelection; 301 VisibleSelectionTemplate<Strategy> s = newSelection;
294 if (shouldAlwaysUseDirectionalSelection(m_frame)) 302 if (shouldAlwaysUseDirectionalSelection(m_frame))
295 s.setIsDirectional(true); 303 s.setIsDirectional(true);
296 304
297 m_granularity = granularity; 305 m_granularity = granularity;
298 306
299 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 307 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
300 // |Editor| class. 308 // |Editor| class.
301 if (closeTyping) 309 if (closeTyping)
302 TypingCommand::closeTyping(m_frame); 310 TypingCommand::closeTyping(m_frame);
303 311
304 if (shouldClearTypingStyle) 312 if (shouldClearTypingStyle)
305 clearTypingStyle(); 313 clearTypingStyle();
306 314
307 if (m_selectionEditor->visibleSelection<Strategy>() == s) { 315 if (m_selectionEditor->visibleSelection<Strategy>() == s &&
316 m_handleVisibility == handleVisibility) {
308 // Even if selection was not changed, selection offsets may have been 317 // Even if selection was not changed, selection offsets may have been
309 // changed. 318 // changed.
310 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid(); 319 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid();
311 notifyLayoutObjectOfSelectionChange(userTriggered); 320 notifyLayoutObjectOfSelectionChange(userTriggered);
312 return; 321 return;
313 } 322 }
314 323
315 const VisibleSelectionTemplate<Strategy> oldSelection = 324 const VisibleSelectionTemplate<Strategy> oldSelection =
316 visibleSelection<Strategy>(); 325 visibleSelection<Strategy>();
317 const Position& oldSelectionStart = selection().start(); 326 const Position& oldSelectionStart = selection().start();
318 327
328 m_handleVisibility = handleVisibility;
319 m_selectionEditor->setVisibleSelection(s, options); 329 m_selectionEditor->setVisibleSelection(s, options);
320 m_frameCaret->setCaretRectNeedsUpdate(); 330 m_frameCaret->setCaretRectNeedsUpdate();
321 331
322 if (!s.isNone() && !(options & DoNotSetFocus)) { 332 if (!s.isNone() && !(options & DoNotSetFocus)) {
323 setFocusedNodeIfNeeded(); 333 setFocusedNodeIfNeeded();
324 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and 334 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and
325 // "FocusIn", |m_frame| may associate to another document. 335 // "FocusIn", |m_frame| may associate to another document.
326 if (!isAvailable() || document() != currentDocument) { 336 if (!isAvailable() || document() != currentDocument) {
327 // Once we get test case to reach here, we should change this 337 // Once we get test case to reach here, we should change this
328 // if-statement to |DCHECK()|. 338 // if-statement to |DCHECK()|.
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 853
844 void FrameSelection::dataWillChange(const CharacterData& node) { 854 void FrameSelection::dataWillChange(const CharacterData& node) {
845 m_frameCaret->dataWillChange(node); 855 m_frameCaret->dataWillChange(node);
846 } 856 }
847 857
848 void FrameSelection::paintCaret(GraphicsContext& context, 858 void FrameSelection::paintCaret(GraphicsContext& context,
849 const LayoutPoint& paintOffset) { 859 const LayoutPoint& paintOffset) {
850 m_frameCaret->paintCaret(context, paintOffset); 860 m_frameCaret->paintCaret(context, paintOffset);
851 } 861 }
852 862
853 bool FrameSelection::contains(const LayoutPoint& point) { 863 bool FrameSelection::contains(const HitTestResult& result) {
854 if (document().layoutViewItem().isNull())
855 return false;
856
857 // Treat a collapsed selection like no selection. 864 // Treat a collapsed selection like no selection.
858 const VisibleSelectionInFlatTree& visibleSelection = 865 const VisibleSelectionInFlatTree& visibleSelection =
859 this->visibleSelection<EditingInFlatTreeStrategy>(); 866 this->visibleSelection<EditingInFlatTreeStrategy>();
860 if (!visibleSelection.isRange()) 867 if (!visibleSelection.isRange())
861 return false; 868 return false;
862 869
863 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
864 HitTestResult result(request, point);
865 document().layoutViewItem().hitTest(result);
866 Node* innerNode = result.innerNode(); 870 Node* innerNode = result.innerNode();
867 if (!innerNode || !innerNode->layoutObject()) 871 if (!innerNode || !innerNode->layoutObject())
868 return false; 872 return false;
869 873
870 const VisiblePositionInFlatTree& visiblePos = 874 const VisiblePositionInFlatTree& visiblePos =
871 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>( 875 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>(
872 innerNode->layoutObject()->positionForPoint(result.localPoint()))); 876 innerNode->layoutObject()->positionForPoint(result.localPoint())));
873 if (visiblePos.isNull()) 877 if (visiblePos.isNull())
874 return false; 878 return false;
875 879
876 const VisiblePositionInFlatTree& visibleStart = 880 const VisiblePositionInFlatTree& visibleStart =
877 visibleSelection.visibleStart(); 881 visibleSelection.visibleStart();
878 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd(); 882 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd();
879 if (visibleStart.isNull() || visibleEnd.isNull()) 883 if (visibleStart.isNull() || visibleEnd.isNull())
880 return false; 884 return false;
881 885
882 const PositionInFlatTree& start = visibleStart.deepEquivalent(); 886 const PositionInFlatTree& start = visibleStart.deepEquivalent();
883 const PositionInFlatTree& end = visibleEnd.deepEquivalent(); 887 const PositionInFlatTree& end = visibleEnd.deepEquivalent();
884 const PositionInFlatTree& pos = visiblePos.deepEquivalent(); 888 const PositionInFlatTree& pos = visiblePos.deepEquivalent();
885 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; 889 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0;
886 } 890 }
887 891
892 bool FrameSelection::contains(const LayoutPoint& point) {
893 if (document().layoutViewItem().isNull())
894 return false;
895
896 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
897 HitTestResult result(request, point);
898 document().layoutViewItem().hitTest(result);
899
900 return contains(result);
901 }
902
888 // Workaround for the fact that it's hard to delete a frame. 903 // Workaround for the fact that it's hard to delete a frame.
889 // Call this after doing user-triggered selections to make it easy to delete the 904 // Call this after doing user-triggered selections to make it easy to delete the
890 // frame you entirely selected. Can't do this implicitly as part of every 905 // frame you entirely selected. Can't do this implicitly as part of every
891 // setSelection call because in some contexts it might not be good for the focus 906 // setSelection call because in some contexts it might not be good for the focus
892 // to move to another frame. So instead we call it from places where we are 907 // to move to another frame. So instead we call it from places where we are
893 // selecting with the mouse or the keyboard after setting the selection. 908 // selecting with the mouse or the keyboard after setting the selection.
894 void FrameSelection::selectFrameElementInParentIfFullySelected() { 909 void FrameSelection::selectFrameElementInParentIfFullySelected() {
895 // Find the parent frame; if there is none, then we have nothing to do. 910 // Find the parent frame; if there is none, then we have nothing to do.
896 Frame* parent = m_frame->tree().parent(); 911 Frame* parent = m_frame->tree().parent();
897 if (!parent) 912 if (!parent)
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 } 1432 }
1418 1433
1419 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) { 1434 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) {
1420 if (isNone()) 1435 if (isNone())
1421 return; 1436 return;
1422 1437
1423 VisibleSelection newSelection = 1438 VisibleSelection newSelection =
1424 granularityStrategy()->updateExtent(contentsPoint, m_frame); 1439 granularityStrategy()->updateExtent(contentsPoint, m_frame);
1425 setSelection(newSelection, 1440 setSelection(newSelection,
1426 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | 1441 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle |
1427 FrameSelection::DoNotClearStrategy | UserTriggered, 1442 FrameSelection::DoNotClearStrategy | UserTriggered |
1443 FrameSelection::HandleVisible,
1428 CursorAlignOnScroll::IfNeeded, CharacterGranularity); 1444 CursorAlignOnScroll::IfNeeded, CharacterGranularity);
1429 } 1445 }
1430 1446
1431 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition, 1447 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition,
1432 const VisiblePosition& extentPosition, 1448 const VisiblePosition& extentPosition,
1433 TextGranularity granularity) { 1449 TextGranularity granularity) {
1434 VisibleSelection newSelection = 1450 VisibleSelection newSelection =
1435 createVisibleSelection(basePosition, extentPosition); 1451 createVisibleSelection(basePosition, extentPosition);
1436 newSelection.expandUsingGranularity(granularity); 1452 newSelection.expandUsingGranularity(granularity);
1437 1453
1438 if (newSelection.isNone()) 1454 if (newSelection.isNone())
1439 return; 1455 return;
1440 1456
1441 setSelection(newSelection, CloseTyping | ClearTypingStyle, 1457 SetSelectionOptions options = CloseTyping | ClearTypingStyle;
1442 CursorAlignOnScroll::IfNeeded, granularity); 1458 if (isHandleVisible())
1459 options |= HandleVisible;
1460 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
1461 granularity);
1443 } 1462 }
1444 1463
1445 void FrameSelection::updateIfNeeded() { 1464 void FrameSelection::updateIfNeeded() {
1446 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); 1465 DCHECK(!m_frame->document()->needsLayoutTreeUpdate());
1447 m_selectionEditor->updateIfNeeded(); 1466 m_selectionEditor->updateIfNeeded();
1448 } 1467 }
1449 1468
1450 void FrameSelection::setCaretVisible(bool caretIsVisible) { 1469 void FrameSelection::setCaretVisible(bool caretIsVisible) {
1451 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible 1470 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible
1452 : CaretVisibility::Hidden); 1471 : CaretVisibility::Hidden);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 } 1504 }
1486 1505
1487 void showTree(const blink::FrameSelection* sel) { 1506 void showTree(const blink::FrameSelection* sel) {
1488 if (sel) 1507 if (sel)
1489 sel->showTreeForThis(); 1508 sel->showTreeForThis();
1490 else 1509 else
1491 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; 1510 LOG(INFO) << "Cannot showTree for <null> FrameSelection.";
1492 } 1511 }
1493 1512
1494 #endif 1513 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698