OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |