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

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 clear handles 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 extent.positionAtRightBoundaryOfBiDiRun())); 222 extent.positionAtRightBoundaryOfBiDiRun()));
222 return; 223 return;
223 } 224 }
224 } 225 }
225 226
226 // TODO(yosin): We should move |setNonDirectionalSelectionIfNeeded()| to 227 // TODO(yosin): We should move |setNonDirectionalSelectionIfNeeded()| to
227 // "SelectionController.cpp" 228 // "SelectionController.cpp"
228 void SelectionController::setNonDirectionalSelectionIfNeeded( 229 void SelectionController::setNonDirectionalSelectionIfNeeded(
229 const VisibleSelectionInFlatTree& passedNewSelection, 230 const VisibleSelectionInFlatTree& passedNewSelection,
230 TextGranularity granularity, 231 TextGranularity granularity,
231 EndPointsAdjustmentMode endpointsAdjustmentMode) { 232 EndPointsAdjustmentMode endpointsAdjustmentMode,
233 HandleVisibility handleVisibility) {
232 VisibleSelectionInFlatTree newSelection = passedNewSelection; 234 VisibleSelectionInFlatTree newSelection = passedNewSelection;
233 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) || 235 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) ||
234 newSelection.isDirectional(); 236 newSelection.isDirectional();
235 237
236 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 238 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
237 // needs to be audited. See http://crbug.com/590369 for more details. 239 // needs to be audited. See http://crbug.com/590369 for more details.
238 document().updateStyleAndLayoutIgnorePendingStylesheets(); 240 document().updateStyleAndLayoutIgnorePendingStylesheets();
239 241
240 const PositionInFlatTree basePosition = 242 const PositionInFlatTree basePosition =
241 m_originalBaseInFlatTree.deepEquivalent(); 243 m_originalBaseInFlatTree.deepEquivalent();
(...skipping 17 matching lines...) Expand all
259 newSelection.setExtent(newExtent); 261 newSelection.setExtent(newExtent);
260 } else if (originalBase.isNotNull()) { 262 } else if (originalBase.isNotNull()) {
261 if (selection().visibleSelection<EditingInFlatTreeStrategy>().base() == 263 if (selection().visibleSelection<EditingInFlatTreeStrategy>().base() ==
262 newSelection.base()) 264 newSelection.base())
263 newSelection.setBase(originalBase); 265 newSelection.setBase(originalBase);
264 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); 266 m_originalBaseInFlatTree = VisiblePositionInFlatTree();
265 } 267 }
266 268
267 // Adjusting base and extent will make newSelection always directional 269 // Adjusting base and extent will make newSelection always directional
268 newSelection.setIsDirectional(isDirectional); 270 newSelection.setIsDirectional(isDirectional);
269 if (selection().visibleSelection<EditingInFlatTreeStrategy>() == newSelection) 271 const bool isHandleVisible = handleVisibility == HandleVisibility::Visible;
272 if (selection().visibleSelection<EditingInFlatTreeStrategy>() ==
273 newSelection &&
274 selection().isHandleVisible() == isHandleVisible)
270 return; 275 return;
271 276
272 const FrameSelection::SetSelectionOptions options = 277 FrameSelection::SetSelectionOptions options =
273 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle; 278 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle;
279 if (isHandleVisible)
280 options |= FrameSelection::HandleVisible;
274 selection().setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded, 281 selection().setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
275 granularity); 282 granularity);
276 } 283 }
277 284
278 template <typename Strategy> 285 template <typename Strategy>
279 void FrameSelection::setSelectionAlgorithm( 286 void FrameSelection::setSelectionAlgorithm(
280 const VisibleSelectionTemplate<Strategy>& newSelection, 287 const VisibleSelectionTemplate<Strategy>& newSelection,
281 SetSelectionOptions options, 288 SetSelectionOptions options,
282 CursorAlignOnScroll align, 289 CursorAlignOnScroll align,
283 TextGranularity granularity) { 290 TextGranularity granularity) {
284 DCHECK(isAvailable()); 291 DCHECK(isAvailable());
285 DCHECK(newSelection.isValidFor(document())); 292 DCHECK(newSelection.isValidFor(document()));
286 const Document& currentDocument = document(); 293 const Document& currentDocument = document();
287 if (m_granularityStrategy && 294 if (m_granularityStrategy &&
288 (options & FrameSelection::DoNotClearStrategy) == 0) 295 (options & FrameSelection::DoNotClearStrategy) == 0)
289 m_granularityStrategy->Clear(); 296 m_granularityStrategy->Clear();
290 bool closeTyping = options & CloseTyping; 297 bool closeTyping = options & CloseTyping;
291 bool shouldClearTypingStyle = options & ClearTypingStyle; 298 bool shouldClearTypingStyle = options & ClearTypingStyle;
299 const HandleVisibility handleVisibility = options & HandleVisible
300 ? HandleVisibility::Visible
301 : HandleVisibility::NotVisible;
292 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); 302 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options);
293 303
294 // TODO(editing-dev): We should rename variable |s| to another name to avoid 304 // TODO(editing-dev): We should rename variable |s| to another name to avoid
295 // using one letter variable name. 305 // using one letter variable name.
296 VisibleSelectionTemplate<Strategy> s = newSelection; 306 VisibleSelectionTemplate<Strategy> s = newSelection;
297 if (shouldAlwaysUseDirectionalSelection(m_frame)) 307 if (shouldAlwaysUseDirectionalSelection(m_frame))
298 s.setIsDirectional(true); 308 s.setIsDirectional(true);
299 309
300 m_granularity = granularity; 310 m_granularity = granularity;
301 311
302 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 312 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
303 // |Editor| class. 313 // |Editor| class.
304 if (closeTyping) 314 if (closeTyping)
305 TypingCommand::closeTyping(m_frame); 315 TypingCommand::closeTyping(m_frame);
306 316
307 if (shouldClearTypingStyle) 317 if (shouldClearTypingStyle)
308 clearTypingStyle(); 318 clearTypingStyle();
309 319
310 if (m_selectionEditor->visibleSelection<Strategy>() == s) { 320 if (m_selectionEditor->visibleSelection<Strategy>() == s &&
321 m_handleVisibility == handleVisibility) {
311 // Even if selection was not changed, selection offsets may have been 322 // Even if selection was not changed, selection offsets may have been
312 // changed. 323 // changed.
313 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid(); 324 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid();
314 notifyLayoutObjectOfSelectionChange(userTriggered); 325 notifyLayoutObjectOfSelectionChange(userTriggered);
315 return; 326 return;
316 } 327 }
317 328
318 const VisibleSelectionTemplate<Strategy> oldSelection = 329 const VisibleSelectionTemplate<Strategy> oldSelection =
319 visibleSelection<Strategy>(); 330 visibleSelection<Strategy>();
320 const Position& oldSelectionStart = selection().start(); 331 const Position& oldSelectionStart = selection().start();
321 332
333 m_handleVisibility = handleVisibility;
322 m_selectionEditor->setVisibleSelection(s, options); 334 m_selectionEditor->setVisibleSelection(s, options);
323 m_frameCaret->setCaretRectNeedsUpdate(); 335 m_frameCaret->setCaretRectNeedsUpdate();
324 336
325 if (!s.isNone() && !(options & DoNotSetFocus)) { 337 if (!s.isNone() && !(options & DoNotSetFocus)) {
326 setFocusedNodeIfNeeded(); 338 setFocusedNodeIfNeeded();
327 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and 339 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and
328 // "FocusIn", |m_frame| may associate to another document. 340 // "FocusIn", |m_frame| may associate to another document.
329 if (!isAvailable() || document() != currentDocument) { 341 if (!isAvailable() || document() != currentDocument) {
330 // Once we get test case to reach here, we should change this 342 // Once we get test case to reach here, we should change this
331 // if-statement to |DCHECK()|. 343 // if-statement to |DCHECK()|.
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 return true; 811 return true;
800 } 812 }
801 813
802 void FrameSelection::clear() { 814 void FrameSelection::clear() {
803 m_granularity = CharacterGranularity; 815 m_granularity = CharacterGranularity;
804 if (m_granularityStrategy) 816 if (m_granularityStrategy)
805 m_granularityStrategy->Clear(); 817 m_granularityStrategy->Clear();
806 setSelection(VisibleSelection()); 818 setSelection(VisibleSelection());
807 } 819 }
808 820
821 void FrameSelection::clearHandles() {
822 m_handleVisibility = HandleVisibility::NotVisible;
823 notifyCompositorForSelectionChange();
824 }
825
809 void FrameSelection::documentAttached(Document* document) { 826 void FrameSelection::documentAttached(Document* document) {
810 DCHECK(document); 827 DCHECK(document);
811 DCHECK(!m_document) << "FrameSelection is already attached to " << m_document; 828 DCHECK(!m_document) << "FrameSelection is already attached to " << m_document;
812 m_document = document; 829 m_document = document;
813 m_selectionEditor->documentAttached(document); 830 m_selectionEditor->documentAttached(document);
814 } 831 }
815 832
816 void FrameSelection::documentDetached(const Document& document) { 833 void FrameSelection::documentDetached(const Document& document) {
817 DCHECK_EQ(m_document, document); 834 DCHECK_EQ(m_document, document);
818 m_document = nullptr; 835 m_document = nullptr;
(...skipping 27 matching lines...) Expand all
846 863
847 void FrameSelection::dataWillChange(const CharacterData& node) { 864 void FrameSelection::dataWillChange(const CharacterData& node) {
848 m_frameCaret->dataWillChange(node); 865 m_frameCaret->dataWillChange(node);
849 } 866 }
850 867
851 void FrameSelection::paintCaret(GraphicsContext& context, 868 void FrameSelection::paintCaret(GraphicsContext& context,
852 const LayoutPoint& paintOffset) { 869 const LayoutPoint& paintOffset) {
853 m_frameCaret->paintCaret(context, paintOffset); 870 m_frameCaret->paintCaret(context, paintOffset);
854 } 871 }
855 872
856 bool FrameSelection::contains(const LayoutPoint& point) { 873 bool FrameSelection::contains(const HitTestResult& result) {
857 if (document().layoutViewItem().isNull())
858 return false;
859
860 // Treat a collapsed selection like no selection. 874 // Treat a collapsed selection like no selection.
861 const VisibleSelectionInFlatTree& visibleSelection = 875 const VisibleSelectionInFlatTree& visibleSelection =
862 this->visibleSelection<EditingInFlatTreeStrategy>(); 876 this->visibleSelection<EditingInFlatTreeStrategy>();
863 if (!visibleSelection.isRange()) 877 if (!visibleSelection.isRange())
864 return false; 878 return false;
865 879
866 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
867 HitTestResult result(request, point);
868 document().layoutViewItem().hitTest(result);
869 Node* innerNode = result.innerNode(); 880 Node* innerNode = result.innerNode();
870 if (!innerNode || !innerNode->layoutObject()) 881 if (!innerNode || !innerNode->layoutObject())
871 return false; 882 return false;
872 883
873 const VisiblePositionInFlatTree& visiblePos = 884 const VisiblePositionInFlatTree& visiblePos =
874 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>( 885 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>(
875 innerNode->layoutObject()->positionForPoint(result.localPoint()))); 886 innerNode->layoutObject()->positionForPoint(result.localPoint())));
876 if (visiblePos.isNull()) 887 if (visiblePos.isNull())
877 return false; 888 return false;
878 889
879 const VisiblePositionInFlatTree& visibleStart = 890 const VisiblePositionInFlatTree& visibleStart =
880 visibleSelection.visibleStart(); 891 visibleSelection.visibleStart();
881 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd(); 892 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd();
882 if (visibleStart.isNull() || visibleEnd.isNull()) 893 if (visibleStart.isNull() || visibleEnd.isNull())
883 return false; 894 return false;
884 895
885 const PositionInFlatTree& start = visibleStart.deepEquivalent(); 896 const PositionInFlatTree& start = visibleStart.deepEquivalent();
886 const PositionInFlatTree& end = visibleEnd.deepEquivalent(); 897 const PositionInFlatTree& end = visibleEnd.deepEquivalent();
887 const PositionInFlatTree& pos = visiblePos.deepEquivalent(); 898 const PositionInFlatTree& pos = visiblePos.deepEquivalent();
888 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; 899 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0;
889 } 900 }
890 901
902 bool FrameSelection::contains(const LayoutPoint& point) {
bokan 2016/10/26 16:17:23 Please rename point to pointInContent
amaralp 2017/01/13 23:52:51 Done.
903 if (document().layoutViewItem().isNull())
904 return false;
905
906 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
907 HitTestResult result(request, point);
908 document().layoutViewItem().hitTest(result);
909
910 return contains(result);
911 }
912
891 // Workaround for the fact that it's hard to delete a frame. 913 // Workaround for the fact that it's hard to delete a frame.
892 // Call this after doing user-triggered selections to make it easy to delete the 914 // Call this after doing user-triggered selections to make it easy to delete the
893 // frame you entirely selected. Can't do this implicitly as part of every 915 // frame you entirely selected. Can't do this implicitly as part of every
894 // setSelection call because in some contexts it might not be good for the focus 916 // setSelection call because in some contexts it might not be good for the focus
895 // to move to another frame. So instead we call it from places where we are 917 // to move to another frame. So instead we call it from places where we are
896 // selecting with the mouse or the keyboard after setting the selection. 918 // selecting with the mouse or the keyboard after setting the selection.
897 void FrameSelection::selectFrameElementInParentIfFullySelected() { 919 void FrameSelection::selectFrameElementInParentIfFullySelected() {
898 // Find the parent frame; if there is none, then we have nothing to do. 920 // Find the parent frame; if there is none, then we have nothing to do.
899 Frame* parent = m_frame->tree().parent(); 921 Frame* parent = m_frame->tree().parent();
900 if (!parent) 922 if (!parent)
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 } 1451 }
1430 1452
1431 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) { 1453 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) {
1432 if (isNone()) 1454 if (isNone())
1433 return; 1455 return;
1434 1456
1435 VisibleSelection newSelection = 1457 VisibleSelection newSelection =
1436 granularityStrategy()->updateExtent(contentsPoint, m_frame); 1458 granularityStrategy()->updateExtent(contentsPoint, m_frame);
1437 setSelection(newSelection, 1459 setSelection(newSelection,
1438 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | 1460 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle |
1439 FrameSelection::DoNotClearStrategy | UserTriggered, 1461 FrameSelection::DoNotClearStrategy | UserTriggered |
1462 FrameSelection::HandleVisible,
1440 CursorAlignOnScroll::IfNeeded, CharacterGranularity); 1463 CursorAlignOnScroll::IfNeeded, CharacterGranularity);
1441 } 1464 }
1442 1465
1443 // TODO(yosin): We should make |FrameSelection::moveRangeSelection()| to take 1466 // TODO(yosin): We should make |FrameSelection::moveRangeSelection()| to take
1444 // two |IntPoint| instead of two |VisiblePosition| like 1467 // two |IntPoint| instead of two |VisiblePosition| like
1445 // |moveRangeSelectionExtent()|. 1468 // |moveRangeSelectionExtent()|.
1446 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition, 1469 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition,
1447 const VisiblePosition& extentPosition, 1470 const VisiblePosition& extentPosition,
1448 TextGranularity granularity) { 1471 TextGranularity granularity) {
1449 VisibleSelection newSelection = createVisibleSelection( 1472 VisibleSelection newSelection = createVisibleSelection(
1450 SelectionInDOMTree::Builder() 1473 SelectionInDOMTree::Builder()
1451 .setBaseAndExtentDeprecated(basePosition.deepEquivalent(), 1474 .setBaseAndExtentDeprecated(basePosition.deepEquivalent(),
1452 extentPosition.deepEquivalent()) 1475 extentPosition.deepEquivalent())
1453 .setAffinity(basePosition.affinity()) 1476 .setAffinity(basePosition.affinity())
1454 .build()); 1477 .build());
1455 newSelection.expandUsingGranularity(granularity); 1478 newSelection.expandUsingGranularity(granularity);
1456 1479
1457 if (newSelection.isNone()) 1480 if (newSelection.isNone())
1458 return; 1481 return;
1459 1482
1460 setSelection(newSelection, CloseTyping | ClearTypingStyle, 1483 SetSelectionOptions options = CloseTyping | ClearTypingStyle;
1461 CursorAlignOnScroll::IfNeeded, granularity); 1484 if (isHandleVisible())
1485 options |= HandleVisible;
1486 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
1487 granularity);
1462 } 1488 }
1463 1489
1464 void FrameSelection::updateIfNeeded() { 1490 void FrameSelection::updateIfNeeded() {
1465 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); 1491 DCHECK(!m_frame->document()->needsLayoutTreeUpdate());
1466 m_selectionEditor->updateIfNeeded(); 1492 m_selectionEditor->updateIfNeeded();
1467 } 1493 }
1468 1494
1469 void FrameSelection::setCaretVisible(bool caretIsVisible) { 1495 void FrameSelection::setCaretVisible(bool caretIsVisible) {
1470 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible 1496 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible
1471 : CaretVisibility::Hidden); 1497 : CaretVisibility::Hidden);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 } 1530 }
1505 1531
1506 void showTree(const blink::FrameSelection* sel) { 1532 void showTree(const blink::FrameSelection* sel) {
1507 if (sel) 1533 if (sel)
1508 sel->showTreeForThis(); 1534 sel->showTreeForThis();
1509 else 1535 else
1510 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; 1536 LOG(INFO) << "Cannot showTree for <null> FrameSelection.";
1511 } 1537 }
1512 1538
1513 #endif 1539 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/editing/FrameSelection.h ('k') | third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698