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

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: git cl format Created 4 years, 2 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) 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 95
96 FrameSelection::FrameSelection(LocalFrame* frame) 96 FrameSelection::FrameSelection(LocalFrame* frame)
97 : m_frame(frame), 97 : m_frame(frame),
98 m_pendingSelection(PendingSelection::create(*this)), 98 m_pendingSelection(PendingSelection::create(*this)),
99 m_selectionEditor(SelectionEditor::create(*this)), 99 m_selectionEditor(SelectionEditor::create(*this)),
100 m_granularity(CharacterGranularity), 100 m_granularity(CharacterGranularity),
101 m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation()), 101 m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation()),
102 m_focused(frame->page() && 102 m_focused(frame->page() &&
103 frame->page()->focusController().focusedFrame() == frame), 103 frame->page()->focusController().focusedFrame() == frame),
104 m_handleVisibility(HandleVisibility::NotVisible),
yosin_UTC9 2016/10/19 06:33:05 nit: Let's initialize in class declaration instead
amaralp 2016/10/21 03:47:18 Done.
104 m_frameCaret(new FrameCaret(frame, *m_selectionEditor)) { 105 m_frameCaret(new FrameCaret(frame, *m_selectionEditor)) {
105 DCHECK(frame); 106 DCHECK(frame);
106 } 107 }
107 108
108 FrameSelection::~FrameSelection() {} 109 FrameSelection::~FrameSelection() {}
109 110
110 const Document& FrameSelection::document() const { 111 const Document& FrameSelection::document() const {
111 DCHECK(m_document); 112 DCHECK(m_document);
112 return *m_document; 113 return *m_document;
113 } 114 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 } 152 }
152 153
153 const VisibleSelectionInFlatTree& FrameSelection::selectionInFlatTree() const { 154 const VisibleSelectionInFlatTree& FrameSelection::selectionInFlatTree() const {
154 return visibleSelection<EditingInFlatTreeStrategy>(); 155 return visibleSelection<EditingInFlatTreeStrategy>();
155 } 156 }
156 157
157 void FrameSelection::moveTo(const VisiblePosition& pos, 158 void FrameSelection::moveTo(const VisiblePosition& pos,
158 EUserTriggered userTriggered, 159 EUserTriggered userTriggered,
159 CursorAlignOnScroll align) { 160 CursorAlignOnScroll align) {
160 SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTriggered; 161 SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTriggered;
162 bool isHandleVisible = userTriggered == UserTriggered;
yosin_UTC9 2016/10/19 06:33:05 nit: This variable name makes me confusing, should
amaralp 2016/10/21 03:47:18 Done.
163 if (isHandleVisible)
164 options |= HandleVisible;
161 setSelection(createVisibleSelection(pos, pos, selection().isDirectional()), 165 setSelection(createVisibleSelection(pos, pos, selection().isDirectional()),
162 options, align); 166 options, align);
163 } 167 }
164 168
165 // TODO(xiaochengh): We should not use reference to return value. 169 // TODO(xiaochengh): We should not use reference to return value.
166 template <typename Strategy> 170 template <typename Strategy>
167 static void adjustEndpointsAtBidiBoundary( 171 static void adjustEndpointsAtBidiBoundary(
168 VisiblePositionTemplate<Strategy>& visibleBase, 172 VisiblePositionTemplate<Strategy>& visibleBase,
169 VisiblePositionTemplate<Strategy>& visibleExtent) { 173 VisiblePositionTemplate<Strategy>& visibleExtent) {
170 DCHECK(visibleBase.isValid()); 174 DCHECK(visibleBase.isValid());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) { 215 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) {
212 visibleExtent = createVisiblePosition(fromPositionInDOMTree<Strategy>( 216 visibleExtent = createVisiblePosition(fromPositionInDOMTree<Strategy>(
213 extent.positionAtRightBoundaryOfBiDiRun())); 217 extent.positionAtRightBoundaryOfBiDiRun()));
214 return; 218 return;
215 } 219 }
216 } 220 }
217 221
218 void FrameSelection::setNonDirectionalSelectionIfNeeded( 222 void FrameSelection::setNonDirectionalSelectionIfNeeded(
219 const VisibleSelectionInFlatTree& passedNewSelection, 223 const VisibleSelectionInFlatTree& passedNewSelection,
220 TextGranularity granularity, 224 TextGranularity granularity,
221 EndPointsAdjustmentMode endpointsAdjustmentMode) { 225 EndPointsAdjustmentMode endpointsAdjustmentMode,
226 const HandleVisibility& handleVisibility) {
yosin_UTC9 2016/10/19 06:33:05 Since |HandleVisibility| is |enum|, we don't need
amaralp 2016/10/21 03:47:18 Done.
222 VisibleSelectionInFlatTree newSelection = passedNewSelection; 227 VisibleSelectionInFlatTree newSelection = passedNewSelection;
223 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) || 228 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) ||
224 newSelection.isDirectional(); 229 newSelection.isDirectional();
225 230
226 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 231 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
227 // needs to be audited. See http://crbug.com/590369 for more details. 232 // needs to be audited. See http://crbug.com/590369 for more details.
228 document().updateStyleAndLayoutIgnorePendingStylesheets(); 233 document().updateStyleAndLayoutIgnorePendingStylesheets();
229 234
230 const PositionInFlatTree basePosition = 235 const PositionInFlatTree basePosition =
231 m_originalBaseInFlatTree.deepEquivalent(); 236 m_originalBaseInFlatTree.deepEquivalent();
(...skipping 17 matching lines...) Expand all
249 newSelection.setExtent(newExtent); 254 newSelection.setExtent(newExtent);
250 } else if (originalBase.isNotNull()) { 255 } else if (originalBase.isNotNull()) {
251 if (visibleSelection<EditingInFlatTreeStrategy>().base() == 256 if (visibleSelection<EditingInFlatTreeStrategy>().base() ==
252 newSelection.base()) 257 newSelection.base())
253 newSelection.setBase(originalBase); 258 newSelection.setBase(originalBase);
254 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); 259 m_originalBaseInFlatTree = VisiblePositionInFlatTree();
255 } 260 }
256 261
257 // Adjusting base and extent will make newSelection always directional 262 // Adjusting base and extent will make newSelection always directional
258 newSelection.setIsDirectional(isDirectional); 263 newSelection.setIsDirectional(isDirectional);
259 if (visibleSelection<EditingInFlatTreeStrategy>() == newSelection) 264 if (visibleSelection<EditingInFlatTreeStrategy>() == newSelection &&
265 m_handleVisibility == handleVisibility)
260 return; 266 return;
261 267
262 const SetSelectionOptions options = CloseTyping | ClearTypingStyle; 268 SetSelectionOptions options = CloseTyping | ClearTypingStyle;
269 if (handleVisibility == HandleVisibility::Visible)
270 options |= HandleVisible;
263 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded, 271 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
264 granularity); 272 granularity);
265 } 273 }
266 274
267 template <typename Strategy> 275 template <typename Strategy>
268 void FrameSelection::setSelectionAlgorithm( 276 void FrameSelection::setSelectionAlgorithm(
269 const VisibleSelectionTemplate<Strategy>& newSelection, 277 const VisibleSelectionTemplate<Strategy>& newSelection,
270 SetSelectionOptions options, 278 SetSelectionOptions options,
271 CursorAlignOnScroll align, 279 CursorAlignOnScroll align,
272 TextGranularity granularity) { 280 TextGranularity granularity) {
273 DCHECK(isAvailable()); 281 DCHECK(isAvailable());
274 DCHECK(newSelection.isValidFor(document())); 282 DCHECK(newSelection.isValidFor(document()));
275 const Document& currentDocument = document(); 283 const Document& currentDocument = document();
276 if (m_granularityStrategy && 284 if (m_granularityStrategy &&
277 (options & FrameSelection::DoNotClearStrategy) == 0) 285 (options & FrameSelection::DoNotClearStrategy) == 0)
278 m_granularityStrategy->Clear(); 286 m_granularityStrategy->Clear();
279 bool closeTyping = options & CloseTyping; 287 bool closeTyping = options & CloseTyping;
280 bool shouldClearTypingStyle = options & ClearTypingStyle; 288 bool shouldClearTypingStyle = options & ClearTypingStyle;
289 HandleVisibility handleVisibility = options & HandleVisible
yosin_UTC9 2016/10/19 06:33:05 nit: s/HandleVisibility/const HandleVisibility/
amaralp 2016/10/21 03:47:18 Done.
290 ? HandleVisibility::Visible
291 : HandleVisibility::NotVisible;
281 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); 292 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options);
282 293
283 VisibleSelectionTemplate<Strategy> s = validateSelection(newSelection); 294 VisibleSelectionTemplate<Strategy> s = validateSelection(newSelection);
284 if (shouldAlwaysUseDirectionalSelection(m_frame)) 295 if (shouldAlwaysUseDirectionalSelection(m_frame))
285 s.setIsDirectional(true); 296 s.setIsDirectional(true);
286 297
287 m_granularity = granularity; 298 m_granularity = granularity;
288 299
289 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 300 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
290 // |Editor| class. 301 // |Editor| class.
291 if (closeTyping) 302 if (closeTyping)
292 TypingCommand::closeTyping(m_frame); 303 TypingCommand::closeTyping(m_frame);
293 304
294 if (shouldClearTypingStyle) 305 if (shouldClearTypingStyle)
295 clearTypingStyle(); 306 clearTypingStyle();
296 307
297 if (m_selectionEditor->visibleSelection<Strategy>() == s) { 308 if (m_selectionEditor->visibleSelection<Strategy>() == s &&
309 m_handleVisibility == handleVisibility) {
298 // Even if selection was not changed, selection offsets may have been 310 // Even if selection was not changed, selection offsets may have been
299 // changed. 311 // changed.
300 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid(); 312 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid();
301 notifyLayoutObjectOfSelectionChange(userTriggered); 313 notifyLayoutObjectOfSelectionChange(userTriggered);
302 return; 314 return;
303 } 315 }
304 316
305 const VisibleSelectionTemplate<Strategy> oldSelection = 317 const VisibleSelectionTemplate<Strategy> oldSelection =
306 visibleSelection<Strategy>(); 318 visibleSelection<Strategy>();
307 const VisibleSelection oldSelectionInDOMTree = selection(); 319 const VisibleSelection oldSelectionInDOMTree = selection();
308 320
321 m_handleVisibility = handleVisibility;
309 m_selectionEditor->setVisibleSelection(s, options); 322 m_selectionEditor->setVisibleSelection(s, options);
310 m_frameCaret->setCaretRectNeedsUpdate(); 323 m_frameCaret->setCaretRectNeedsUpdate();
311 324
312 if (!s.isNone() && !(options & DoNotSetFocus)) { 325 if (!s.isNone() && !(options & DoNotSetFocus)) {
313 setFocusedNodeIfNeeded(); 326 setFocusedNodeIfNeeded();
314 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and 327 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and
315 // "FocusIn", |m_frame| may associate to another document. 328 // "FocusIn", |m_frame| may associate to another document.
316 if (!isAvailable() || document() != currentDocument) { 329 if (!isAvailable() || document() != currentDocument) {
317 // Once we get test case to reach here, we should change this 330 // Once we get test case to reach here, we should change this
318 // if-statement to |DCHECK()|. 331 // if-statement to |DCHECK()|.
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 846
834 void FrameSelection::dataWillChange(const CharacterData& node) { 847 void FrameSelection::dataWillChange(const CharacterData& node) {
835 m_frameCaret->dataWillChange(node); 848 m_frameCaret->dataWillChange(node);
836 } 849 }
837 850
838 void FrameSelection::paintCaret(GraphicsContext& context, 851 void FrameSelection::paintCaret(GraphicsContext& context,
839 const LayoutPoint& paintOffset) { 852 const LayoutPoint& paintOffset) {
840 m_frameCaret->paintCaret(context, paintOffset); 853 m_frameCaret->paintCaret(context, paintOffset);
841 } 854 }
842 855
843 bool FrameSelection::contains(const LayoutPoint& point) { 856 bool FrameSelection::contains(const HitTestResult& result) {
844 if (document().layoutViewItem().isNull())
845 return false;
846
847 // Treat a collapsed selection like no selection. 857 // Treat a collapsed selection like no selection.
848 const VisibleSelectionInFlatTree& visibleSelection = 858 const VisibleSelectionInFlatTree& visibleSelection =
849 this->visibleSelection<EditingInFlatTreeStrategy>(); 859 this->visibleSelection<EditingInFlatTreeStrategy>();
850 if (!visibleSelection.isRange()) 860 if (!visibleSelection.isRange())
851 return false; 861 return false;
852 862
853 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
854 HitTestResult result(request, point);
855 document().layoutViewItem().hitTest(result);
856 Node* innerNode = result.innerNode(); 863 Node* innerNode = result.innerNode();
857 if (!innerNode || !innerNode->layoutObject()) 864 if (!innerNode || !innerNode->layoutObject())
858 return false; 865 return false;
859 866
860 const VisiblePositionInFlatTree& visiblePos = 867 const VisiblePositionInFlatTree& visiblePos =
861 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>( 868 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>(
862 innerNode->layoutObject()->positionForPoint(result.localPoint()))); 869 innerNode->layoutObject()->positionForPoint(result.localPoint())));
863 if (visiblePos.isNull()) 870 if (visiblePos.isNull())
864 return false; 871 return false;
865 872
866 const VisiblePositionInFlatTree& visibleStart = 873 const VisiblePositionInFlatTree& visibleStart =
867 visibleSelection.visibleStart(); 874 visibleSelection.visibleStart();
868 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd(); 875 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd();
869 if (visibleStart.isNull() || visibleEnd.isNull()) 876 if (visibleStart.isNull() || visibleEnd.isNull())
870 return false; 877 return false;
871 878
872 const PositionInFlatTree& start = visibleStart.deepEquivalent(); 879 const PositionInFlatTree& start = visibleStart.deepEquivalent();
873 const PositionInFlatTree& end = visibleEnd.deepEquivalent(); 880 const PositionInFlatTree& end = visibleEnd.deepEquivalent();
874 const PositionInFlatTree& pos = visiblePos.deepEquivalent(); 881 const PositionInFlatTree& pos = visiblePos.deepEquivalent();
875 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; 882 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0;
876 } 883 }
877 884
885 bool FrameSelection::contains(const LayoutPoint& point) {
886 if (document().layoutViewItem().isNull())
887 return false;
888
889 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
890 HitTestResult result(request, point);
891 document().layoutViewItem().hitTest(result);
892
893 return contains(result);
894 }
895
878 // Workaround for the fact that it's hard to delete a frame. 896 // Workaround for the fact that it's hard to delete a frame.
879 // Call this after doing user-triggered selections to make it easy to delete the 897 // Call this after doing user-triggered selections to make it easy to delete the
880 // frame you entirely selected. Can't do this implicitly as part of every 898 // frame you entirely selected. Can't do this implicitly as part of every
881 // setSelection call because in some contexts it might not be good for the focus 899 // setSelection call because in some contexts it might not be good for the focus
882 // to move to another frame. So instead we call it from places where we are 900 // to move to another frame. So instead we call it from places where we are
883 // selecting with the mouse or the keyboard after setting the selection. 901 // selecting with the mouse or the keyboard after setting the selection.
884 void FrameSelection::selectFrameElementInParentIfFullySelected() { 902 void FrameSelection::selectFrameElementInParentIfFullySelected() {
885 // Find the parent frame; if there is none, then we have nothing to do. 903 // Find the parent frame; if there is none, then we have nothing to do.
886 Frame* parent = m_frame->tree().parent(); 904 Frame* parent = m_frame->tree().parent();
887 if (!parent) 905 if (!parent)
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1434 } 1452 }
1435 1453
1436 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) { 1454 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) {
1437 if (isNone()) 1455 if (isNone())
1438 return; 1456 return;
1439 1457
1440 VisibleSelection newSelection = 1458 VisibleSelection newSelection =
1441 granularityStrategy()->updateExtent(contentsPoint, m_frame); 1459 granularityStrategy()->updateExtent(contentsPoint, m_frame);
1442 setSelection(newSelection, 1460 setSelection(newSelection,
1443 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | 1461 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle |
1444 FrameSelection::DoNotClearStrategy | UserTriggered, 1462 FrameSelection::DoNotClearStrategy | UserTriggered |
1463 FrameSelection::HandleVisible,
1445 CursorAlignOnScroll::IfNeeded, CharacterGranularity); 1464 CursorAlignOnScroll::IfNeeded, CharacterGranularity);
1446 } 1465 }
1447 1466
1448 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition, 1467 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition,
1449 const VisiblePosition& extentPosition, 1468 const VisiblePosition& extentPosition,
1450 TextGranularity granularity) { 1469 TextGranularity granularity) {
1451 VisibleSelection newSelection = 1470 VisibleSelection newSelection =
1452 createVisibleSelection(basePosition, extentPosition); 1471 createVisibleSelection(basePosition, extentPosition);
1453 newSelection.expandUsingGranularity(granularity); 1472 newSelection.expandUsingGranularity(granularity);
1454 1473
1455 if (newSelection.isNone()) 1474 if (newSelection.isNone())
1456 return; 1475 return;
1457 1476 SetSelectionOptions options = CloseTyping | ClearTypingStyle;
1458 setSelection(newSelection, granularity); 1477 if (isHandleVisible())
1478 options |= HandleVisible;
1479 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
1480 granularity);
1459 } 1481 }
1460 1482
1461 void FrameSelection::updateIfNeeded() { 1483 void FrameSelection::updateIfNeeded() {
1462 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); 1484 DCHECK(!m_frame->document()->needsLayoutTreeUpdate());
1463 m_selectionEditor->updateIfNeeded(); 1485 m_selectionEditor->updateIfNeeded();
1464 } 1486 }
1465 1487
1466 void FrameSelection::setCaretVisible(bool caretIsVisible) { 1488 void FrameSelection::setCaretVisible(bool caretIsVisible) {
1467 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible 1489 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible
1468 : CaretVisibility::Hidden); 1490 : CaretVisibility::Hidden);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 } 1523 }
1502 1524
1503 void showTree(const blink::FrameSelection* sel) { 1525 void showTree(const blink::FrameSelection* sel) {
1504 if (sel) 1526 if (sel)
1505 sel->showTreeForThis(); 1527 sel->showTreeForThis();
1506 else 1528 else
1507 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; 1529 LOG(INFO) << "Cannot showTree for <null> FrameSelection.";
1508 } 1530 }
1509 1531
1510 #endif 1532 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698