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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 Element* const editable = rootEditableElement(); | 159 Element* const editable = rootEditableElement(); |
160 if (!editable) | 160 if (!editable) |
161 return; | 161 return; |
162 | 162 |
163 const VisiblePosition position = | 163 const VisiblePosition position = |
164 visiblePositionForContentsPoint(point, frame()); | 164 visiblePositionForContentsPoint(point, frame()); |
165 SelectionInDOMTree::Builder builder; | 165 SelectionInDOMTree::Builder builder; |
166 builder.setIsDirectional(selection().isDirectional()); | 166 builder.setIsDirectional(selection().isDirectional()); |
167 if (position.isNotNull()) | 167 if (position.isNotNull()) |
168 builder.collapse(position.toPositionWithAffinity()); | 168 builder.collapse(position.toPositionWithAffinity()); |
169 setSelection(builder.build(), CloseTyping | ClearTypingStyle | UserTriggered); | 169 setSelection(builder.build(), |
| 170 CloseTyping | ClearTypingStyle | UserTriggered | HandleVisible); |
170 } | 171 } |
171 | 172 |
172 template <typename Strategy> | 173 template <typename Strategy> |
173 void FrameSelection::setSelectionAlgorithm( | 174 void FrameSelection::setSelectionAlgorithm( |
174 const VisibleSelectionTemplate<Strategy>& newSelection, | 175 const VisibleSelectionTemplate<Strategy>& newSelection, |
175 SetSelectionOptions options, | 176 SetSelectionOptions options, |
176 CursorAlignOnScroll align, | 177 CursorAlignOnScroll align, |
177 TextGranularity granularity) { | 178 TextGranularity granularity) { |
178 DCHECK(isAvailable()); | 179 DCHECK(isAvailable()); |
179 DCHECK(newSelection.isValidFor(document())); | 180 DCHECK(newSelection.isValidFor(document())); |
180 const Document& currentDocument = document(); | 181 const Document& currentDocument = document(); |
181 if (m_granularityStrategy && | 182 if (m_granularityStrategy && |
182 (options & FrameSelection::DoNotClearStrategy) == 0) | 183 (options & FrameSelection::DoNotClearStrategy) == 0) |
183 m_granularityStrategy->Clear(); | 184 m_granularityStrategy->Clear(); |
184 bool closeTyping = options & CloseTyping; | 185 bool closeTyping = options & CloseTyping; |
185 bool shouldClearTypingStyle = options & ClearTypingStyle; | 186 bool shouldClearTypingStyle = options & ClearTypingStyle; |
| 187 const HandleVisibility handleVisibility = options & HandleVisible |
| 188 ? HandleVisibility::Visible |
| 189 : HandleVisibility::NotVisible; |
186 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); | 190 EUserTriggered userTriggered = selectionOptionsToUserTriggered(options); |
187 | 191 |
188 // TODO(editing-dev): We should rename variable |s| to another name to avoid | 192 // TODO(editing-dev): We should rename variable |s| to another name to avoid |
189 // using one letter variable name. | 193 // using one letter variable name. |
190 VisibleSelectionTemplate<Strategy> s = newSelection; | 194 VisibleSelectionTemplate<Strategy> s = newSelection; |
191 if (shouldAlwaysUseDirectionalSelection(m_frame)) | 195 if (shouldAlwaysUseDirectionalSelection(m_frame)) |
192 s.setIsDirectional(true); | 196 s.setIsDirectional(true); |
193 | 197 |
194 m_granularity = granularity; | 198 m_granularity = granularity; |
195 | 199 |
196 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to | 200 // TODO(yosin): We should move to call |TypingCommand::closeTyping()| to |
197 // |Editor| class. | 201 // |Editor| class. |
198 if (closeTyping) | 202 if (closeTyping) |
199 TypingCommand::closeTyping(m_frame); | 203 TypingCommand::closeTyping(m_frame); |
200 | 204 |
201 if (shouldClearTypingStyle) | 205 if (shouldClearTypingStyle) |
202 clearTypingStyle(); | 206 clearTypingStyle(); |
203 | 207 |
204 if (m_selectionEditor->visibleSelection<Strategy>() == s) { | 208 if (m_selectionEditor->visibleSelection<Strategy>() == s && |
| 209 m_handleVisibility == handleVisibility) { |
205 // Even if selection was not changed, selection offsets may have been | 210 // Even if selection was not changed, selection offsets may have been |
206 // changed. | 211 // changed. |
207 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid(); | 212 m_frame->inputMethodController().cancelCompositionIfSelectionIsInvalid(); |
208 notifyLayoutObjectOfSelectionChange(userTriggered); | 213 notifyLayoutObjectOfSelectionChange(userTriggered); |
209 return; | 214 return; |
210 } | 215 } |
211 | 216 |
212 const VisibleSelectionTemplate<Strategy> oldSelection = | 217 const VisibleSelectionTemplate<Strategy> oldSelection = |
213 visibleSelection<Strategy>(); | 218 visibleSelection<Strategy>(); |
214 const Position& oldSelectionStart = selection().start(); | 219 const Position& oldSelectionStart = selection().start(); |
215 | 220 |
| 221 m_handleVisibility = handleVisibility; |
216 m_selectionEditor->setVisibleSelection(s, options); | 222 m_selectionEditor->setVisibleSelection(s, options); |
217 m_frameCaret->setCaretRectNeedsUpdate(); | 223 m_frameCaret->setCaretRectNeedsUpdate(); |
218 | 224 |
219 if (!s.isNone() && !(options & DoNotSetFocus)) { | 225 if (!s.isNone() && !(options & DoNotSetFocus)) { |
220 setFocusedNodeIfNeeded(); | 226 setFocusedNodeIfNeeded(); |
221 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and | 227 // |setFocusedNodeIfNeeded()| dispatches sync events "FocusOut" and |
222 // "FocusIn", |m_frame| may associate to another document. | 228 // "FocusIn", |m_frame| may associate to another document. |
223 if (!isAvailable() || document() != currentDocument) { | 229 if (!isAvailable() || document() != currentDocument) { |
224 // Once we get test case to reach here, we should change this | 230 // Once we get test case to reach here, we should change this |
225 // if-statement to |DCHECK()|. | 231 // if-statement to |DCHECK()|. |
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 | 743 |
738 void FrameSelection::dataWillChange(const CharacterData& node) { | 744 void FrameSelection::dataWillChange(const CharacterData& node) { |
739 m_frameCaret->dataWillChange(node); | 745 m_frameCaret->dataWillChange(node); |
740 } | 746 } |
741 | 747 |
742 void FrameSelection::paintCaret(GraphicsContext& context, | 748 void FrameSelection::paintCaret(GraphicsContext& context, |
743 const LayoutPoint& paintOffset) { | 749 const LayoutPoint& paintOffset) { |
744 m_frameCaret->paintCaret(context, paintOffset); | 750 m_frameCaret->paintCaret(context, paintOffset); |
745 } | 751 } |
746 | 752 |
747 bool FrameSelection::contains(const LayoutPoint& point) { | 753 bool FrameSelection::contains(const HitTestResult& result) { |
748 if (document().layoutViewItem().isNull()) | |
749 return false; | |
750 | |
751 // Treat a collapsed selection like no selection. | 754 // Treat a collapsed selection like no selection. |
752 const VisibleSelectionInFlatTree& visibleSelection = | 755 const VisibleSelectionInFlatTree& visibleSelection = |
753 this->visibleSelection<EditingInFlatTreeStrategy>(); | 756 this->visibleSelection<EditingInFlatTreeStrategy>(); |
754 if (!visibleSelection.isRange()) | 757 if (!visibleSelection.isRange()) |
755 return false; | 758 return false; |
756 | 759 |
757 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); | |
758 HitTestResult result(request, point); | |
759 document().layoutViewItem().hitTest(result); | |
760 Node* innerNode = result.innerNode(); | 760 Node* innerNode = result.innerNode(); |
761 if (!innerNode || !innerNode->layoutObject()) | 761 if (!innerNode || !innerNode->layoutObject()) |
762 return false; | 762 return false; |
763 | 763 |
764 const VisiblePositionInFlatTree& visiblePos = | 764 const VisiblePositionInFlatTree& visiblePos = |
765 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>( | 765 createVisiblePosition(fromPositionInDOMTree<EditingInFlatTreeStrategy>( |
766 innerNode->layoutObject()->positionForPoint(result.localPoint()))); | 766 innerNode->layoutObject()->positionForPoint(result.localPoint()))); |
767 if (visiblePos.isNull()) | 767 if (visiblePos.isNull()) |
768 return false; | 768 return false; |
769 | 769 |
770 const VisiblePositionInFlatTree& visibleStart = | 770 const VisiblePositionInFlatTree& visibleStart = |
771 visibleSelection.visibleStart(); | 771 visibleSelection.visibleStart(); |
772 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd(); | 772 const VisiblePositionInFlatTree& visibleEnd = visibleSelection.visibleEnd(); |
773 if (visibleStart.isNull() || visibleEnd.isNull()) | 773 if (visibleStart.isNull() || visibleEnd.isNull()) |
774 return false; | 774 return false; |
775 | 775 |
776 const PositionInFlatTree& start = visibleStart.deepEquivalent(); | 776 const PositionInFlatTree& start = visibleStart.deepEquivalent(); |
777 const PositionInFlatTree& end = visibleEnd.deepEquivalent(); | 777 const PositionInFlatTree& end = visibleEnd.deepEquivalent(); |
778 const PositionInFlatTree& pos = visiblePos.deepEquivalent(); | 778 const PositionInFlatTree& pos = visiblePos.deepEquivalent(); |
779 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; | 779 return start.compareTo(pos) <= 0 && pos.compareTo(end) <= 0; |
780 } | 780 } |
781 | 781 |
| 782 bool FrameSelection::contains(const LayoutPoint& pointInContent) { |
| 783 if (document().layoutViewItem().isNull()) |
| 784 return false; |
| 785 |
| 786 HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active); |
| 787 HitTestResult result(request, pointInContent); |
| 788 document().layoutViewItem().hitTest(result); |
| 789 |
| 790 return contains(result); |
| 791 } |
| 792 |
782 // Workaround for the fact that it's hard to delete a frame. | 793 // Workaround for the fact that it's hard to delete a frame. |
783 // Call this after doing user-triggered selections to make it easy to delete the | 794 // Call this after doing user-triggered selections to make it easy to delete the |
784 // frame you entirely selected. Can't do this implicitly as part of every | 795 // frame you entirely selected. Can't do this implicitly as part of every |
785 // setSelection call because in some contexts it might not be good for the focus | 796 // setSelection call because in some contexts it might not be good for the focus |
786 // to move to another frame. So instead we call it from places where we are | 797 // to move to another frame. So instead we call it from places where we are |
787 // selecting with the mouse or the keyboard after setting the selection. | 798 // selecting with the mouse or the keyboard after setting the selection. |
788 void FrameSelection::selectFrameElementInParentIfFullySelected() { | 799 void FrameSelection::selectFrameElementInParentIfFullySelected() { |
789 // Find the parent frame; if there is none, then we have nothing to do. | 800 // Find the parent frame; if there is none, then we have nothing to do. |
790 Frame* parent = m_frame->tree().parent(); | 801 Frame* parent = m_frame->tree().parent(); |
791 if (!parent) | 802 if (!parent) |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 } | 1342 } |
1332 | 1343 |
1333 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) { | 1344 void FrameSelection::moveRangeSelectionExtent(const IntPoint& contentsPoint) { |
1334 if (isNone()) | 1345 if (isNone()) |
1335 return; | 1346 return; |
1336 | 1347 |
1337 VisibleSelection newSelection = | 1348 VisibleSelection newSelection = |
1338 granularityStrategy()->updateExtent(contentsPoint, m_frame); | 1349 granularityStrategy()->updateExtent(contentsPoint, m_frame); |
1339 setSelection(newSelection, | 1350 setSelection(newSelection, |
1340 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | | 1351 FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | |
1341 FrameSelection::DoNotClearStrategy | UserTriggered, | 1352 FrameSelection::DoNotClearStrategy | UserTriggered | |
| 1353 FrameSelection::HandleVisible, |
1342 CursorAlignOnScroll::IfNeeded, CharacterGranularity); | 1354 CursorAlignOnScroll::IfNeeded, CharacterGranularity); |
1343 } | 1355 } |
1344 | 1356 |
1345 // TODO(yosin): We should make |FrameSelection::moveRangeSelection()| to take | 1357 // TODO(yosin): We should make |FrameSelection::moveRangeSelection()| to take |
1346 // two |IntPoint| instead of two |VisiblePosition| like | 1358 // two |IntPoint| instead of two |VisiblePosition| like |
1347 // |moveRangeSelectionExtent()|. | 1359 // |moveRangeSelectionExtent()|. |
1348 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition, | 1360 void FrameSelection::moveRangeSelection(const VisiblePosition& basePosition, |
1349 const VisiblePosition& extentPosition, | 1361 const VisiblePosition& extentPosition, |
1350 TextGranularity granularity) { | 1362 TextGranularity granularity) { |
1351 VisibleSelection newSelection = createVisibleSelection( | 1363 VisibleSelection newSelection = createVisibleSelection( |
1352 SelectionInDOMTree::Builder() | 1364 SelectionInDOMTree::Builder() |
1353 .setBaseAndExtentDeprecated(basePosition.deepEquivalent(), | 1365 .setBaseAndExtentDeprecated(basePosition.deepEquivalent(), |
1354 extentPosition.deepEquivalent()) | 1366 extentPosition.deepEquivalent()) |
1355 .setAffinity(basePosition.affinity()) | 1367 .setAffinity(basePosition.affinity()) |
1356 .setGranularity(granularity) | 1368 .setGranularity(granularity) |
1357 .build()); | 1369 .build()); |
1358 | 1370 |
1359 if (newSelection.isNone()) | 1371 if (newSelection.isNone()) |
1360 return; | 1372 return; |
1361 | 1373 |
1362 setSelection(newSelection, CloseTyping | ClearTypingStyle, | 1374 SetSelectionOptions options = CloseTyping | ClearTypingStyle; |
1363 CursorAlignOnScroll::IfNeeded, granularity); | 1375 if (isHandleVisible()) |
| 1376 options |= HandleVisible; |
| 1377 setSelection(newSelection, options, CursorAlignOnScroll::IfNeeded, |
| 1378 granularity); |
1364 } | 1379 } |
1365 | 1380 |
1366 void FrameSelection::updateIfNeeded() { | 1381 void FrameSelection::updateIfNeeded() { |
1367 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); | 1382 DCHECK(!m_frame->document()->needsLayoutTreeUpdate()); |
1368 m_selectionEditor->updateIfNeeded(); | 1383 m_selectionEditor->updateIfNeeded(); |
1369 } | 1384 } |
1370 | 1385 |
1371 void FrameSelection::setCaretVisible(bool caretIsVisible) { | 1386 void FrameSelection::setCaretVisible(bool caretIsVisible) { |
1372 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible | 1387 m_frameCaret->setCaretVisibility(caretIsVisible ? CaretVisibility::Visible |
1373 : CaretVisibility::Hidden); | 1388 : CaretVisibility::Hidden); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 } | 1421 } |
1407 | 1422 |
1408 void showTree(const blink::FrameSelection* sel) { | 1423 void showTree(const blink::FrameSelection* sel) { |
1409 if (sel) | 1424 if (sel) |
1410 sel->showTreeForThis(); | 1425 sel->showTreeForThis(); |
1411 else | 1426 else |
1412 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; | 1427 LOG(INFO) << "Cannot showTree for <null> FrameSelection."; |
1413 } | 1428 } |
1414 | 1429 |
1415 #endif | 1430 #endif |
OLD | NEW |