4ff490bca3ae0f363cdb1e5a2cc36adbbccd55c6
[WebKit-https.git] / Source / WebCore / editing / SelectionController.cpp
1 /*
2  * Copyright (C) 2004, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25   
26 #include "config.h"
27 #include "SelectionController.h"
28
29 #include "CharacterData.h"
30 #include "DeleteSelectionCommand.h"
31 #include "Document.h"
32 #include "Editor.h"
33 #include "EditorClient.h"
34 #include "Element.h"
35 #include "EventHandler.h"
36 #include "ExceptionCode.h"
37 #include "FloatQuad.h"
38 #include "FocusController.h"
39 #include "Frame.h"
40 #include "FrameTree.h"
41 #include "FrameView.h"
42 #include "GraphicsContext.h"
43 #include "HTMLFormElement.h"
44 #include "HTMLFrameElementBase.h"
45 #include "HTMLInputElement.h"
46 #include "HTMLNames.h"
47 #include "HitTestRequest.h"
48 #include "HitTestResult.h"
49 #include "Page.h"
50 #include "Range.h"
51 #include "RenderLayer.h"
52 #include "RenderTextControl.h"
53 #include "RenderTheme.h"
54 #include "RenderView.h"
55 #include "RenderWidget.h"
56 #include "SecureTextInput.h"
57 #include "Settings.h"
58 #include "TextIterator.h"
59 #include "TypingCommand.h"
60 #include "htmlediting.h"
61 #include "visible_units.h"
62 #include <stdio.h>
63 #include <wtf/text/CString.h>
64
65 #define EDIT_DEBUG 0
66
67 namespace WebCore {
68
69 using namespace HTMLNames;
70
71 const int NoXPosForVerticalArrowNavigation = INT_MIN;
72
73 SelectionController::SelectionController(Frame* frame, bool isDragCaretController)
74     : m_frame(frame)
75     , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation)
76     , m_granularity(CharacterGranularity)
77     , m_caretBlinkTimer(this, &SelectionController::caretBlinkTimerFired)
78     , m_caretRectNeedsUpdate(true)
79     , m_absCaretBoundsDirty(true)
80     , m_isDragCaretController(isDragCaretController)
81     , m_isCaretBlinkingSuspended(false)
82     , m_focused(frame && frame->page() && frame->page()->focusController()->focusedFrame() == frame)
83     , m_caretVisible(isDragCaretController)
84     , m_caretPaint(true)
85 {
86     setIsDirectional(false);
87 }
88
89 void SelectionController::moveTo(const VisiblePosition &pos, bool userTriggered, CursorAlignOnScroll align)
90 {
91     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
92     if (userTriggered)
93         options |= UserTriggered;
94     setSelection(VisibleSelection(pos.deepEquivalent(), pos.deepEquivalent(), pos.affinity()), options, align);
95 }
96
97 void SelectionController::moveTo(const VisiblePosition &base, const VisiblePosition &extent, bool userTriggered)
98 {
99     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
100     if (userTriggered)
101         options |= UserTriggered;
102     setSelection(VisibleSelection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()), options);
103 }
104
105 void SelectionController::moveTo(const Position &pos, EAffinity affinity, bool userTriggered)
106 {
107     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
108     if (userTriggered)
109         options |= UserTriggered;
110     setSelection(VisibleSelection(pos, affinity), options);
111 }
112
113 void SelectionController::moveTo(const Range *r, EAffinity affinity, bool userTriggered)
114 {
115     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
116     if (userTriggered)
117         options |= UserTriggered;
118     VisibleSelection selection = r ? VisibleSelection(r->startPosition(), r->endPosition(), affinity) : VisibleSelection(Position(), Position(), affinity);
119     setSelection(selection, options);
120 }
121
122 void SelectionController::moveTo(const Position &base, const Position &extent, EAffinity affinity, bool userTriggered)
123 {
124     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
125     if (userTriggered)
126         options |= UserTriggered;
127     setSelection(VisibleSelection(base, extent, affinity), options);
128 }
129
130 void SelectionController::setSelection(const VisibleSelection& s, SetSelectionOptions options, CursorAlignOnScroll align, TextGranularity granularity, DirectionalityPolicy directionalityPolicy)
131 {
132     m_granularity = granularity;
133
134     bool closeTyping = options & CloseTyping;
135     bool shouldClearTypingStyle = options & ClearTypingStyle;
136     bool userTriggered = options & UserTriggered;
137
138     setIsDirectional(directionalityPolicy == MakeDirectionalSelection);
139
140     if (m_isDragCaretController) {
141         invalidateCaretRect();
142         m_selection = s;
143         m_caretRectNeedsUpdate = true;
144         invalidateCaretRect();
145         updateCaretRect();
146         return;
147     }
148     if (!m_frame) {
149         m_selection = s;
150         return;
151     }
152
153     // <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at SelectionController::setSelection
154     // if document->frame() == m_frame we can get into an infinite loop
155     if (s.base().anchorNode()) {
156         Document* document = s.base().anchorNode()->document();
157         if (document && document->frame() && document->frame() != m_frame && document != m_frame->document()) {
158             document->frame()->selection()->setSelection(s, options);
159             return;
160         }
161     }
162
163     if (closeTyping)
164         TypingCommand::closeTyping(m_frame->editor()->lastEditCommand());
165
166     if (shouldClearTypingStyle)
167         clearTypingStyle();
168
169     if (m_selection == s) {
170         // Even if selection was not changed, selection offsets may have been changed.
171         notifyRendererOfSelectionChange(userTriggered);
172         return;
173     }
174
175     VisibleSelection oldSelection = m_selection;
176
177     m_selection = s;
178     
179     m_caretRectNeedsUpdate = true;
180     
181     if (!s.isNone())
182         setFocusedNodeIfNeeded();
183     
184     updateAppearance();
185
186     // Always clear the x position used for vertical arrow navigation.
187     // It will be restored by the vertical arrow navigation code if necessary.
188     m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
189     selectFrameElementInParentIfFullySelected();
190     notifyRendererOfSelectionChange(userTriggered);
191     m_frame->editor()->respondToChangedSelection(oldSelection, options);
192     if (userTriggered) {
193         ScrollAlignment alignment;
194
195         if (m_frame->editor()->behavior().shouldCenterAlignWhenSelectionIsRevealed())
196             alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::alignCenterAlways : ScrollAlignment::alignCenterIfNeeded;
197         else
198             alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded;
199
200         revealSelection(alignment, true);
201     }
202
203     notifyAccessibilityForSelectionChange();
204     m_frame->document()->enqueueDocumentEvent(Event::create(eventNames().selectionchangeEvent, false, false));
205 }
206
207 static bool removingNodeRemovesPosition(Node* node, const Position& position)
208 {
209     if (!position.anchorNode())
210         return false;
211
212     if (position.anchorNode() == node)
213         return true;
214
215     if (!node->isElementNode())
216         return false;
217
218     Element* element = static_cast<Element*>(node);
219     return element->contains(position.anchorNode()) || element->contains(position.anchorNode()->shadowAncestorNode());
220 }
221
222 void SelectionController::nodeWillBeRemoved(Node *node)
223 {
224     if (isNone())
225         return;
226
227     // There can't be a selection inside a fragment, so if a fragment's node is being removed,
228     // the selection in the document that created the fragment needs no adjustment.
229     if (node && highestAncestor(node)->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
230         return;
231
232     respondToNodeModification(node, removingNodeRemovesPosition(node, m_selection.base()), removingNodeRemovesPosition(node, m_selection.extent()),
233         removingNodeRemovesPosition(node, m_selection.start()), removingNodeRemovesPosition(node, m_selection.end()));
234 }
235
236 void SelectionController::respondToNodeModification(Node* node, bool baseRemoved, bool extentRemoved, bool startRemoved, bool endRemoved)
237 {
238     bool clearRenderTreeSelection = false;
239     bool clearDOMTreeSelection = false;
240
241     if (startRemoved || endRemoved) {
242         // FIXME: When endpoints are removed, we should just alter the selection, instead of blowing it away.
243         clearRenderTreeSelection = true;
244         clearDOMTreeSelection = true;
245     } else if (baseRemoved || extentRemoved) {
246         // The base and/or extent are about to be removed, but the start and end aren't.
247         // Change the base and extent to the start and end, but don't re-validate the
248         // selection, since doing so could move the start and end into the node
249         // that is about to be removed.
250         if (m_selection.isBaseFirst())
251             m_selection.setWithoutValidation(m_selection.start(), m_selection.end());
252         else
253             m_selection.setWithoutValidation(m_selection.end(), m_selection.start());
254     } else if (m_selection.firstRange()) {
255         ExceptionCode ec = 0;
256         Range::CompareResults compareResult = m_selection.firstRange()->compareNode(node, ec);
257         if (!ec && (compareResult == Range::NODE_BEFORE_AND_AFTER || compareResult == Range::NODE_INSIDE)) {
258             // If we did nothing here, when this node's renderer was destroyed, the rect that it 
259             // occupied would be invalidated, but, selection gaps that change as a result of 
260             // the removal wouldn't be invalidated.
261             // FIXME: Don't do so much unnecessary invalidation.
262             clearRenderTreeSelection = true;
263         }
264     }
265
266     if (clearRenderTreeSelection) {
267         RefPtr<Document> document = m_selection.start().anchorNode()->document();
268         document->updateStyleIfNeeded();
269         if (RenderView* view = toRenderView(document->renderer()))
270             view->clearSelection();
271     }
272
273     if (clearDOMTreeSelection)
274         setSelection(VisibleSelection(), 0);
275 }
276
277 enum EndPointType { EndPointIsStart, EndPointIsEnd };
278
279 static bool shouldRemovePositionAfterAdoptingTextReplacement(Position& position, EndPointType type, CharacterData* node, unsigned offset, unsigned oldLength, unsigned newLength)
280 {
281     if (!position.anchorNode() || position.anchorNode() != node || position.anchorType() != Position::PositionIsOffsetInAnchor)
282         return false;
283
284     ASSERT(position.offsetInContainerNode() >= 0);
285     unsigned positionOffset = static_cast<unsigned>(position.offsetInContainerNode());
286     if (positionOffset > offset && positionOffset < offset + oldLength)
287         return true;
288
289     // Adjust the offset if the position is after or at the end of the deleted contents (positionOffset >= offset + oldLength)
290     // to avoid having a stale offset except when the position is the end of selection and nothing is deleted, in which case,
291     // adjusting offset results in incorrectly extending the selection until the end of newly inserted contents.
292     if ((positionOffset > offset + oldLength) || (positionOffset == offset + oldLength && (type == EndPointIsStart || oldLength)))
293         position.moveToOffset(positionOffset - oldLength + newLength);
294
295     return false;
296 }
297
298 void SelectionController::textWillBeReplaced(CharacterData* node, unsigned offset, unsigned oldLength, unsigned newLength)
299 {
300     // The fragment check is a performance optimization. See http://trac.webkit.org/changeset/30062.
301     if (isNone() || !node || highestAncestor(node)->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
302         return;
303
304     Position base = m_selection.base();
305     Position extent = m_selection.extent();
306     Position start = m_selection.start();
307     Position end = m_selection.end();
308     bool shouldRemoveBase = shouldRemovePositionAfterAdoptingTextReplacement(base, m_selection.isBaseFirst() ? EndPointIsStart : EndPointIsEnd, node, offset, oldLength, newLength);
309     bool shouldRemoveExtent = shouldRemovePositionAfterAdoptingTextReplacement(extent, m_selection.isBaseFirst() ? EndPointIsEnd : EndPointIsStart, node, offset, oldLength, newLength);
310     bool shouldRemoveStart = shouldRemovePositionAfterAdoptingTextReplacement(start, EndPointIsStart, node, offset, oldLength, newLength);
311     bool shouldRemoveEnd = shouldRemovePositionAfterAdoptingTextReplacement(end, EndPointIsEnd, node, offset, oldLength, newLength);
312
313     if ((base != m_selection.base() || extent != m_selection.extent() || start != m_selection.start() || end != m_selection.end())
314         && !shouldRemoveStart && !shouldRemoveEnd) {
315         VisibleSelection newSelection;
316         if (!shouldRemoveBase && !shouldRemoveExtent)
317             newSelection.setWithoutValidation(base, extent);
318         else {
319             if (newSelection.isBaseFirst())
320                 newSelection.setWithoutValidation(start, end);
321             else
322                 newSelection.setWithoutValidation(end, start);
323         }
324         m_frame->document()->updateLayout();
325         setSelection(newSelection, 0);
326         return;
327     }
328
329     respondToNodeModification(node, shouldRemoveBase, shouldRemoveExtent, shouldRemoveStart, shouldRemoveEnd);
330 }
331
332 void SelectionController::setIsDirectional(bool isDirectional)
333 {
334     m_isDirectional = !m_frame || m_frame->editor()->behavior().shouldConsiderSelectionAsDirectional() || isDirectional;
335 }
336
337 TextDirection SelectionController::directionOfEnclosingBlock()
338 {
339     return WebCore::directionOfEnclosingBlock(m_selection.extent());
340 }
341
342 void SelectionController::willBeModified(EAlteration alter, SelectionDirection direction)
343 {
344     if (alter != AlterationExtend)
345         return;
346
347     Position start = m_selection.start();
348     Position end = m_selection.end();
349
350     bool baseIsStart = true;
351
352     if (m_isDirectional) {
353         // Make base and extent match start and end so we extend the user-visible selection.
354         // This only matters for cases where base and extend point to different positions than
355         // start and end (e.g. after a double-click to select a word).
356         if (m_selection.isBaseFirst())
357             baseIsStart = true;
358         else
359             baseIsStart = false;
360     } else {
361         switch (direction) {
362         case DirectionRight:
363             if (directionOfEnclosingBlock() == LTR)
364                 baseIsStart = true;
365             else
366                 baseIsStart = false;
367             break;
368         case DirectionForward:
369             baseIsStart = true;
370             break;
371         case DirectionLeft:
372             if (directionOfEnclosingBlock() == LTR)
373                 baseIsStart = false;
374             else
375                 baseIsStart = true;
376             break;
377         case DirectionBackward:
378             baseIsStart = false;
379             break;
380         }
381     }
382     if (baseIsStart) {
383         m_selection.setBase(start);
384         m_selection.setExtent(end);
385     } else {
386         m_selection.setBase(end);
387         m_selection.setExtent(start);
388     }
389 }
390
391 VisiblePosition SelectionController::positionForPlatform(bool isGetStart) const
392 {
393     Settings* settings = m_frame ? m_frame->settings() : 0;
394     if (settings && settings->editingBehaviorType() == EditingMacBehavior)
395         return isGetStart ? m_selection.visibleStart() : m_selection.visibleEnd();
396     // Linux and Windows always extend selections from the extent endpoint.
397     // FIXME: VisibleSelection should be fixed to ensure as an invariant that
398     // base/extent always point to the same nodes as start/end, but which points
399     // to which depends on the value of isBaseFirst. Then this can be changed
400     // to just return m_sel.extent().
401     return m_selection.isBaseFirst() ? m_selection.visibleEnd() : m_selection.visibleStart();
402 }
403
404 VisiblePosition SelectionController::startForPlatform() const
405 {
406     return positionForPlatform(true);
407 }
408
409 VisiblePosition SelectionController::endForPlatform() const
410 {
411     return positionForPlatform(false);
412 }
413
414 VisiblePosition SelectionController::modifyExtendingRight(TextGranularity granularity)
415 {
416     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
417
418     // The difference between modifyExtendingRight and modifyExtendingForward is:
419     // modifyExtendingForward always extends forward logically.
420     // modifyExtendingRight behaves the same as modifyExtendingForward except for extending character or word,
421     // it extends forward logically if the enclosing block is LTR direction,
422     // but it extends backward logically if the enclosing block is RTL direction.
423     switch (granularity) {
424     case CharacterGranularity:
425         if (directionOfEnclosingBlock() == LTR)
426             pos = pos.next(CannotCrossEditingBoundary);
427         else
428             pos = pos.previous(CannotCrossEditingBoundary);
429         break;
430     case WordGranularity:
431         if (directionOfEnclosingBlock() == LTR)
432             pos = nextWordPosition(pos);
433         else
434             pos = previousWordPosition(pos);
435         break;
436     case LineBoundary:
437         if (directionOfEnclosingBlock() == LTR)
438             pos = modifyExtendingForward(granularity);
439         else
440             pos = modifyExtendingBackward(granularity);
441         break;
442     case SentenceGranularity:
443     case LineGranularity:
444     case ParagraphGranularity:
445     case SentenceBoundary:
446     case ParagraphBoundary:
447     case DocumentBoundary:
448         // FIXME: implement all of the above?
449         pos = modifyExtendingForward(granularity);
450     }
451     return pos;
452 }
453
454 VisiblePosition SelectionController::modifyExtendingForward(TextGranularity granularity)
455 {
456     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
457     switch (granularity) {
458     case CharacterGranularity:
459         pos = pos.next(CannotCrossEditingBoundary);
460         break;
461     case WordGranularity:
462         pos = nextWordPosition(pos);
463         break;
464     case SentenceGranularity:
465         pos = nextSentencePosition(pos);
466         break;
467     case LineGranularity:
468         pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
469         break;
470     case ParagraphGranularity:
471         pos = nextParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
472         break;
473     case SentenceBoundary:
474         pos = endOfSentence(endForPlatform());
475         break;
476     case LineBoundary:
477         pos = logicalEndOfLine(endForPlatform());
478         break;
479     case ParagraphBoundary:
480         pos = endOfParagraph(endForPlatform());
481         break;
482     case DocumentBoundary:
483         pos = endForPlatform();
484         if (isEditablePosition(pos.deepEquivalent()))
485             pos = endOfEditableContent(pos);
486         else
487             pos = endOfDocument(pos);
488         break;
489     }
490     
491     return pos;
492 }
493
494 VisiblePosition SelectionController::modifyMovingRight(TextGranularity granularity)
495 {
496     VisiblePosition pos;
497     switch (granularity) {
498     case CharacterGranularity:
499         if (isRange()) {
500             if (directionOfEnclosingBlock() == LTR)
501                 pos = VisiblePosition(m_selection.end(), m_selection.affinity());
502             else
503                 pos = VisiblePosition(m_selection.start(), m_selection.affinity());
504         } else
505             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).right(true);
506         break;
507     case WordGranularity:
508     case SentenceGranularity:
509     case LineGranularity:
510     case ParagraphGranularity:
511     case SentenceBoundary:
512     case ParagraphBoundary:
513     case DocumentBoundary:
514         // FIXME: Implement all of the above.
515         pos = modifyMovingForward(granularity);
516         break;
517     case LineBoundary:
518         pos = rightBoundaryOfLine(startForPlatform(), directionOfEnclosingBlock());
519         break;
520     }
521     return pos;
522 }
523
524 VisiblePosition SelectionController::modifyMovingForward(TextGranularity granularity)
525 {
526     VisiblePosition pos;
527     // FIXME: Stay in editable content for the less common granularities.
528     switch (granularity) {
529     case CharacterGranularity:
530         if (isRange())
531             pos = VisiblePosition(m_selection.end(), m_selection.affinity());
532         else
533             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).next(CannotCrossEditingBoundary);
534         break;
535     case WordGranularity:
536         pos = nextWordPosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
537         break;
538     case SentenceGranularity:
539         pos = nextSentencePosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
540         break;
541     case LineGranularity: {
542         // down-arrowing from a range selection that ends at the start of a line needs
543         // to leave the selection at that line start (no need to call nextLinePosition!)
544         pos = endForPlatform();
545         if (!isRange() || !isStartOfLine(pos))
546             pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(START));
547         break;
548     }
549     case ParagraphGranularity:
550         pos = nextParagraphPosition(endForPlatform(), xPosForVerticalArrowNavigation(START));
551         break;
552     case SentenceBoundary:
553         pos = endOfSentence(endForPlatform());
554         break;
555     case LineBoundary:
556         pos = logicalEndOfLine(endForPlatform());
557         break;
558     case ParagraphBoundary:
559         pos = endOfParagraph(endForPlatform());
560         break;
561     case DocumentBoundary:
562         pos = endForPlatform();
563         if (isEditablePosition(pos.deepEquivalent()))
564             pos = endOfEditableContent(pos);
565         else
566             pos = endOfDocument(pos);
567         break;
568     }
569     return pos;
570 }
571
572 VisiblePosition SelectionController::modifyExtendingLeft(TextGranularity granularity)
573 {
574     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
575
576     // The difference between modifyExtendingLeft and modifyExtendingBackward is:
577     // modifyExtendingBackward always extends backward logically.
578     // modifyExtendingLeft behaves the same as modifyExtendingBackward except for extending character or word,
579     // it extends backward logically if the enclosing block is LTR direction,
580     // but it extends forward logically if the enclosing block is RTL direction.
581     switch (granularity) {
582     case CharacterGranularity:
583         if (directionOfEnclosingBlock() == LTR)
584             pos = pos.previous(CannotCrossEditingBoundary);
585         else
586             pos = pos.next(CannotCrossEditingBoundary);
587         break;
588     case WordGranularity:
589         if (directionOfEnclosingBlock() == LTR)
590             pos = previousWordPosition(pos);
591         else
592             pos = nextWordPosition(pos);
593         break;
594     case LineBoundary:
595         if (directionOfEnclosingBlock() == LTR)
596             pos = modifyExtendingBackward(granularity);
597         else
598             pos = modifyExtendingForward(granularity);
599         break;
600     case SentenceGranularity:
601     case LineGranularity:
602     case ParagraphGranularity:
603     case SentenceBoundary:
604     case ParagraphBoundary:
605     case DocumentBoundary:
606         pos = modifyExtendingBackward(granularity);
607     }
608     return pos;
609 }
610        
611 VisiblePosition SelectionController::modifyExtendingBackward(TextGranularity granularity)
612 {
613     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
614
615     // Extending a selection backward by word or character from just after a table selects
616     // the table.  This "makes sense" from the user perspective, esp. when deleting.
617     // It was done here instead of in VisiblePosition because we want VPs to iterate
618     // over everything.
619     switch (granularity) {
620     case CharacterGranularity:
621         pos = pos.previous(CannotCrossEditingBoundary);
622         break;
623     case WordGranularity:
624         pos = previousWordPosition(pos);
625         break;
626     case SentenceGranularity:
627         pos = previousSentencePosition(pos);
628         break;
629     case LineGranularity:
630         pos = previousLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
631         break;
632     case ParagraphGranularity:
633         pos = previousParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
634         break;
635     case SentenceBoundary:
636         pos = startOfSentence(startForPlatform());
637         break;
638     case LineBoundary:
639         pos = logicalStartOfLine(startForPlatform());
640         break;
641     case ParagraphBoundary:
642         pos = startOfParagraph(startForPlatform());
643         break;
644     case DocumentBoundary:
645         pos = startForPlatform();
646         if (isEditablePosition(pos.deepEquivalent()))
647             pos = startOfEditableContent(pos);
648         else
649             pos = startOfDocument(pos);
650         break;
651     }
652     return pos;
653 }
654
655 VisiblePosition SelectionController::modifyMovingLeft(TextGranularity granularity)
656 {
657     VisiblePosition pos;
658     switch (granularity) {
659     case CharacterGranularity:
660         if (isRange())
661             if (directionOfEnclosingBlock() == LTR)
662                 pos = VisiblePosition(m_selection.start(), m_selection.affinity());
663             else
664                 pos = VisiblePosition(m_selection.end(), m_selection.affinity());
665         else
666             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).left(true);
667         break;
668     case WordGranularity:
669     case SentenceGranularity:
670     case LineGranularity:
671     case ParagraphGranularity:
672     case SentenceBoundary:
673     case ParagraphBoundary:
674     case DocumentBoundary:
675         // FIXME: Implement all of the above.
676         pos = modifyMovingBackward(granularity);
677         break;
678     case LineBoundary:
679         pos = leftBoundaryOfLine(startForPlatform(), directionOfEnclosingBlock());
680         break;
681     }
682     return pos;
683 }
684
685 VisiblePosition SelectionController::modifyMovingBackward(TextGranularity granularity)
686 {
687     VisiblePosition pos;
688     switch (granularity) {
689     case CharacterGranularity:
690         if (isRange())
691             pos = VisiblePosition(m_selection.start(), m_selection.affinity());
692         else
693             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).previous(CannotCrossEditingBoundary);
694         break;
695     case WordGranularity:
696         pos = previousWordPosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
697         break;
698     case SentenceGranularity:
699         pos = previousSentencePosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
700         break;
701     case LineGranularity:
702         pos = previousLinePosition(startForPlatform(), xPosForVerticalArrowNavigation(START));
703         break;
704     case ParagraphGranularity:
705         pos = previousParagraphPosition(startForPlatform(), xPosForVerticalArrowNavigation(START));
706         break;
707     case SentenceBoundary:
708         pos = startOfSentence(startForPlatform());
709         break;
710     case LineBoundary:
711         pos = logicalStartOfLine(startForPlatform());
712         break;
713     case ParagraphBoundary:
714         pos = startOfParagraph(startForPlatform());
715         break;
716     case DocumentBoundary:
717         pos = startForPlatform();
718         if (isEditablePosition(pos.deepEquivalent()))
719             pos = startOfEditableContent(pos);
720         else
721             pos = startOfDocument(pos);
722         break;
723     }
724     return pos;
725 }
726
727 static bool isBoundary(TextGranularity granularity)
728 {
729     return granularity == LineBoundary || granularity == ParagraphBoundary || granularity == DocumentBoundary;
730 }    
731
732 bool SelectionController::modify(EAlteration alter, SelectionDirection direction, TextGranularity granularity, bool userTriggered)
733 {
734     if (userTriggered) {
735         SelectionController trialSelectionController;
736         trialSelectionController.setSelection(m_selection);
737         trialSelectionController.setIsDirectional(m_isDirectional);
738         trialSelectionController.modify(alter, direction, granularity, false);
739
740         bool change = shouldChangeSelection(trialSelectionController.selection());
741         if (!change)
742             return false;
743     }
744
745     willBeModified(alter, direction);
746
747     bool wasRange = m_selection.isRange();
748     Position originalStartPosition = m_selection.start();
749     VisiblePosition position;
750     switch (direction) {
751     case DirectionRight:
752         if (alter == AlterationMove)
753             position = modifyMovingRight(granularity);
754         else
755             position = modifyExtendingRight(granularity);
756         break;
757     case DirectionForward:
758         if (alter == AlterationExtend)
759             position = modifyExtendingForward(granularity);
760         else
761             position = modifyMovingForward(granularity);
762         break;
763     case DirectionLeft:
764         if (alter == AlterationMove)
765             position = modifyMovingLeft(granularity);
766         else
767             position = modifyExtendingLeft(granularity);
768         break;
769     case DirectionBackward:
770         if (alter == AlterationExtend)
771             position = modifyExtendingBackward(granularity);
772         else
773             position = modifyMovingBackward(granularity);
774         break;
775     }
776
777     if (position.isNull())
778         return false;
779
780     if (isSpatialNavigationEnabled(m_frame))
781         if (!wasRange && alter == AlterationMove && position == originalStartPosition)
782             return false;
783
784     // Some of the above operations set an xPosForVerticalArrowNavigation.
785     // Setting a selection will clear it, so save it to possibly restore later.
786     // Note: the START position type is arbitrary because it is unused, it would be
787     // the requested position type if there were no xPosForVerticalArrowNavigation set.
788     int x = xPosForVerticalArrowNavigation(START);
789
790     switch (alter) {
791     case AlterationMove:
792         moveTo(position, userTriggered);
793         break;
794     case AlterationExtend:
795         // Standard Mac behavior when extending to a boundary is grow the selection rather than leaving the
796         // base in place and moving the extent. Matches NSTextView.
797         if (!m_frame || !m_frame->editor()->behavior().shouldAlwaysGrowSelectionWhenExtendingToBoundary() || m_selection.isCaret() || !isBoundary(granularity))
798             setExtent(position, userTriggered);
799         else {
800             TextDirection textDirection = directionOfEnclosingBlock();
801             if (direction == DirectionForward || (textDirection == LTR && direction == DirectionRight) || (textDirection == RTL && direction == DirectionLeft))
802                 setEnd(position, userTriggered);
803             else
804                 setStart(position, userTriggered);
805         }
806         break;
807     }
808     
809     if (granularity == LineGranularity || granularity == ParagraphGranularity)
810         m_xPosForVerticalArrowNavigation = x;
811
812     if (userTriggered)
813         m_granularity = CharacterGranularity;
814
815
816     setCaretRectNeedsUpdate();
817
818     setIsDirectional(alter == AlterationExtend);
819
820     return true;
821 }
822
823 // FIXME: Maybe baseline would be better?
824 static bool absoluteCaretY(const VisiblePosition &c, int &y)
825 {
826     IntRect rect = c.absoluteCaretBounds();
827     if (rect.isEmpty())
828         return false;
829     y = rect.y() + rect.height() / 2;
830     return true;
831 }
832
833 bool SelectionController::modify(EAlteration alter, int verticalDistance, bool userTriggered, CursorAlignOnScroll align)
834 {
835     if (!verticalDistance)
836         return false;
837
838     if (userTriggered) {
839         SelectionController trialSelectionController;
840         trialSelectionController.setSelection(m_selection);
841         trialSelectionController.setIsDirectional(m_isDirectional);
842         trialSelectionController.modify(alter, verticalDistance, false);
843
844         bool change = shouldChangeSelection(trialSelectionController.selection());
845         if (!change)
846             return false;
847     }
848
849     bool up = verticalDistance < 0;
850     if (up)
851         verticalDistance = -verticalDistance;
852
853     willBeModified(alter, up ? DirectionBackward : DirectionForward);
854
855     VisiblePosition pos;
856     int xPos = 0;
857     switch (alter) {
858     case AlterationMove:
859         pos = VisiblePosition(up ? m_selection.start() : m_selection.end(), m_selection.affinity());
860         xPos = xPosForVerticalArrowNavigation(up ? START : END);
861         m_selection.setAffinity(up ? UPSTREAM : DOWNSTREAM);
862         break;
863     case AlterationExtend:
864         pos = VisiblePosition(m_selection.extent(), m_selection.affinity());
865         xPos = xPosForVerticalArrowNavigation(EXTENT);
866         m_selection.setAffinity(DOWNSTREAM);
867         break;
868     }
869
870     int startY;
871     if (!absoluteCaretY(pos, startY))
872         return false;
873     if (up)
874         startY = -startY;
875     int lastY = startY;
876
877     VisiblePosition result;
878     VisiblePosition next;
879     for (VisiblePosition p = pos; ; p = next) {
880         next = (up ? previousLinePosition : nextLinePosition)(p, xPos);
881         if (next.isNull() || next == p)
882             break;
883         int nextY;
884         if (!absoluteCaretY(next, nextY))
885             break;
886         if (up)
887             nextY = -nextY;
888         if (nextY - startY > verticalDistance)
889             break;
890         if (nextY >= lastY) {
891             lastY = nextY;
892             result = next;
893         }
894     }
895
896     if (result.isNull())
897         return false;
898
899     switch (alter) {
900     case AlterationMove:
901         moveTo(result, userTriggered, align);
902         break;
903     case AlterationExtend:
904         setExtent(result, userTriggered);
905         break;
906     }
907
908     if (userTriggered)
909         m_granularity = CharacterGranularity;
910
911     setIsDirectional(alter == AlterationExtend);
912
913     return true;
914 }
915
916 int SelectionController::xPosForVerticalArrowNavigation(EPositionType type)
917 {
918     int x = 0;
919
920     if (isNone())
921         return x;
922
923     Position pos;
924     switch (type) {
925     case START:
926         pos = m_selection.start();
927         break;
928     case END:
929         pos = m_selection.end();
930         break;
931     case BASE:
932         pos = m_selection.base();
933         break;
934     case EXTENT:
935         pos = m_selection.extent();
936         break;
937     }
938
939     Frame* frame = pos.anchorNode()->document()->frame();
940     if (!frame)
941         return x;
942         
943     if (m_xPosForVerticalArrowNavigation == NoXPosForVerticalArrowNavigation) {
944         VisiblePosition visiblePosition(pos, m_selection.affinity());
945         // VisiblePosition creation can fail here if a node containing the selection becomes visibility:hidden
946         // after the selection is created and before this function is called.
947         x = visiblePosition.isNotNull() ? visiblePosition.xOffsetForVerticalNavigation() : 0;
948         m_xPosForVerticalArrowNavigation = x;
949     } else
950         x = m_xPosForVerticalArrowNavigation;
951         
952     return x;
953 }
954
955 void SelectionController::clear()
956 {
957     m_granularity = CharacterGranularity;
958     setSelection(VisibleSelection());
959 }
960
961 void SelectionController::setStart(const VisiblePosition &pos, bool userTriggered)
962 {
963     if (m_selection.isBaseFirst())
964         setBase(pos, userTriggered);
965     else
966         setExtent(pos, userTriggered);
967 }
968
969 void SelectionController::setEnd(const VisiblePosition &pos, bool userTriggered)
970 {
971     if (m_selection.isBaseFirst())
972         setExtent(pos, userTriggered);
973     else
974         setBase(pos, userTriggered);
975 }
976
977 void SelectionController::setBase(const VisiblePosition &pos, bool userTriggered)
978 {
979     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
980     if (userTriggered)
981         options |= UserTriggered;
982     setSelection(VisibleSelection(pos.deepEquivalent(), m_selection.extent(), pos.affinity()), options);
983 }
984
985 void SelectionController::setExtent(const VisiblePosition &pos, bool userTriggered)
986 {
987     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
988     if (userTriggered)
989         options |= UserTriggered;
990     setSelection(VisibleSelection(m_selection.base(), pos.deepEquivalent(), pos.affinity()), options);
991 }
992
993 void SelectionController::setBase(const Position &pos, EAffinity affinity, bool userTriggered)
994 {
995     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
996     if (userTriggered)
997         options |= UserTriggered;
998     setSelection(VisibleSelection(pos, m_selection.extent(), affinity), options);
999 }
1000
1001 void SelectionController::setExtent(const Position &pos, EAffinity affinity, bool userTriggered)
1002 {
1003     SetSelectionOptions options = CloseTyping | ClearTypingStyle;
1004     if (userTriggered)
1005         options |= UserTriggered;
1006     setSelection(VisibleSelection(m_selection.base(), pos, affinity), options);
1007 }
1008
1009 void SelectionController::setCaretRectNeedsUpdate(bool flag)
1010 {
1011     m_caretRectNeedsUpdate = flag;
1012 }
1013
1014 void SelectionController::updateCaretRect()
1015 {
1016     if (isNone() || !m_selection.start().anchorNode()->inDocument() || !m_selection.end().anchorNode()->inDocument()) {
1017         m_caretRect = IntRect();
1018         return;
1019     }
1020
1021     m_selection.start().anchorNode()->document()->updateStyleIfNeeded();
1022     
1023     m_caretRect = IntRect();
1024         
1025     if (isCaret()) {
1026         VisiblePosition pos(m_selection.start(), m_selection.affinity());
1027         if (pos.isNotNull()) {
1028             ASSERT(pos.deepEquivalent().deprecatedNode()->renderer());
1029             
1030             // First compute a rect local to the renderer at the selection start
1031             RenderObject* renderer;
1032             IntRect localRect = pos.localCaretRect(renderer);
1033
1034             // Get the renderer that will be responsible for painting the caret (which
1035             // is either the renderer we just found, or one of its containers)
1036             RenderObject* caretPainter = caretRenderer();
1037
1038             // Compute an offset between the renderer and the caretPainter
1039             bool unrooted = false;
1040             while (renderer != caretPainter) {
1041                 RenderObject* containerObject = renderer->container();
1042                 if (!containerObject) {
1043                     unrooted = true;
1044                     break;
1045                 }
1046                 localRect.move(renderer->offsetFromContainer(containerObject, localRect.location()));
1047                 renderer = containerObject;
1048             }
1049             
1050             if (!unrooted)
1051                 m_caretRect = localRect;
1052             
1053             m_absCaretBoundsDirty = true;
1054         }
1055     }
1056
1057     m_caretRectNeedsUpdate = false;
1058 }
1059
1060 RenderObject* SelectionController::caretRenderer() const
1061 {
1062     Node* node = m_selection.start().deprecatedNode();
1063     if (!node)
1064         return 0;
1065
1066     RenderObject* renderer = node->renderer();
1067     if (!renderer)
1068         return 0;
1069
1070     // if caretNode is a block and caret is inside it then caret should be painted by that block
1071     bool paintedByBlock = renderer->isBlockFlow() && caretRendersInsideNode(node);
1072     return paintedByBlock ? renderer : renderer->containingBlock();
1073 }
1074
1075 IntRect SelectionController::localCaretRect()
1076 {
1077     if (m_caretRectNeedsUpdate)
1078         updateCaretRect();
1079     
1080     return m_caretRect;
1081 }
1082
1083 IntRect SelectionController::absoluteBoundsForLocalRect(const IntRect& rect) const
1084 {
1085     RenderObject* caretPainter = caretRenderer();
1086     if (!caretPainter)
1087         return IntRect();
1088     
1089     IntRect localRect(rect);
1090     if (caretPainter->isBox())
1091         toRenderBox(caretPainter)->flipForWritingMode(localRect);
1092     return caretPainter->localToAbsoluteQuad(FloatRect(localRect)).enclosingBoundingBox();
1093 }
1094
1095 IntRect SelectionController::absoluteCaretBounds()
1096 {
1097     recomputeCaretRect();
1098     return m_absCaretBounds;
1099 }
1100
1101 static IntRect repaintRectForCaret(IntRect caret)
1102 {
1103     if (caret.isEmpty())
1104         return IntRect();
1105     // Ensure that the dirty rect intersects the block that paints the caret even in the case where
1106     // the caret itself is just outside the block. See <https://bugs.webkit.org/show_bug.cgi?id=19086>.
1107     caret.inflateX(1);
1108     return caret;
1109 }
1110
1111 IntRect SelectionController::caretRepaintRect() const
1112 {
1113     return absoluteBoundsForLocalRect(repaintRectForCaret(localCaretRectForPainting()));
1114 }
1115
1116 bool SelectionController::recomputeCaretRect()
1117 {
1118     if (!m_caretRectNeedsUpdate)
1119         return false;
1120
1121     if (!m_frame)
1122         return false;
1123         
1124     FrameView* v = m_frame->document()->view();
1125     if (!v)
1126         return false;
1127
1128     IntRect oldRect = m_caretRect;
1129     IntRect newRect = localCaretRect();
1130     if (oldRect == newRect && !m_absCaretBoundsDirty)
1131         return false;
1132
1133     IntRect oldAbsCaretBounds = m_absCaretBounds;
1134     // FIXME: Rename m_caretRect to m_localCaretRect.
1135     m_absCaretBounds = absoluteBoundsForLocalRect(m_caretRect);
1136     m_absCaretBoundsDirty = false;
1137     
1138     if (oldAbsCaretBounds == m_absCaretBounds)
1139         return false;
1140         
1141     IntRect oldAbsoluteCaretRepaintBounds = m_absoluteCaretRepaintBounds;
1142     // We believe that we need to inflate the local rect before transforming it to obtain the repaint bounds.
1143     m_absoluteCaretRepaintBounds = caretRepaintRect();
1144
1145 #if ENABLE(TEXT_CARET)    
1146     if (RenderView* view = toRenderView(m_frame->document()->renderer())) {
1147         // FIXME: make caret repainting container-aware.
1148         view->repaintRectangleInViewAndCompositedLayers(oldAbsoluteCaretRepaintBounds, false);
1149         if (shouldRepaintCaret(view))
1150             view->repaintRectangleInViewAndCompositedLayers(m_absoluteCaretRepaintBounds, false);
1151     }
1152 #endif
1153     return true;
1154 }
1155
1156 bool SelectionController::shouldRepaintCaret(const RenderView* view) const
1157 {
1158     ASSERT(view);
1159     Frame* frame = view->frameView() ? view->frameView()->frame() : 0; // The frame where the selection started.
1160     bool caretBrowsing = frame && frame->settings() && frame->settings()->caretBrowsingEnabled();
1161     return (caretBrowsing || isContentEditable());
1162 }
1163
1164 void SelectionController::invalidateCaretRect()
1165 {
1166     if (!isCaret())
1167         return;
1168
1169     Document* d = m_selection.start().anchorNode()->document();
1170
1171     // recomputeCaretRect will always return false for the drag caret,
1172     // because its m_frame is always 0.
1173     bool caretRectChanged = recomputeCaretRect();
1174
1175     // EDIT FIXME: This is an unfortunate hack.
1176     // Basically, we can't trust this layout position since we 
1177     // can't guarantee that the check to see if we are in unrendered 
1178     // content will work at this point. We may have to wait for
1179     // a layout and re-render of the document to happen. So, resetting this
1180     // flag will cause another caret layout to happen the first time
1181     // that we try to paint the caret after this call. That one will work since
1182     // it happens after the document has accounted for any editing
1183     // changes which may have been done.
1184     // And, we need to leave this layout here so the caret moves right 
1185     // away after clicking.
1186     m_caretRectNeedsUpdate = true;
1187
1188     if (!caretRectChanged) {
1189         RenderView* view = toRenderView(d->renderer());
1190         if (view && shouldRepaintCaret(view))
1191             view->repaintRectangleInViewAndCompositedLayers(caretRepaintRect(), false);
1192     }
1193 }
1194
1195 void SelectionController::paintCaret(GraphicsContext* context, int tx, int ty, const IntRect& clipRect)
1196 {
1197 #if ENABLE(TEXT_CARET)
1198     if (!m_caretVisible)
1199         return;
1200     if (!m_caretPaint)
1201         return;
1202     if (!m_selection.isCaret())
1203         return;
1204
1205     IntRect drawingRect = localCaretRectForPainting();
1206     if (caretRenderer() && caretRenderer()->isBox())
1207         toRenderBox(caretRenderer())->flipForWritingMode(drawingRect);
1208     drawingRect.move(tx, ty);
1209     IntRect caret = intersection(drawingRect, clipRect);
1210     if (caret.isEmpty())
1211         return;
1212
1213     Color caretColor = Color::black;
1214     ColorSpace colorSpace = ColorSpaceDeviceRGB;
1215     Element* element = rootEditableElement();
1216     if (element && element->renderer()) {
1217         caretColor = element->renderer()->style()->visitedDependentColor(CSSPropertyColor);
1218         colorSpace = element->renderer()->style()->colorSpace();
1219     }
1220
1221     context->fillRect(caret, caretColor, colorSpace);
1222 #else
1223     UNUSED_PARAM(context);
1224     UNUSED_PARAM(tx);
1225     UNUSED_PARAM(ty);
1226     UNUSED_PARAM(clipRect);
1227 #endif
1228 }
1229
1230 void SelectionController::debugRenderer(RenderObject *r, bool selected) const
1231 {
1232     if (r->node()->isElementNode()) {
1233         Element* element = static_cast<Element *>(r->node());
1234         fprintf(stderr, "%s%s\n", selected ? "==> " : "    ", element->localName().string().utf8().data());
1235     } else if (r->isText()) {
1236         RenderText* textRenderer = toRenderText(r);
1237         if (!textRenderer->textLength() || !textRenderer->firstTextBox()) {
1238             fprintf(stderr, "%s#text (empty)\n", selected ? "==> " : "    ");
1239             return;
1240         }
1241         
1242         static const int max = 36;
1243         String text = textRenderer->text();
1244         int textLength = text.length();
1245         if (selected) {
1246             int offset = 0;
1247             if (r->node() == m_selection.start().containerNode())
1248                 offset = m_selection.start().computeOffsetInContainerNode();
1249             else if (r->node() == m_selection.end().containerNode())
1250                 offset = m_selection.end().computeOffsetInContainerNode();
1251
1252             int pos;
1253             InlineTextBox* box = textRenderer->findNextInlineTextBox(offset, pos);
1254             text = text.substring(box->start(), box->len());
1255             
1256             String show;
1257             int mid = max / 2;
1258             int caret = 0;
1259             
1260             // text is shorter than max
1261             if (textLength < max) {
1262                 show = text;
1263                 caret = pos;
1264             } else if (pos - mid < 0) {
1265                 // too few characters to left
1266                 show = text.left(max - 3) + "...";
1267                 caret = pos;
1268             } else if (pos - mid >= 0 && pos + mid <= textLength) {
1269                 // enough characters on each side
1270                 show = "..." + text.substring(pos - mid + 3, max - 6) + "...";
1271                 caret = mid;
1272             } else {
1273                 // too few characters on right
1274                 show = "..." + text.right(max - 3);
1275                 caret = pos - (textLength - show.length());
1276             }
1277             
1278             show.replace('\n', ' ');
1279             show.replace('\r', ' ');
1280             fprintf(stderr, "==> #text : \"%s\" at offset %d\n", show.utf8().data(), pos);
1281             fprintf(stderr, "           ");
1282             for (int i = 0; i < caret; i++)
1283                 fprintf(stderr, " ");
1284             fprintf(stderr, "^\n");
1285         } else {
1286             if ((int)text.length() > max)
1287                 text = text.left(max - 3) + "...";
1288             else
1289                 text = text.left(max);
1290             fprintf(stderr, "    #text : \"%s\"\n", text.utf8().data());
1291         }
1292     }
1293 }
1294
1295 bool SelectionController::contains(const IntPoint& point)
1296 {
1297     Document* document = m_frame->document();
1298     
1299     // Treat a collapsed selection like no selection.
1300     if (!isRange())
1301         return false;
1302     if (!document->renderer()) 
1303         return false;
1304     
1305     HitTestRequest request(HitTestRequest::ReadOnly |
1306                            HitTestRequest::Active);
1307     HitTestResult result(point);
1308     document->renderView()->layer()->hitTest(request, result);
1309     Node* innerNode = result.innerNode();
1310     if (!innerNode || !innerNode->renderer())
1311         return false;
1312     
1313     VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(result.localPoint()));
1314     if (visiblePos.isNull())
1315         return false;
1316         
1317     if (m_selection.visibleStart().isNull() || m_selection.visibleEnd().isNull())
1318         return false;
1319         
1320     Position start(m_selection.visibleStart().deepEquivalent());
1321     Position end(m_selection.visibleEnd().deepEquivalent());
1322     Position p(visiblePos.deepEquivalent());
1323
1324     return comparePositions(start, p) <= 0 && comparePositions(p, end) <= 0;
1325 }
1326
1327 // Workaround for the fact that it's hard to delete a frame.
1328 // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
1329 // Can't do this implicitly as part of every setSelection call because in some contexts it might not be good
1330 // for the focus to move to another frame. So instead we call it from places where we are selecting with the
1331 // mouse or the keyboard after setting the selection.
1332 void SelectionController::selectFrameElementInParentIfFullySelected()
1333 {
1334     // Find the parent frame; if there is none, then we have nothing to do.
1335     Frame* parent = m_frame->tree()->parent();
1336     if (!parent)
1337         return;
1338     Page* page = m_frame->page();
1339     if (!page)
1340         return;
1341
1342     // Check if the selection contains the entire frame contents; if not, then there is nothing to do.
1343     if (!isRange())
1344         return;
1345     if (!isStartOfDocument(selection().visibleStart()))
1346         return;
1347     if (!isEndOfDocument(selection().visibleEnd()))
1348         return;
1349
1350     // Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
1351     Element* ownerElement = m_frame->ownerElement();
1352     if (!ownerElement)
1353         return;
1354     ContainerNode* ownerElementParent = ownerElement->parentNode();
1355     if (!ownerElementParent)
1356         return;
1357         
1358     // This method's purpose is it to make it easier to select iframes (in order to delete them).  Don't do anything if the iframe isn't deletable.
1359     if (!ownerElementParent->rendererIsEditable())
1360         return;
1361
1362     // Create compute positions before and after the element.
1363     unsigned ownerElementNodeIndex = ownerElement->nodeIndex();
1364     VisiblePosition beforeOwnerElement(VisiblePosition(Position(ownerElementParent, ownerElementNodeIndex, Position::PositionIsOffsetInAnchor)));
1365     VisiblePosition afterOwnerElement(VisiblePosition(Position(ownerElementParent, ownerElementNodeIndex + 1, Position::PositionIsOffsetInAnchor), VP_UPSTREAM_IF_POSSIBLE));
1366
1367     // Focus on the parent frame, and then select from before this element to after.
1368     VisibleSelection newSelection(beforeOwnerElement, afterOwnerElement);
1369     if (parent->selection()->shouldChangeSelection(newSelection)) {
1370         page->focusController()->setFocusedFrame(parent);
1371         parent->selection()->setSelection(newSelection);
1372     }
1373 }
1374
1375 void SelectionController::selectAll()
1376 {
1377     Document* document = m_frame->document();
1378     
1379     if (document->focusedNode() && document->focusedNode()->canSelectAll()) {
1380         document->focusedNode()->selectAll();
1381         return;
1382     }
1383     
1384     Node* root = 0;
1385     if (isContentEditable())
1386         root = highestEditableRoot(m_selection.start());
1387     else {
1388         root = shadowTreeRootNode();
1389         if (!root)
1390             root = document->documentElement();
1391     }
1392     if (!root)
1393         return;
1394     VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode(root));
1395     if (shouldChangeSelection(newSelection))
1396         setSelection(newSelection);
1397     selectFrameElementInParentIfFullySelected();
1398     notifyRendererOfSelectionChange(true);
1399 }
1400
1401 bool SelectionController::setSelectedRange(Range* range, EAffinity affinity, bool closeTyping)
1402 {
1403     if (!range)
1404         return false;
1405
1406     ExceptionCode ec = 0;
1407     Node* startContainer = range->startContainer(ec);
1408     if (ec)
1409         return false;
1410
1411     Node* endContainer = range->endContainer(ec);
1412     if (ec)
1413         return false;
1414     
1415     ASSERT(startContainer);
1416     ASSERT(endContainer);
1417     ASSERT(startContainer->document() == endContainer->document());
1418     
1419     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1420
1421     // Non-collapsed ranges are not allowed to start at the end of a line that is wrapped,
1422     // they start at the beginning of the next line instead
1423     bool collapsed = range->collapsed(ec);
1424     if (ec)
1425         return false;
1426     
1427     int startOffset = range->startOffset(ec);
1428     if (ec)
1429         return false;
1430
1431     int endOffset = range->endOffset(ec);
1432     if (ec)
1433         return false;
1434     
1435     // FIXME: Can we provide extentAffinity?
1436     VisiblePosition visibleStart(Position(startContainer, startOffset, Position::PositionIsOffsetInAnchor), collapsed ? affinity : DOWNSTREAM);
1437     VisiblePosition visibleEnd(Position(endContainer, endOffset, Position::PositionIsOffsetInAnchor), SEL_DEFAULT_AFFINITY);
1438     SetSelectionOptions options = ClearTypingStyle;
1439     if (closeTyping)
1440         options |= CloseTyping;
1441     setSelection(VisibleSelection(visibleStart, visibleEnd), options);
1442     return true;
1443 }
1444
1445 bool SelectionController::isInPasswordField() const
1446 {
1447     ASSERT(start().isNull() || start().anchorType() == Position::PositionIsOffsetInAnchor
1448            || start().containerNode() || !start().anchorNode()->shadowAncestorNode());
1449     Node* startNode = start().containerNode();
1450     if (!startNode)
1451         return false;
1452
1453     startNode = startNode->shadowAncestorNode();
1454     if (!startNode)
1455         return false;
1456
1457     if (!startNode->hasTagName(inputTag))
1458         return false;
1459     
1460     return static_cast<HTMLInputElement*>(startNode)->isPasswordField();
1461 }
1462
1463 bool SelectionController::caretRendersInsideNode(Node* node) const
1464 {
1465     if (!node)
1466         return false;
1467     return !isTableElement(node) && !editingIgnoresContent(node);
1468 }
1469
1470 void SelectionController::focusedOrActiveStateChanged()
1471 {
1472     bool activeAndFocused = isFocusedAndActive();
1473
1474     // Because RenderObject::selectionBackgroundColor() and
1475     // RenderObject::selectionForegroundColor() check if the frame is active,
1476     // we have to update places those colors were painted.
1477     if (RenderView* view = toRenderView(m_frame->document()->renderer()))
1478         view->repaintRectangleInViewAndCompositedLayers(enclosingIntRect(bounds()));
1479
1480     // Caret appears in the active frame.
1481     if (activeAndFocused)
1482         setSelectionFromNone();
1483     setCaretVisible(activeAndFocused);
1484
1485     // Update for caps lock state
1486     m_frame->eventHandler()->capsLockStateMayHaveChanged();
1487
1488     // Because CSSStyleSelector::checkOneSelector() and
1489     // RenderTheme::isFocused() check if the frame is active, we have to
1490     // update style and theme state that depended on those.
1491     if (Node* node = m_frame->document()->focusedNode()) {
1492         node->setNeedsStyleRecalc();
1493         if (RenderObject* renderer = node->renderer())
1494             if (renderer && renderer->style()->hasAppearance())
1495                 renderer->theme()->stateChanged(renderer, FocusState);
1496     }
1497
1498     // Secure keyboard entry is set by the active frame.
1499     if (m_frame->document()->useSecureKeyboardEntryWhenActive())
1500         setUseSecureKeyboardEntry(activeAndFocused);
1501 }
1502
1503 void SelectionController::pageActivationChanged()
1504 {
1505     focusedOrActiveStateChanged();
1506 }
1507
1508 void SelectionController::updateSecureKeyboardEntryIfActive()
1509 {
1510     if (m_frame->document() && isFocusedAndActive())
1511         setUseSecureKeyboardEntry(m_frame->document()->useSecureKeyboardEntryWhenActive());
1512 }
1513
1514 void SelectionController::setUseSecureKeyboardEntry(bool enable)
1515 {
1516     if (enable)
1517         enableSecureTextInput();
1518     else
1519         disableSecureTextInput();
1520 }
1521
1522 void SelectionController::setFocused(bool flag)
1523 {
1524     if (m_focused == flag)
1525         return;
1526     m_focused = flag;
1527
1528     focusedOrActiveStateChanged();
1529 }
1530
1531 bool SelectionController::isFocusedAndActive() const
1532 {
1533     return m_focused && m_frame->page() && m_frame->page()->focusController()->isActive();
1534 }
1535
1536 void SelectionController::updateAppearance()
1537 {
1538     ASSERT(!m_isDragCaretController);
1539
1540 #if ENABLE(TEXT_CARET)
1541     bool caretRectChanged = recomputeCaretRect();
1542
1543     bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
1544     bool shouldBlink = m_caretVisible
1545         && isCaret() && (isContentEditable() || caretBrowsing);
1546
1547     // If the caret moved, stop the blink timer so we can restart with a
1548     // black caret in the new location.
1549     if (caretRectChanged || !shouldBlink)
1550         m_caretBlinkTimer.stop();
1551
1552     // Start blinking with a black caret. Be sure not to restart if we're
1553     // already blinking in the right location.
1554     if (shouldBlink && !m_caretBlinkTimer.isActive()) {
1555         if (double blinkInterval = m_frame->page()->theme()->caretBlinkInterval())
1556             m_caretBlinkTimer.startRepeating(blinkInterval);
1557
1558         if (!m_caretPaint) {
1559             m_caretPaint = true;
1560             invalidateCaretRect();
1561         }
1562     }
1563 #endif
1564
1565     // We need to update style in case the node containing the selection is made display:none.
1566     m_frame->document()->updateStyleIfNeeded();
1567
1568     RenderView* view = m_frame->contentRenderer();
1569     if (!view)
1570         return;
1571
1572     VisibleSelection selection = this->selection();
1573
1574     if (!selection.isRange()) {
1575         view->clearSelection();
1576         return;
1577     }
1578
1579     // Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection.
1580     // Example: foo <a>bar</a>.  Imagine that a line wrap occurs after 'foo', and that 'bar' is selected.   If we pass [foo, 3]
1581     // as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected
1582     // and will fill the gap before 'bar'.
1583     Position startPos = selection.start();
1584     Position candidate = startPos.downstream();
1585     if (candidate.isCandidate())
1586         startPos = candidate;
1587     Position endPos = selection.end();
1588     candidate = endPos.upstream();
1589     if (candidate.isCandidate())
1590         endPos = candidate;
1591
1592     // We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted
1593     // because we don't yet notify the SelectionController of text removal.
1594     if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
1595         RenderObject* startRenderer = startPos.deprecatedNode()->renderer();
1596         RenderObject* endRenderer = endPos.deprecatedNode()->renderer();
1597         view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
1598     }
1599 }
1600
1601 void SelectionController::setCaretVisible(bool flag)
1602 {
1603     if (m_caretVisible == flag)
1604         return;
1605     clearCaretRectIfNeeded();
1606     m_caretVisible = flag;
1607     updateAppearance();
1608 }
1609
1610 void SelectionController::clearCaretRectIfNeeded()
1611 {
1612 #if ENABLE(TEXT_CARET)
1613     if (!m_caretPaint)
1614         return;
1615     m_caretPaint = false;
1616     invalidateCaretRect();
1617 #endif
1618 }
1619
1620 void SelectionController::caretBlinkTimerFired(Timer<SelectionController>*)
1621 {
1622 #if ENABLE(TEXT_CARET)
1623     ASSERT(m_caretVisible);
1624     ASSERT(isCaret());
1625     bool caretPaint = m_caretPaint;
1626     if (isCaretBlinkingSuspended() && caretPaint)
1627         return;
1628     m_caretPaint = !caretPaint;
1629     invalidateCaretRect();
1630 #endif
1631 }
1632
1633 void SelectionController::notifyRendererOfSelectionChange(bool userTriggered)
1634 {
1635     m_frame->document()->updateStyleIfNeeded();
1636
1637     if (!rootEditableElement())
1638         return;
1639
1640     RenderObject* renderer = rootEditableElement()->shadowAncestorNode()->renderer();
1641     if (!renderer || !renderer->isTextControl())
1642         return;
1643
1644     toRenderTextControl(renderer)->selectionChanged(userTriggered);
1645 }
1646
1647 // Helper function that tells whether a particular node is an element that has an entire
1648 // Frame and FrameView, a <frame>, <iframe>, or <object>.
1649 static bool isFrameElement(const Node* n)
1650 {
1651     if (!n)
1652         return false;
1653     RenderObject* renderer = n->renderer();
1654     if (!renderer || !renderer->isWidget())
1655         return false;
1656     Widget* widget = toRenderWidget(renderer)->widget();
1657     return widget && widget->isFrameView();
1658 }
1659
1660 void SelectionController::setFocusedNodeIfNeeded()
1661 {
1662     if (isNone() || !isFocused())
1663         return;
1664
1665     bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
1666     if (caretBrowsing) {
1667         if (Node* anchor = enclosingAnchorElement(base())) {
1668             m_frame->page()->focusController()->setFocusedNode(anchor, m_frame);
1669             return;
1670         }
1671     }
1672
1673     if (Node* target = rootEditableElement()) {
1674         // Walk up the DOM tree to search for a node to focus. 
1675         while (target) {
1676             // We don't want to set focus on a subframe when selecting in a parent frame,
1677             // so add the !isFrameElement check here. There's probably a better way to make this
1678             // work in the long term, but this is the safest fix at this time.
1679             if (target && target->isMouseFocusable() && !isFrameElement(target)) {
1680                 m_frame->page()->focusController()->setFocusedNode(target, m_frame);
1681                 return;
1682             }
1683             target = target->parentOrHostNode(); 
1684         }
1685         m_frame->document()->setFocusedNode(0);
1686     }
1687
1688     if (caretBrowsing)
1689         m_frame->page()->focusController()->setFocusedNode(0, m_frame);
1690 }
1691
1692 void SelectionController::paintDragCaret(GraphicsContext* p, int tx, int ty, const IntRect& clipRect) const
1693 {
1694 #if ENABLE(TEXT_CARET)
1695     SelectionController* dragCaretController = m_frame->page()->dragCaretController();
1696     ASSERT(dragCaretController->selection().isCaret());
1697     if (dragCaretController->selection().start().anchorNode()->document()->frame() == m_frame)
1698         dragCaretController->paintCaret(p, tx, ty, clipRect);
1699 #else
1700     UNUSED_PARAM(p);
1701     UNUSED_PARAM(tx);
1702     UNUSED_PARAM(ty);
1703     UNUSED_PARAM(clipRect);
1704 #endif
1705 }
1706
1707 PassRefPtr<CSSMutableStyleDeclaration> SelectionController::copyTypingStyle() const
1708 {
1709     if (!m_typingStyle || !m_typingStyle->style())
1710         return 0;
1711     return m_typingStyle->style()->copy();
1712 }
1713
1714 bool SelectionController::shouldDeleteSelection(const VisibleSelection& selection) const
1715 {
1716     return m_frame->editor()->client()->shouldDeleteRange(selection.toNormalizedRange().get());
1717 }
1718
1719 FloatRect SelectionController::bounds(bool clipToVisibleContent) const
1720 {
1721     RenderView* root = m_frame->contentRenderer();
1722     FrameView* view = m_frame->view();
1723     if (!root || !view)
1724         return IntRect();
1725
1726     IntRect selectionRect = root->selectionBounds(clipToVisibleContent);
1727     return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
1728 }
1729
1730 void SelectionController::getClippedVisibleTextRectangles(Vector<FloatRect>& rectangles) const
1731 {
1732     RenderView* root = m_frame->contentRenderer();
1733     if (!root)
1734         return;
1735
1736     FloatRect visibleContentRect = m_frame->view()->visibleContentRect();
1737
1738     Vector<FloatQuad> quads;
1739     toNormalizedRange()->textQuads(quads, true);
1740
1741     // FIXME: We are appending empty rectangles to the list for those that fall outside visibleContentRect.
1742     // It might be better to omit those rectangles entirely.
1743     size_t size = quads.size();
1744     for (size_t i = 0; i < size; ++i)
1745         rectangles.append(intersection(quads[i].enclosingBoundingBox(), visibleContentRect));
1746 }
1747
1748 // Scans logically forward from "start", including any child frames.
1749 static HTMLFormElement* scanForForm(Node* start)
1750 {
1751     for (Node* node = start; node; node = node->traverseNextNode()) {
1752         if (node->hasTagName(formTag))
1753             return static_cast<HTMLFormElement*>(node);
1754         if (node->isHTMLElement() && toHTMLElement(node)->isFormControlElement())
1755             return static_cast<HTMLFormControlElement*>(node)->form();
1756         if (node->hasTagName(frameTag) || node->hasTagName(iframeTag)) {
1757             Node* childDocument = static_cast<HTMLFrameElementBase*>(node)->contentDocument();
1758             if (HTMLFormElement* frameResult = scanForForm(childDocument))
1759                 return frameResult;
1760         }
1761     }
1762     return 0;
1763 }
1764
1765 // We look for either the form containing the current focus, or for one immediately after it
1766 HTMLFormElement* SelectionController::currentForm() const
1767 {
1768     // Start looking either at the active (first responder) node, or where the selection is.
1769     Node* start = m_frame->document()->focusedNode();
1770     if (!start)
1771         start = this->start().deprecatedNode();
1772
1773     // Try walking up the node tree to find a form element.
1774     Node* node;
1775     for (node = start; node; node = node->parentNode()) {
1776         if (node->hasTagName(formTag))
1777             return static_cast<HTMLFormElement*>(node);
1778         if (node->isHTMLElement() && toHTMLElement(node)->isFormControlElement())
1779             return static_cast<HTMLFormControlElement*>(node)->form();
1780     }
1781
1782     // Try walking forward in the node tree to find a form element.
1783     return scanForForm(start);
1784 }
1785
1786 void SelectionController::revealSelection(const ScrollAlignment& alignment, bool revealExtent)
1787 {
1788     IntRect rect;
1789
1790     switch (selectionType()) {
1791     case VisibleSelection::NoSelection:
1792         return;
1793     case VisibleSelection::CaretSelection:
1794         rect = absoluteCaretBounds();
1795         break;
1796     case VisibleSelection::RangeSelection:
1797         rect = revealExtent ? VisiblePosition(extent()).absoluteCaretBounds() : enclosingIntRect(bounds(false));
1798         break;
1799     }
1800
1801     Position start = this->start();
1802     ASSERT(start.deprecatedNode());
1803     if (start.deprecatedNode() && start.deprecatedNode()->renderer()) {
1804         // FIXME: This code only handles scrolling the startContainer's layer, but
1805         // the selection rect could intersect more than just that.
1806         // See <rdar://problem/4799899>.
1807         if (RenderLayer* layer = start.deprecatedNode()->renderer()->enclosingLayer()) {
1808             layer->scrollRectToVisible(rect, false, alignment, alignment);
1809             updateAppearance();
1810         }
1811     }
1812 }
1813
1814 void SelectionController::setSelectionFromNone()
1815 {
1816     // Put a caret inside the body if the entire frame is editable (either the
1817     // entire WebView is editable or designMode is on for this document).
1818
1819     Document* document = m_frame->document();
1820     bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
1821     if (!isNone() || !(document->rendererIsEditable() || caretBrowsing))
1822         return;
1823
1824     Node* node = document->documentElement();
1825     while (node && !node->hasTagName(bodyTag))
1826         node = node->traverseNextNode();
1827     if (node)
1828         setSelection(VisibleSelection(firstPositionInOrBeforeNode(node), DOWNSTREAM));
1829 }
1830
1831 bool SelectionController::shouldChangeSelection(const VisibleSelection& newSelection) const
1832 {
1833     return m_frame->editor()->shouldChangeSelection(selection(), newSelection, newSelection.affinity(), false);
1834 }
1835
1836 #ifndef NDEBUG
1837
1838 void SelectionController::formatForDebugger(char* buffer, unsigned length) const
1839 {
1840     m_selection.formatForDebugger(buffer, length);
1841 }
1842
1843 void SelectionController::showTreeForThis() const
1844 {
1845     m_selection.showTreeForThis();
1846 }
1847
1848 #endif
1849
1850 }
1851
1852 #ifndef NDEBUG
1853
1854 void showTree(const WebCore::SelectionController& sel)
1855 {
1856     sel.showTreeForThis();
1857 }
1858
1859 void showTree(const WebCore::SelectionController* sel)
1860 {
1861     if (sel)
1862         sel->showTreeForThis();
1863 }
1864
1865 #endif