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

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: fixed contextual search test function 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_isHandleVisible(false),
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;
161 setSelection(createVisibleSelection(pos, pos, selection().isDirectional()), 163 setSelection(createVisibleSelection(pos, pos, selection().isDirectional()),
162 options, align); 164 options, align, CharacterGranularity, isHandleVisible);
163 } 165 }
164 166
165 void FrameSelection::moveTo(const Position& pos, TextAffinity affinity) { 167 void FrameSelection::moveTo(const Position& pos, TextAffinity affinity) {
166 SetSelectionOptions options = CloseTyping | ClearTypingStyle; 168 SetSelectionOptions options = CloseTyping | ClearTypingStyle;
167 setSelection( 169 setSelection(
168 createVisibleSelection(pos, affinity, selection().isDirectional()), 170 createVisibleSelection(pos, affinity, selection().isDirectional()),
169 options); 171 options);
170 } 172 }
171 173
172 // TODO(xiaochengh): We should not use reference to return value. 174 // TODO(xiaochengh): We should not use reference to return value.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) { 220 base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) {
219 visibleExtent = createVisiblePosition(fromPositionInDOMTree<Strategy>( 221 visibleExtent = createVisiblePosition(fromPositionInDOMTree<Strategy>(
220 extent.positionAtRightBoundaryOfBiDiRun())); 222 extent.positionAtRightBoundaryOfBiDiRun()));
221 return; 223 return;
222 } 224 }
223 } 225 }
224 226
225 void FrameSelection::setNonDirectionalSelectionIfNeeded( 227 void FrameSelection::setNonDirectionalSelectionIfNeeded(
226 const VisibleSelectionInFlatTree& passedNewSelection, 228 const VisibleSelectionInFlatTree& passedNewSelection,
227 TextGranularity granularity, 229 TextGranularity granularity,
228 EndPointsAdjustmentMode endpointsAdjustmentMode) { 230 EndPointsAdjustmentMode endpointsAdjustmentMode,
231 bool isHandleVisible) {
229 VisibleSelectionInFlatTree newSelection = passedNewSelection; 232 VisibleSelectionInFlatTree newSelection = passedNewSelection;
230 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) || 233 bool isDirectional = shouldAlwaysUseDirectionalSelection(m_frame) ||
231 newSelection.isDirectional(); 234 newSelection.isDirectional();
232 235
233 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets 236 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets
234 // 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.
235 document().updateStyleAndLayoutIgnorePendingStylesheets(); 238 document().updateStyleAndLayoutIgnorePendingStylesheets();
236 239
237 const PositionInFlatTree basePosition = 240 const PositionInFlatTree basePosition =
238 m_originalBaseInFlatTree.deepEquivalent(); 241 m_originalBaseInFlatTree.deepEquivalent();
(...skipping 17 matching lines...) Expand all
256 newSelection.setExtent(newExtent); 259 newSelection.setExtent(newExtent);
257 } else if (originalBase.isNotNull()) { 260 } else if (originalBase.isNotNull()) {
258 if (visibleSelection<EditingInFlatTreeStrategy>().base() == 261 if (visibleSelection<EditingInFlatTreeStrategy>().base() ==
259 newSelection.base()) 262 newSelection.base())
260 newSelection.setBase(originalBase); 263 newSelection.setBase(originalBase);
261 m_originalBaseInFlatTree = VisiblePositionInFlatTree(); 264 m_originalBaseInFlatTree = VisiblePositionInFlatTree();
262 } 265 }
263 266
264 // Adjusting base and extent will make newSelection always directional 267 // Adjusting base and extent will make newSelection always directional
265 newSelection.setIsDirectional(isDirectional); 268 newSelection.setIsDirectional(isDirectional);
266 if (visibleSelection<EditingInFlatTreeStrategy>() == newSelection) 269 if (visibleSelection<EditingInFlatTreeStrategy>() == newSelection &&
270 m_isHandleVisible == isHandleVisible)
267 return; 271 return;
268 272
269 const SetSelectionOptions options = CloseTyping | ClearTypingStyle; 273 const SetSelectionOptions options = CloseTyping | ClearTypingStyle;
270 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded, 274 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded,
271 granularity); 275 granularity, isHandleVisible);
272 } 276 }
273 277
274 template <typename Strategy> 278 template <typename Strategy>
275 void FrameSelection::setSelectionAlgorithm( 279 void FrameSelection::setSelectionAlgorithm(
276 const VisibleSelectionTemplate<Strategy>& newSelection, 280 const VisibleSelectionTemplate<Strategy>& newSelection,
277 SetSelectionOptions options, 281 SetSelectionOptions options,
278 CursorAlignOnScroll align, 282 CursorAlignOnScroll align,
279 TextGranularity granularity) { 283 TextGranularity granularity,
284 bool isHandleVisible) {
280 DCHECK(isAvailable()); 285 DCHECK(isAvailable());
281 DCHECK(newSelection.isValidFor(document())); 286 DCHECK(newSelection.isValidFor(document()));
282 const Document& currentDocument = document(); 287 const Document& currentDocument = document();
283 if (m_granularityStrategy && 288 if (m_granularityStrategy &&
284 (options & FrameSelection::DoNotClearStrategy) == 0) 289 (options & FrameSelection::DoNotClearStrategy) == 0)
285 m_granularityStrategy->Clear(); 290 m_granularityStrategy->Clear();
286 bool closeTyping = options & CloseTyping; 291 bool closeTyping = options & CloseTyping;
287 bool shouldClearTypingStyle = options & ClearTypingStyle; 292 bool shouldClearTypingStyle = options & ClearTypingStyle;
288 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); 293 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options);
289 294
290 VisibleSelectionTemplate<Strategy> s = validateSelection(newSelection); 295 VisibleSelectionTemplate<Strategy> s = validateSelection(newSelection);
291 if (shouldAlwaysUseDirectionalSelection(m_frame)) 296 if (shouldAlwaysUseDirectionalSelection(m_frame))
292 s.setIsDirectional(true); 297 s.setIsDirectional(true);
293 298
294 m_granularity = granularity; 299 m_granularity = granularity;
295 300
296 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to 301 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to
297 // |Editor| class. 302 // |Editor| class.
298 if (closeTyping) 303 if (closeTyping)
299 TypingCommand::closeTyping(m_frame); 304 TypingCommand::closeTyping(m_frame);
300 305
301 if (shouldClearTypingStyle) 306 if (shouldClearTypingStyle)
302 clearTypingStyle(); 307 clearTypingStyle();
303 308
304 if (m_selectionEditor->visibleSelection<Strategy>() == s) { 309 if (m_selectionEditor->visibleSelection<Strategy>() == s &&
310 m_isHandleVisible == isHandleVisible) {
305 // Even if selection was not changed, selection offsets may have been 311 // Even if selection was not changed, selection offsets may have been
306 // changed. 312 // changed.
307 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid(); 313 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid();
308 notifyLayoutObjectOfSelectionChange(userTriggered); 314 notifyLayoutObjectOfSelectionChange(userTriggered);
309 return; 315 return;
310 } 316 }
311 317
312 const VisibleSelectionTemplate<Strategy> oldSelection = 318 const VisibleSelectionTemplate<Strategy> oldSelection =
313 visibleSelection<Strategy>(); 319 visibleSelection<Strategy>();
314 const VisibleSelection oldSelectionInDOMTree = selection(); 320 const VisibleSelection oldSelectionInDOMTree = selection();
315 321
322 m_isHandleVisible = isHandleVisible;
316 m_selectionEditor->setVisibleSelection(s, options); 323 m_selectionEditor->setVisibleSelection(s, options);
317 m_frameCaret->setCaretRectNeedsUpdate(); 324 m_frameCaret->setCaretRectNeedsUpdate();
318 325
319 if (!s.isNone() && !(options & DoNotSetFocus)) { 326 if (!s.isNone() && !(options & DoNotSetFocus)) {
320 setFocusedNodeIfNeeded(); 327 setFocusedNodeIfNeeded();
321 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and 328 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and
322 // "FocusIn", |m_frame| may associate to another document. 329 // "FocusIn", |m_frame| may associate to another document.
323 if (!isAvailable() || document() != currentDocument) { 330 if (!isAvailable() || document() != currentDocument) {
324 // Once we get test case to reach here, we should change this 331 // Once we get test case to reach here, we should change this
325 // if-statement to |DCHECK()|. 332 // if-statement to |DCHECK()|.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 notifyAccessibilityForSelectionChange(); 387 notifyAccessibilityForSelectionChange();
381 notifyCompositorForSelectionChange(); 388 notifyCompositorForSelectionChange();
382 notifyEventHandlerForSelectionChange(); 389 notifyEventHandlerForSelectionChange();
383 m_frame->localDOMWindow()->enqueueDocumentEvent( 390 m_frame->localDOMWindow()->enqueueDocumentEvent(
384 Event::create(EventTypeNames::selectionchange)); 391 Event::create(EventTypeNames::selectionchange));
385 } 392 }
386 393
387 void FrameSelection::setSelection(const VisibleSelection& newSelection, 394 void FrameSelection::setSelection(const VisibleSelection& newSelection,
388 SetSelectionOptions options, 395 SetSelectionOptions options,
389 CursorAlignOnScroll align, 396 CursorAlignOnScroll align,
390 TextGranularity granularity) { 397 TextGranularity granularity,
398 bool isHandleVisible) {
391 setSelectionAlgorithm<EditingStrategy>(newSelection, options, align, 399 setSelectionAlgorithm<EditingStrategy>(newSelection, options, align,
392 granularity); 400 granularity, isHandleVisible);
393 } 401 }
394 402
395 void FrameSelection::setSelection( 403 void FrameSelection::setSelection(
396 const VisibleSelectionInFlatTree& newSelection, 404 const VisibleSelectionInFlatTree& newSelection,
397 SetSelectionOptions options, 405 SetSelectionOptions options,
398 CursorAlignOnScroll align, 406 CursorAlignOnScroll align,
399 TextGranularity granularity) { 407 TextGranularity granularity,
400 setSelectionAlgorithm<EditingInFlatTreeStrategy>(newSelection, options, align, 408 bool isHandleVisible) {
401 granularity); 409 setSelectionAlgorithm<EditingInFlatTreeStrategy>(
410 newSelection, options, align, granularity, isHandleVisible);
402 } 411 }
403 412
404 static bool removingNodeRemovesPosition(Node& node, const Position& position) { 413 static bool removingNodeRemovesPosition(Node& node, const Position& position) {
405 if (!position.anchorNode()) 414 if (!position.anchorNode())
406 return false; 415 return false;
407 416
408 if (position.anchorNode() == node) 417 if (position.anchorNode() == node)
409 return true; 418 return true;
410 419
411 if (!node.isElementNode()) 420 if (!node.isElementNode())
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 817
809 void FrameSelection::dataWillChange(const CharacterData& node) { 818 void FrameSelection::dataWillChange(const CharacterData& node) {
810 m_frameCaret->dataWillChange(node); 819 m_frameCaret->dataWillChange(node);
811 } 820 }
812 821
813 void FrameSelection::paintCaret(GraphicsContext& context, 822 void FrameSelection::paintCaret(GraphicsContext& context,
814 const LayoutPoint& paintOffset) { 823 const LayoutPoint& paintOffset) {
815 m_frameCaret->paintCaret(context, paintOffset); 824 m_frameCaret->paintCaret(context, paintOffset);
816 } 825 }
817 826
818 bool FrameSelection::contains(const LayoutPoint& point) { 827 bool FrameSelection::contains(const HitTestResult& result) {
819 if (document().layoutViewItem().isNull())
820 return false;
821
822 // Treat a collapsed selection like no selection. 828 // Treat a collapsed selection like no selection.
823 const VisibleSelectionInFlatTree& visibleSelection = 829 const VisibleSelectionInFlatTree& visibleSelection =
824 this->visibleSelection<EditingInFlatTreeStrategy>(); 830 this->visibleSelection<EditingInFlatTreeStrategy>();
825 if (!visibleSelection.isRange()) 831 if (!visibleSelection.isRange())
826 return false; 832 return false;
827 833
828 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
829 HitTestResult result(request, point);
830 document().layoutViewItem().hitTest(result);
831 Node* innerNode = result.innerNode(); 834 Node* innerNode = result.innerNode();
832 if (!innerNode || !innerNode->layoutObject()) 835 if (!innerNode || !innerNode->layoutObject())
833 return false; 836 return false;
834 837
835 const VisiblePositionInFlatTree& visiblePos = 838 const VisiblePositionInFlatTree& visiblePos =
836 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>( 839 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>(
837 innerNode->layoutObject()->positionForPoint(result.localPoint()))); 840 innerNode->layoutObject()->positionForPoint(result.localPoint())));
838 if (visiblePos.isNull()) 841 if (visiblePos.isNull())
839 return false; 842 return false;
840 843
841 const VisiblePositionInFlatTree& visibleStart = 844 const VisiblePositionInFlatTree& visibleStart =
842 visibleSelection.visibleStart(); 845 visibleSelection.visibleStart();
843 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd(); 846 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd();
844 if (visibleStart.isNull() || visibleEnd.isNull()) 847 if (visibleStart.isNull() || visibleEnd.isNull())
845 return false; 848 return false;
846 849
847 const PositionInFlatTree& start = visibleStart.deepEquivalent(); 850 const PositionInFlatTree& start = visibleStart.deepEquivalent();
848 const PositionInFlatTree& end = visibleEnd.deepEquivalent(); 851 const PositionInFlatTree& end = visibleEnd.deepEquivalent();
849 const PositionInFlatTree& pos = visiblePos.deepEquivalent(); 852 const PositionInFlatTree& pos = visiblePos.deepEquivalent();
850 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; 853 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0;
851 } 854 }
852 855
856 bool FrameSelection::contains(const LayoutPoint& point) {
857 if (document().layoutViewItem().isNull())
858 return false;
859
860 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active);
861 HitTestResult result(request, point);
862 document().layoutViewItem().hitTest(result);
863
864 return contains(result);
865 }
866
853 // Workaround for the fact that it's hard to delete a frame. 867 // Workaround for the fact that it's hard to delete a frame.
854 // Call this after doing user-triggered selections to make it easy to delete the 868 // Call this after doing user-triggered selections to make it easy to delete the
855 // frame you entirely selected. Can't do this implicitly as part of every 869 // frame you entirely selected. Can't do this implicitly as part of every
856 // setSelection call because in some contexts it might not be good for the focus 870 // setSelection call because in some contexts it might not be good for the focus
857 // to move to another frame. So instead we call it from places where we are 871 // to move to another frame. So instead we call it from places where we are
858 // selecting with the mouse or the keyboard after setting the selection. 872 // selecting with the mouse or the keyboard after setting the selection.
859 void FrameSelection::selectFrameElementInParentIfFullySelected() { 873 void FrameSelection::selectFrameElementInParentIfFullySelected() {
860 // Find the parent frame; if there is none, then we have nothing to do. 874 // Find the parent frame; if there is none, then we have nothing to do.
861 Frame* parent = m_frame->tree().parent(); 875 Frame* parent = m_frame->tree().parent();
862 if (!parent) 876 if (!parent)
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 1429
1416 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) { 1430 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) {
1417 if (isNone()) 1431 if (isNone())
1418 return; 1432 return;
1419 1433
1420 VisibleSelection newSelection = 1434 VisibleSelection newSelection =
1421 granularityStrategy()->updateExtent(contentsPoint, m_frame); 1435 granularityStrategy()->updateExtent(contentsPoint, m_frame);
1422 setSelection(newSelection, 1436 setSelection(newSelection,
1423 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | 1437 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle |
1424 FrameSelection::DoNotClearStrategy | UserTriggered, 1438 FrameSelection::DoNotClearStrategy | UserTriggered,
1425 CursorAlignOnScroll::IfNeeded, CharacterGranularity); 1439 CursorAlignOnScroll::IfNeeded, CharacterGranularity,
1440 m_isHandleVisible);
1426 } 1441 }
1427 1442
1428 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition, 1443 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition,
1429 const VisiblePosition& extentPosition, 1444 const VisiblePosition& extentPosition,
1430 TextGranularity granularity) { 1445 TextGranularity granularity) {
1431 VisibleSelection newSelection = 1446 VisibleSelection newSelection =
1432 createVisibleSelection(basePosition, extentPosition); 1447 createVisibleSelection(basePosition, extentPosition);
1433 newSelection.expandUsingGranularity(granularity); 1448 newSelection.expandUsingGranularity(granularity);
1434 1449
1435 if (newSelection.isNone()) 1450 if (newSelection.isNone())
1436 return; 1451 return;
1437 1452
1438 setSelection(newSelection, granularity); 1453 setSelection(newSelection, granularity, m_isHandleVisible);
1439 } 1454 }
1440 1455
1441 void FrameSelection::updateIfNeeded() { 1456 void FrameSelection::updateIfNeeded() {
1442 m_selectionEditor->updateIfNeeded(); 1457 m_selectionEditor->updateIfNeeded();
1443 } 1458 }
1444 1459
1445 void FrameSelection::setCaretVisible(bool caretIsVisible) { 1460 void FrameSelection::setCaretVisible(bool caretIsVisible) {
1446 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible 1461 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible
1447 : CaretVisibility::Hidden); 1462 : CaretVisibility::Hidden);
1448 } 1463 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 } 1495 }
1481 1496
1482 void showTree(const blink::FrameSelection* sel) { 1497 void showTree(const blink::FrameSelection* sel) {
1483 if (sel) 1498 if (sel)
1484 sel->showTreeForThis(); 1499 sel->showTreeForThis();
1485 else 1500 else
1486 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; 1501 LOG(INFO) << "Cannot showTree for <null> FrameSelection.";
1487 } 1502 }
1488 1503
1489 #endif 1504 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698