99b222471a34b77d726876bd10fc53a305c23e52
[WebKit-https.git] / 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 "DeleteSelectionCommand.h"
30 #include "Document.h"
31 #include "Editor.h"
32 #include "Element.h"
33 #include "EventHandler.h"
34 #include "ExceptionCode.h"
35 #include "FloatQuad.h"
36 #include "FocusController.h"
37 #include "Frame.h"
38 #include "FrameTree.h"
39 #include "FrameView.h"
40 #include "GraphicsContext.h"
41 #include "HTMLFrameOwnerElement.h"
42 #include "HTMLInputElement.h"
43 #include "HTMLNames.h"
44 #include "HitTestRequest.h"
45 #include "HitTestResult.h"
46 #include "Page.h"
47 #include "Range.h"
48 #include "RenderLayer.h"
49 #include "RenderTheme.h"
50 #include "RenderView.h"
51 #include "SecureTextInput.h"
52 #include "Settings.h"
53 #include "TextIterator.h"
54 #include "TypingCommand.h"
55 #include "htmlediting.h"
56 #include "visible_units.h"
57 #include <stdio.h>
58 #include <wtf/text/CString.h>
59
60 #define EDIT_DEBUG 0
61
62 namespace WebCore {
63
64 using namespace HTMLNames;
65
66 const int NoXPosForVerticalArrowNavigation = INT_MIN;
67
68 SelectionController::SelectionController(Frame* frame, bool isDragCaretController)
69     : m_frame(frame)
70     , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation)
71     , m_granularity(CharacterGranularity)
72     , m_caretBlinkTimer(this, &SelectionController::caretBlinkTimerFired)
73     , m_caretRectNeedsUpdate(true)
74     , m_absCaretBoundsDirty(true)
75     , m_isDragCaretController(isDragCaretController)
76     , m_isCaretBlinkingSuspended(false)
77     , m_focused(frame && frame->page() && frame->page()->focusController()->focusedFrame() == frame)
78     , m_caretVisible(isDragCaretController)
79     , m_caretPaint(true)
80 {
81     setIsDirectional(false);
82 }
83
84 void SelectionController::moveTo(const VisiblePosition &pos, bool userTriggered, CursorAlignOnScroll align)
85 {
86     setSelection(VisibleSelection(pos.deepEquivalent(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered, align);
87 }
88
89 void SelectionController::moveTo(const VisiblePosition &base, const VisiblePosition &extent, bool userTriggered)
90 {
91     setSelection(VisibleSelection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()), true, true, userTriggered);
92 }
93
94 void SelectionController::moveTo(const Position &pos, EAffinity affinity, bool userTriggered)
95 {
96     setSelection(VisibleSelection(pos, affinity), true, true, userTriggered);
97 }
98
99 void SelectionController::moveTo(const Range *r, EAffinity affinity, bool userTriggered)
100 {
101     VisibleSelection selection = r ? VisibleSelection(r->startPosition(), r->endPosition(), affinity) : VisibleSelection(Position(), Position(), affinity);
102     setSelection(selection, true, true, userTriggered);
103 }
104
105 void SelectionController::moveTo(const Position &base, const Position &extent, EAffinity affinity, bool userTriggered)
106 {
107     setSelection(VisibleSelection(base, extent, affinity), true, true, userTriggered);
108 }
109
110 void SelectionController::setSelection(const VisibleSelection& s, bool closeTyping, bool clearTypingStyle, bool userTriggered, CursorAlignOnScroll align, TextGranularity granularity, DirectionalityPolicy directionalityPolicy)
111 {
112     m_granularity = granularity;
113
114     setIsDirectional(directionalityPolicy == MakeDirectionalSelection);
115
116     if (m_isDragCaretController) {
117         invalidateCaretRect();
118         m_selection = s;
119         m_caretRectNeedsUpdate = true;
120         invalidateCaretRect();
121         updateCaretRect();
122         return;
123     }
124     if (!m_frame) {
125         m_selection = s;
126         return;
127     }
128
129     Node* baseNode = s.base().node();
130     Document* document = 0;
131     if (baseNode)
132         document = baseNode->document();
133     
134     // <http://bugs.webkit.org/show_bug.cgi?id=23464>: Infinite recursion at SelectionController::setSelection
135     // if document->frame() == m_frame we can get into an infinite loop
136     if (document && document->frame() && document->frame() != m_frame && document != m_frame->document()) {
137         document->frame()->selection()->setSelection(s, closeTyping, clearTypingStyle, userTriggered);
138         return;
139     }
140     
141     if (closeTyping)
142         TypingCommand::closeTyping(m_frame->editor()->lastEditCommand());
143
144     if (clearTypingStyle)
145         m_frame->clearTypingStyle();
146         
147     if (m_selection == s)
148         return;
149     
150     VisibleSelection oldSelection = m_selection;
151
152     m_selection = s;
153     
154     m_caretRectNeedsUpdate = true;
155     
156     if (!s.isNone())
157         m_frame->setFocusedNodeIfNeeded();
158     
159     updateAppearance();
160
161     // Always clear the x position used for vertical arrow navigation.
162     // It will be restored by the vertical arrow navigation code if necessary.
163     m_xPosForVerticalArrowNavigation = NoXPosForVerticalArrowNavigation;
164     selectFrameElementInParentIfFullySelected();
165     m_frame->notifyRendererOfSelectionChange(userTriggered);
166     m_frame->editor()->respondToChangedSelection(oldSelection, closeTyping);
167     if (userTriggered) {
168         ScrollAlignment alignment;
169
170         if (m_frame->editor()->behavior().shouldCenterAlignWhenSelectionIsRevealed())
171             alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::alignCenterAlways : ScrollAlignment::alignCenterIfNeeded;
172         else
173             alignment = (align == AlignCursorOnScrollAlways) ? ScrollAlignment::alignTopAlways : ScrollAlignment::alignToEdgeIfNeeded;
174
175         m_frame->revealSelection(alignment, true);
176     }
177
178     notifyAccessibilityForSelectionChange();
179 }
180
181 static bool removingNodeRemovesPosition(Node* node, const Position& position)
182 {
183     if (!position.node())
184         return false;
185         
186     if (position.node() == node)
187         return true;
188     
189     if (!node->isElementNode())
190         return false;
191     
192     Element* element = static_cast<Element*>(node);
193     return element->contains(position.node()) || element->contains(position.node()->shadowAncestorNode());
194 }
195
196 void SelectionController::nodeWillBeRemoved(Node *node)
197 {
198     if (isNone())
199         return;
200         
201     // There can't be a selection inside a fragment, so if a fragment's node is being removed,
202     // the selection in the document that created the fragment needs no adjustment.
203     if (node && highestAncestor(node)->nodeType() == Node::DOCUMENT_FRAGMENT_NODE)
204         return;
205     
206     bool baseRemoved = removingNodeRemovesPosition(node, m_selection.base());
207     bool extentRemoved = removingNodeRemovesPosition(node, m_selection.extent());
208     bool startRemoved = removingNodeRemovesPosition(node, m_selection.start());
209     bool endRemoved = removingNodeRemovesPosition(node, m_selection.end());
210     
211     bool clearRenderTreeSelection = false;
212     bool clearDOMTreeSelection = false;
213
214     if (startRemoved || endRemoved) {
215         // FIXME: When endpoints are removed, we should just alter the selection, instead of blowing it away.
216         clearRenderTreeSelection = true;
217         clearDOMTreeSelection = true;
218     } else if (baseRemoved || extentRemoved) {
219         // The base and/or extent are about to be removed, but the start and end aren't.
220         // Change the base and extent to the start and end, but don't re-validate the
221         // selection, since doing so could move the start and end into the node
222         // that is about to be removed.
223         if (m_selection.isBaseFirst())
224             m_selection.setWithoutValidation(m_selection.start(), m_selection.end());
225         else
226             m_selection.setWithoutValidation(m_selection.end(), m_selection.start());
227     // FIXME: This could be more efficient if we had an isNodeInRange function on Ranges.
228     } else if (comparePositions(m_selection.start(), Position(node, 0)) == -1 && comparePositions(m_selection.end(), Position(node, 0)) == 1) {
229         // If we did nothing here, when this node's renderer was destroyed, the rect that it 
230         // occupied would be invalidated, but, selection gaps that change as a result of 
231         // the removal wouldn't be invalidated.
232         // FIXME: Don't do so much unnecessary invalidation.
233         clearRenderTreeSelection = true;
234     }
235
236     if (clearRenderTreeSelection) {
237         RefPtr<Document> document = m_selection.start().node()->document();
238         document->updateStyleIfNeeded();
239         if (RenderView* view = toRenderView(document->renderer()))
240             view->clearSelection();
241     }
242
243     if (clearDOMTreeSelection)
244         setSelection(VisibleSelection(), false, false);
245 }
246     
247 void SelectionController::setIsDirectional(bool isDirectional)
248 {
249     m_isDirectional = !m_frame || m_frame->editor()->behavior().shouldConsiderSelectionAsDirectional() || isDirectional;
250 }
251
252 void SelectionController::willBeModified(EAlteration alter, EDirection direction)
253 {
254     if (alter != AlterationExtend)
255         return;
256
257     Position start = m_selection.start();
258     Position end = m_selection.end();
259
260     if (m_isDirectional) {
261         // Make base and extent match start and end so we extend the user-visible selection.
262         // This only matters for cases where base and extend point to different positions than
263         // start and end (e.g. after a double-click to select a word).
264         if (m_selection.isBaseFirst()) {
265             m_selection.setBase(start);
266             m_selection.setExtent(end);            
267         } else {
268             m_selection.setBase(end);
269             m_selection.setExtent(start);
270         }
271     } else {
272         // FIXME: This is probably not correct for right and left when the direction is RTL.
273         switch (direction) {
274         case DirectionRight:
275         case DirectionForward:
276             m_selection.setBase(start);
277             m_selection.setExtent(end);
278             break;
279         case DirectionLeft:
280         case DirectionBackward:
281             m_selection.setBase(end);
282             m_selection.setExtent(start);
283             break;
284         }
285     }
286 }
287
288 TextDirection SelectionController::directionOfEnclosingBlock()
289 {
290     Node* n = m_selection.extent().node();
291     Node* enclosingBlockNode = enclosingBlock(n);
292     if (!enclosingBlockNode)
293         return LTR;
294     RenderObject* renderer = enclosingBlockNode->renderer();
295     if (renderer)
296         return renderer->style()->direction();
297     return LTR;
298 }
299
300 VisiblePosition SelectionController::positionForPlatform(bool isGetStart) const
301 {
302     Position pos;
303     Settings* settings = m_frame ? m_frame->settings() : 0;
304     if (settings && settings->editingBehaviorType() == EditingMacBehavior)
305         pos = isGetStart ? m_selection.start() : m_selection.end();
306     else {
307         // Linux and Windows always extend selections from the extent endpoint.
308         // FIXME: VisibleSelection should be fixed to ensure as an invariant that
309         // base/extent always point to the same nodes as start/end, but which points
310         // to which depends on the value of isBaseFirst. Then this can be changed
311         // to just return m_sel.extent().
312         pos = m_selection.isBaseFirst() ? m_selection.end() : m_selection.start();
313     }
314     return VisiblePosition(pos, m_selection.affinity());
315 }
316
317 VisiblePosition SelectionController::startForPlatform() const
318 {
319     return positionForPlatform(true);
320 }
321
322 VisiblePosition SelectionController::endForPlatform() const
323 {
324     return positionForPlatform(false);
325 }
326
327 VisiblePosition SelectionController::modifyExtendingRight(TextGranularity granularity)
328 {
329     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
330
331     // The difference between modifyExtendingRight and modifyExtendingForward is:
332     // modifyExtendingForward always extends forward logically.
333     // modifyExtendingRight behaves the same as modifyExtendingForward except for extending character or word,
334     // it extends forward logically if the enclosing block is LTR direction,
335     // but it extends backward logically if the enclosing block is RTL direction.
336     switch (granularity) {
337     case CharacterGranularity:
338         if (directionOfEnclosingBlock() == LTR)
339             pos = pos.next(true);
340         else
341             pos = pos.previous(true);
342         break;
343     case WordGranularity:
344         if (directionOfEnclosingBlock() == LTR)
345             pos = nextWordPosition(pos);
346         else
347             pos = previousWordPosition(pos);
348         break;
349     case SentenceGranularity:
350     case LineGranularity:
351     case ParagraphGranularity:
352     case SentenceBoundary:
353     case LineBoundary:
354     case ParagraphBoundary:
355     case DocumentBoundary:
356         // FIXME: implement all of the above?
357         pos = modifyExtendingForward(granularity);
358     }
359     return pos;
360 }
361         
362 VisiblePosition SelectionController::modifyExtendingForward(TextGranularity granularity)
363 {
364     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
365     switch (granularity) {
366     case CharacterGranularity:
367         pos = pos.next(true);
368         break;
369     case WordGranularity:
370         pos = nextWordPosition(pos);
371         break;
372     case SentenceGranularity:
373         pos = nextSentencePosition(pos);
374         break;
375     case LineGranularity:
376         pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
377         break;
378     case ParagraphGranularity:
379         pos = nextParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
380         break;
381     case SentenceBoundary:
382         pos = endOfSentence(endForPlatform());
383         break;
384     case LineBoundary:
385         pos = endForPlatform();
386         pos.setAffinity(UPSTREAM);
387         pos = logicalEndOfLine(pos);
388         break;
389     case ParagraphBoundary:
390         pos = endOfParagraph(endForPlatform());
391         break;
392     case DocumentBoundary:
393         pos = endForPlatform();
394         if (isEditablePosition(pos.deepEquivalent()))
395             pos = endOfEditableContent(pos);
396         else
397             pos = endOfDocument(pos);
398         break;
399     }
400     
401     return pos;
402 }
403
404 VisiblePosition SelectionController::modifyMovingRight(TextGranularity granularity)
405 {
406     VisiblePosition pos;
407     switch (granularity) {
408     case CharacterGranularity:
409         if (isRange())
410             pos = VisiblePosition(m_selection.end(), m_selection.affinity());
411         else
412             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).right(true);
413         break;
414     case WordGranularity:
415     case SentenceGranularity:
416     case LineGranularity:
417     case ParagraphGranularity:
418     case SentenceBoundary:
419     case LineBoundary:
420     case ParagraphBoundary:
421     case DocumentBoundary:
422         // FIXME: Implement all of the above.
423         pos = modifyMovingForward(granularity);
424         break;
425     }
426     return pos;
427 }
428
429 VisiblePosition SelectionController::modifyMovingForward(TextGranularity granularity)
430 {
431     VisiblePosition pos;
432     // FIXME: Stay in editable content for the less common granularities.
433     switch (granularity) {
434     case CharacterGranularity:
435         if (isRange())
436             pos = VisiblePosition(m_selection.end(), m_selection.affinity());
437         else
438             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).next(true);
439         break;
440     case WordGranularity:
441         pos = nextWordPosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
442         break;
443     case SentenceGranularity:
444         pos = nextSentencePosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
445         break;
446     case LineGranularity: {
447         // down-arrowing from a range selection that ends at the start of a line needs
448         // to leave the selection at that line start (no need to call nextLinePosition!)
449         pos = endForPlatform();
450         if (!isRange() || !isStartOfLine(pos))
451             pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(START));
452         break;
453     }
454     case ParagraphGranularity:
455         pos = nextParagraphPosition(endForPlatform(), xPosForVerticalArrowNavigation(START));
456         break;
457     case SentenceBoundary:
458         pos = endOfSentence(endForPlatform());
459         break;
460     case LineBoundary:
461         pos = logicalEndOfLine(endForPlatform());
462         break;
463     case ParagraphBoundary:
464         pos = endOfParagraph(endForPlatform());
465         break;
466     case DocumentBoundary:
467         pos = endForPlatform();
468         if (isEditablePosition(pos.deepEquivalent()))
469             pos = endOfEditableContent(pos);
470         else
471             pos = endOfDocument(pos);
472         break;
473     }
474     return pos;
475 }
476
477 VisiblePosition SelectionController::modifyExtendingLeft(TextGranularity granularity)
478 {
479     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
480
481     // The difference between modifyExtendingLeft and modifyExtendingBackward is:
482     // modifyExtendingBackward always extends backward logically.
483     // modifyExtendingLeft behaves the same as modifyExtendingBackward except for extending character or word,
484     // it extends backward logically if the enclosing block is LTR direction,
485     // but it extends forward logically if the enclosing block is RTL direction.
486     switch (granularity) {
487     case CharacterGranularity:
488         if (directionOfEnclosingBlock() == LTR)
489             pos = pos.previous(true);
490         else
491             pos = pos.next(true);
492         break;
493     case WordGranularity:
494         if (directionOfEnclosingBlock() == LTR)
495             pos = previousWordPosition(pos);
496         else
497             pos = nextWordPosition(pos);
498         break;
499     case SentenceGranularity:
500     case LineGranularity:
501     case ParagraphGranularity:
502     case SentenceBoundary:
503     case LineBoundary:
504     case ParagraphBoundary:
505     case DocumentBoundary:
506         pos = modifyExtendingBackward(granularity);
507     }
508     return pos;
509 }
510        
511 VisiblePosition SelectionController::modifyExtendingBackward(TextGranularity granularity)
512 {
513     VisiblePosition pos(m_selection.extent(), m_selection.affinity());
514
515     // Extending a selection backward by word or character from just after a table selects
516     // the table.  This "makes sense" from the user perspective, esp. when deleting.
517     // It was done here instead of in VisiblePosition because we want VPs to iterate
518     // over everything.
519     switch (granularity) {
520     case CharacterGranularity:
521         pos = pos.previous(true);
522         break;
523     case WordGranularity:
524         pos = previousWordPosition(pos);
525         break;
526     case SentenceGranularity:
527         pos = previousSentencePosition(pos);
528         break;
529     case LineGranularity:
530         pos = previousLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
531         break;
532     case ParagraphGranularity:
533         pos = previousParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
534         break;
535     case SentenceBoundary:
536         pos = startOfSentence(startForPlatform());
537         break;
538     case LineBoundary:
539         pos = logicalStartOfLine(startForPlatform());
540         break;
541     case ParagraphBoundary:
542         pos = startOfParagraph(startForPlatform());
543         break;
544     case DocumentBoundary:
545         pos = startForPlatform();
546         if (isEditablePosition(pos.deepEquivalent()))
547             pos = startOfEditableContent(pos);
548         else
549             pos = startOfDocument(pos);
550         break;
551     }
552     return pos;
553 }
554
555 VisiblePosition SelectionController::modifyMovingLeft(TextGranularity granularity)
556 {
557     VisiblePosition pos;
558     switch (granularity) {
559     case CharacterGranularity:
560         if (isRange())
561             pos = VisiblePosition(m_selection.start(), m_selection.affinity());
562         else
563             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).left(true);
564         break;
565     case WordGranularity:
566     case SentenceGranularity:
567     case LineGranularity:
568     case ParagraphGranularity:
569     case SentenceBoundary:
570     case LineBoundary:
571     case ParagraphBoundary:
572     case DocumentBoundary:
573         // FIXME: Implement all of the above.
574         pos = modifyMovingBackward(granularity);
575         break;
576     }
577     return pos;
578 }
579
580 VisiblePosition SelectionController::modifyMovingBackward(TextGranularity granularity)
581 {
582     VisiblePosition pos;
583     switch (granularity) {
584     case CharacterGranularity:
585         if (isRange())
586             pos = VisiblePosition(m_selection.start(), m_selection.affinity());
587         else
588             pos = VisiblePosition(m_selection.extent(), m_selection.affinity()).previous(true);
589         break;
590     case WordGranularity:
591         pos = previousWordPosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
592         break;
593     case SentenceGranularity:
594         pos = previousSentencePosition(VisiblePosition(m_selection.extent(), m_selection.affinity()));
595         break;
596     case LineGranularity:
597         pos = previousLinePosition(startForPlatform(), xPosForVerticalArrowNavigation(START));
598         break;
599     case ParagraphGranularity:
600         pos = previousParagraphPosition(startForPlatform(), xPosForVerticalArrowNavigation(START));
601         break;
602     case SentenceBoundary:
603         pos = startOfSentence(startForPlatform());
604         break;
605     case LineBoundary:
606         pos = logicalStartOfLine(startForPlatform());
607         break;
608     case ParagraphBoundary:
609         pos = startOfParagraph(startForPlatform());
610         break;
611     case DocumentBoundary:
612         pos = startForPlatform();
613         if (isEditablePosition(pos.deepEquivalent()))
614             pos = startOfEditableContent(pos);
615         else
616             pos = startOfDocument(pos);
617         break;
618     }
619     return pos;
620 }
621
622 bool SelectionController::modify(EAlteration alter, EDirection dir, TextGranularity granularity, bool userTriggered)
623 {
624     Settings* settings = m_frame ? m_frame->settings() : 0;
625     return modify(alter, dir, granularity, userTriggered, settings);
626 }
627     
628 static bool isBoundary(TextGranularity granularity)
629 {
630     return granularity == LineBoundary || granularity == ParagraphBoundary || granularity == DocumentBoundary;
631 }    
632     
633 bool SelectionController::modify(EAlteration alter, EDirection direction, TextGranularity granularity, bool userTriggered, Settings* settings)
634 {
635     if (userTriggered) {
636         SelectionController trialSelectionController;
637         trialSelectionController.setSelection(m_selection);
638         trialSelectionController.setIsDirectional(m_isDirectional);
639         trialSelectionController.modify(alter, direction, granularity, false, settings);
640
641         bool change = m_frame->shouldChangeSelection(trialSelectionController.selection());
642         if (!change)
643             return false;
644     }
645
646     willBeModified(alter, direction);
647
648     VisiblePosition position;
649     switch (direction) {
650     case DirectionRight:
651         if (alter == AlterationMove)
652             position = modifyMovingRight(granularity);
653         else
654             position = modifyExtendingRight(granularity);
655         break;
656     case DirectionForward:
657         if (alter == AlterationExtend)
658             position = modifyExtendingForward(granularity);
659         else
660             position = modifyMovingForward(granularity);
661         break;
662     case DirectionLeft:
663         if (alter == AlterationMove)
664             position = modifyMovingLeft(granularity);
665         else
666             position = modifyExtendingLeft(granularity);
667         break;
668     case DirectionBackward:
669         if (alter == AlterationExtend)
670             position = modifyExtendingBackward(granularity);
671         else
672             position = modifyMovingBackward(granularity);
673         break;
674     }
675
676     if (position.isNull())
677         return false;
678
679     // Some of the above operations set an xPosForVerticalArrowNavigation.
680     // Setting a selection will clear it, so save it to possibly restore later.
681     // Note: the START position type is arbitrary because it is unused, it would be
682     // the requested position type if there were no xPosForVerticalArrowNavigation set.
683     int x = xPosForVerticalArrowNavigation(START);
684
685     switch (alter) {
686     case AlterationMove:
687         moveTo(position, userTriggered);
688         break;
689     case AlterationExtend:
690         if (!settings || settings->editingBehaviorType() != EditingMacBehavior || m_selection.isCaret() || !isBoundary(granularity))
691             setExtent(position, userTriggered);
692         else {
693             // Standard Mac behavior when extending to a boundary is grow the selection rather
694             // than leaving the base in place and moving the extent. Matches NSTextView.
695             if (direction == DirectionForward || direction == DirectionRight)
696                 setEnd(position, userTriggered);
697             else
698                 setStart(position, userTriggered);
699         }
700     }
701     
702     if (granularity == LineGranularity || granularity == ParagraphGranularity)
703         m_xPosForVerticalArrowNavigation = x;
704
705     if (userTriggered)
706         m_granularity = CharacterGranularity;
707
708
709     setCaretRectNeedsUpdate();
710
711     setIsDirectional(alter == AlterationExtend);
712
713     return true;
714 }
715
716 // FIXME: Maybe baseline would be better?
717 static bool absoluteCaretY(const VisiblePosition &c, int &y)
718 {
719     IntRect rect = c.absoluteCaretBounds();
720     if (rect.isEmpty())
721         return false;
722     y = rect.y() + rect.height() / 2;
723     return true;
724 }
725
726 bool SelectionController::modify(EAlteration alter, int verticalDistance, bool userTriggered, CursorAlignOnScroll align)
727 {
728     if (!verticalDistance)
729         return false;
730
731     if (userTriggered) {
732         SelectionController trialSelectionController;
733         trialSelectionController.setSelection(m_selection);
734         trialSelectionController.setIsDirectional(m_isDirectional);
735         trialSelectionController.modify(alter, verticalDistance, false);
736
737         bool change = m_frame->shouldChangeSelection(trialSelectionController.selection());
738         if (!change)
739             return false;
740     }
741
742     bool up = verticalDistance < 0;
743     if (up)
744         verticalDistance = -verticalDistance;
745
746     willBeModified(alter, up ? DirectionBackward : DirectionForward);
747
748     VisiblePosition pos;
749     int xPos = 0;
750     switch (alter) {
751     case AlterationMove:
752         pos = VisiblePosition(up ? m_selection.start() : m_selection.end(), m_selection.affinity());
753         xPos = xPosForVerticalArrowNavigation(up ? START : END);
754         m_selection.setAffinity(up ? UPSTREAM : DOWNSTREAM);
755         break;
756     case AlterationExtend:
757         pos = VisiblePosition(m_selection.extent(), m_selection.affinity());
758         xPos = xPosForVerticalArrowNavigation(EXTENT);
759         m_selection.setAffinity(DOWNSTREAM);
760         break;
761     }
762
763     int startY;
764     if (!absoluteCaretY(pos, startY))
765         return false;
766     if (up)
767         startY = -startY;
768     int lastY = startY;
769
770     VisiblePosition result;
771     VisiblePosition next;
772     for (VisiblePosition p = pos; ; p = next) {
773         next = (up ? previousLinePosition : nextLinePosition)(p, xPos);
774         if (next.isNull() || next == p)
775             break;
776         int nextY;
777         if (!absoluteCaretY(next, nextY))
778             break;
779         if (up)
780             nextY = -nextY;
781         if (nextY - startY > verticalDistance)
782             break;
783         if (nextY >= lastY) {
784             lastY = nextY;
785             result = next;
786         }
787     }
788
789     if (result.isNull())
790         return false;
791
792     switch (alter) {
793     case AlterationMove:
794         moveTo(result, userTriggered, align);
795         break;
796     case AlterationExtend:
797         setExtent(result, userTriggered);
798         break;
799     }
800
801     if (userTriggered)
802         m_granularity = CharacterGranularity;
803
804     setIsDirectional(alter == AlterationExtend);
805
806     return true;
807 }
808
809 int SelectionController::xPosForVerticalArrowNavigation(EPositionType type)
810 {
811     int x = 0;
812
813     if (isNone())
814         return x;
815
816     Position pos;
817     switch (type) {
818     case START:
819         pos = m_selection.start();
820         break;
821     case END:
822         pos = m_selection.end();
823         break;
824     case BASE:
825         pos = m_selection.base();
826         break;
827     case EXTENT:
828         pos = m_selection.extent();
829         break;
830     }
831
832     Frame* frame = pos.node()->document()->frame();
833     if (!frame)
834         return x;
835         
836     if (m_xPosForVerticalArrowNavigation == NoXPosForVerticalArrowNavigation) {
837         VisiblePosition visiblePosition(pos, m_selection.affinity());
838         // VisiblePosition creation can fail here if a node containing the selection becomes visibility:hidden
839         // after the selection is created and before this function is called.
840         x = visiblePosition.isNotNull() ? visiblePosition.xOffsetForVerticalNavigation() : 0;
841         m_xPosForVerticalArrowNavigation = x;
842     } else
843         x = m_xPosForVerticalArrowNavigation;
844         
845     return x;
846 }
847
848 void SelectionController::clear()
849 {
850     m_granularity = CharacterGranularity;
851     setSelection(VisibleSelection());
852 }
853
854 void SelectionController::setStart(const VisiblePosition &pos, bool userTriggered)
855 {
856     if (m_selection.isBaseFirst())
857         setBase(pos, userTriggered);
858     else
859         setExtent(pos, userTriggered);
860 }
861
862 void SelectionController::setEnd(const VisiblePosition &pos, bool userTriggered)
863 {
864     if (m_selection.isBaseFirst())
865         setExtent(pos, userTriggered);
866     else
867         setBase(pos, userTriggered);
868 }
869
870 void SelectionController::setBase(const VisiblePosition &pos, bool userTriggered)
871 {
872     setSelection(VisibleSelection(pos.deepEquivalent(), m_selection.extent(), pos.affinity()), true, true, userTriggered);
873 }
874
875 void SelectionController::setExtent(const VisiblePosition &pos, bool userTriggered)
876 {
877     setSelection(VisibleSelection(m_selection.base(), pos.deepEquivalent(), pos.affinity()), true, true, userTriggered);
878 }
879
880 void SelectionController::setBase(const Position &pos, EAffinity affinity, bool userTriggered)
881 {
882     setSelection(VisibleSelection(pos, m_selection.extent(), affinity), true, true, userTriggered);
883 }
884
885 void SelectionController::setExtent(const Position &pos, EAffinity affinity, bool userTriggered)
886 {
887     setSelection(VisibleSelection(m_selection.base(), pos, affinity), true, true, userTriggered);
888 }
889
890 void SelectionController::setCaretRectNeedsUpdate(bool flag)
891 {
892     m_caretRectNeedsUpdate = flag;
893 }
894
895 void SelectionController::updateCaretRect()
896 {
897     if (isNone() || !m_selection.start().node()->inDocument() || !m_selection.end().node()->inDocument()) {
898         m_caretRect = IntRect();
899         return;
900     }
901
902     m_selection.start().node()->document()->updateStyleIfNeeded();
903     
904     m_caretRect = IntRect();
905         
906     if (isCaret()) {
907         VisiblePosition pos(m_selection.start(), m_selection.affinity());
908         if (pos.isNotNull()) {
909             ASSERT(pos.deepEquivalent().node()->renderer());
910             
911             // First compute a rect local to the renderer at the selection start
912             RenderObject* renderer;
913             IntRect localRect = pos.localCaretRect(renderer);
914
915             // Get the renderer that will be responsible for painting the caret (which
916             // is either the renderer we just found, or one of its containers)
917             RenderObject* caretPainter = caretRenderer();
918
919             // Compute an offset between the renderer and the caretPainter
920             bool unrooted = false;
921             while (renderer != caretPainter) {
922                 RenderObject* containerObject = renderer->container();
923                 if (!containerObject) {
924                     unrooted = true;
925                     break;
926                 }
927                 localRect.move(renderer->offsetFromContainer(containerObject, localRect.location()));
928                 renderer = containerObject;
929             }
930             
931             if (!unrooted)
932                 m_caretRect = localRect;
933             
934             m_absCaretBoundsDirty = true;
935         }
936     }
937
938     m_caretRectNeedsUpdate = false;
939 }
940
941 RenderObject* SelectionController::caretRenderer() const
942 {
943     Node* node = m_selection.start().node();
944     if (!node)
945         return 0;
946
947     RenderObject* renderer = node->renderer();
948     if (!renderer)
949         return 0;
950
951     // if caretNode is a block and caret is inside it then caret should be painted by that block
952     bool paintedByBlock = renderer->isBlockFlow() && caretRendersInsideNode(node);
953     return paintedByBlock ? renderer : renderer->containingBlock();
954 }
955
956 IntRect SelectionController::localCaretRect()
957 {
958     if (m_caretRectNeedsUpdate)
959         updateCaretRect();
960     
961     return m_caretRect;
962 }
963
964 IntRect SelectionController::absoluteBoundsForLocalRect(const IntRect& rect) const
965 {
966     RenderObject* caretPainter = caretRenderer();
967     if (!caretPainter)
968         return IntRect();
969         
970     return caretPainter->localToAbsoluteQuad(FloatRect(rect)).enclosingBoundingBox();
971 }
972
973 IntRect SelectionController::absoluteCaretBounds()
974 {
975     recomputeCaretRect();
976     return m_absCaretBounds;
977 }
978
979 static IntRect repaintRectForCaret(IntRect caret)
980 {
981     if (caret.isEmpty())
982         return IntRect();
983     // Ensure that the dirty rect intersects the block that paints the caret even in the case where
984     // the caret itself is just outside the block. See <https://bugs.webkit.org/show_bug.cgi?id=19086>.
985     caret.inflateX(1);
986     return caret;
987 }
988
989 IntRect SelectionController::caretRepaintRect() const
990 {
991     return absoluteBoundsForLocalRect(repaintRectForCaret(localCaretRectForPainting()));
992 }
993
994 bool SelectionController::recomputeCaretRect()
995 {
996     if (!m_caretRectNeedsUpdate)
997         return false;
998
999     if (!m_frame)
1000         return false;
1001         
1002     FrameView* v = m_frame->document()->view();
1003     if (!v)
1004         return false;
1005
1006     IntRect oldRect = m_caretRect;
1007     IntRect newRect = localCaretRect();
1008     if (oldRect == newRect && !m_absCaretBoundsDirty)
1009         return false;
1010
1011     IntRect oldAbsCaretBounds = m_absCaretBounds;
1012     // FIXME: Rename m_caretRect to m_localCaretRect.
1013     m_absCaretBounds = absoluteBoundsForLocalRect(m_caretRect);
1014     m_absCaretBoundsDirty = false;
1015     
1016     if (oldAbsCaretBounds == m_absCaretBounds)
1017         return false;
1018         
1019     IntRect oldAbsoluteCaretRepaintBounds = m_absoluteCaretRepaintBounds;
1020     // We believe that we need to inflate the local rect before transforming it to obtain the repaint bounds.
1021     m_absoluteCaretRepaintBounds = caretRepaintRect();
1022
1023 #if ENABLE(TEXT_CARET)    
1024     if (RenderView* view = toRenderView(m_frame->document()->renderer())) {
1025         // FIXME: make caret repainting container-aware.
1026         view->repaintRectangleInViewAndCompositedLayers(oldAbsoluteCaretRepaintBounds, false);
1027         if (shouldRepaintCaret(view))
1028             view->repaintRectangleInViewAndCompositedLayers(m_absoluteCaretRepaintBounds, false);
1029     }
1030 #endif
1031     return true;
1032 }
1033
1034 bool SelectionController::shouldRepaintCaret(const RenderView* view) const
1035 {
1036     ASSERT(view);
1037     Frame* frame = view->frameView() ? view->frameView()->frame() : 0; // The frame where the selection started.
1038     bool caretBrowsing = frame && frame->settings() && frame->settings()->caretBrowsingEnabled();
1039     return (caretBrowsing || isContentEditable());
1040 }
1041
1042 void SelectionController::invalidateCaretRect()
1043 {
1044     if (!isCaret())
1045         return;
1046
1047     Document* d = m_selection.start().node()->document();
1048
1049     // recomputeCaretRect will always return false for the drag caret,
1050     // because its m_frame is always 0.
1051     bool caretRectChanged = recomputeCaretRect();
1052
1053     // EDIT FIXME: This is an unfortunate hack.
1054     // Basically, we can't trust this layout position since we 
1055     // can't guarantee that the check to see if we are in unrendered 
1056     // content will work at this point. We may have to wait for
1057     // a layout and re-render of the document to happen. So, resetting this
1058     // flag will cause another caret layout to happen the first time
1059     // that we try to paint the caret after this call. That one will work since
1060     // it happens after the document has accounted for any editing
1061     // changes which may have been done.
1062     // And, we need to leave this layout here so the caret moves right 
1063     // away after clicking.
1064     m_caretRectNeedsUpdate = true;
1065
1066     if (!caretRectChanged) {
1067         RenderView* view = toRenderView(d->renderer());
1068         if (view && shouldRepaintCaret(view))
1069             view->repaintRectangleInViewAndCompositedLayers(caretRepaintRect(), false);
1070     }
1071 }
1072
1073 void SelectionController::paintCaret(GraphicsContext* context, int tx, int ty, const IntRect& clipRect)
1074 {
1075 #if ENABLE(TEXT_CARET)
1076     if (!m_caretVisible)
1077         return;
1078     if (!m_caretPaint)
1079         return;
1080     if (!m_selection.isCaret())
1081         return;
1082
1083     IntRect drawingRect = localCaretRectForPainting();
1084     drawingRect.move(tx, ty);
1085     IntRect caret = intersection(drawingRect, clipRect);
1086     if (caret.isEmpty())
1087         return;
1088
1089     Color caretColor = Color::black;
1090     ColorSpace colorSpace = DeviceColorSpace;
1091     Element* element = rootEditableElement();
1092     if (element && element->renderer()) {
1093         caretColor = element->renderer()->style()->visitedDependentColor(CSSPropertyColor);
1094         colorSpace = element->renderer()->style()->colorSpace();
1095     }
1096
1097     context->fillRect(caret, caretColor, colorSpace);
1098 #else
1099     UNUSED_PARAM(context);
1100     UNUSED_PARAM(tx);
1101     UNUSED_PARAM(ty);
1102     UNUSED_PARAM(clipRect);
1103 #endif
1104 }
1105
1106 void SelectionController::debugRenderer(RenderObject *r, bool selected) const
1107 {
1108     if (r->node()->isElementNode()) {
1109         Element* element = static_cast<Element *>(r->node());
1110         fprintf(stderr, "%s%s\n", selected ? "==> " : "    ", element->localName().string().utf8().data());
1111     } else if (r->isText()) {
1112         RenderText* textRenderer = toRenderText(r);
1113         if (!textRenderer->textLength() || !textRenderer->firstTextBox()) {
1114             fprintf(stderr, "%s#text (empty)\n", selected ? "==> " : "    ");
1115             return;
1116         }
1117         
1118         static const int max = 36;
1119         String text = textRenderer->text();
1120         int textLength = text.length();
1121         if (selected) {
1122             int offset = 0;
1123             if (r->node() == m_selection.start().node())
1124                 offset = m_selection.start().deprecatedEditingOffset();
1125             else if (r->node() == m_selection.end().node())
1126                 offset = m_selection.end().deprecatedEditingOffset();
1127                 
1128             int pos;
1129             InlineTextBox* box = textRenderer->findNextInlineTextBox(offset, pos);
1130             text = text.substring(box->start(), box->len());
1131             
1132             String show;
1133             int mid = max / 2;
1134             int caret = 0;
1135             
1136             // text is shorter than max
1137             if (textLength < max) {
1138                 show = text;
1139                 caret = pos;
1140             } else if (pos - mid < 0) {
1141                 // too few characters to left
1142                 show = text.left(max - 3) + "...";
1143                 caret = pos;
1144             } else if (pos - mid >= 0 && pos + mid <= textLength) {
1145                 // enough characters on each side
1146                 show = "..." + text.substring(pos - mid + 3, max - 6) + "...";
1147                 caret = mid;
1148             } else {
1149                 // too few characters on right
1150                 show = "..." + text.right(max - 3);
1151                 caret = pos - (textLength - show.length());
1152             }
1153             
1154             show.replace('\n', ' ');
1155             show.replace('\r', ' ');
1156             fprintf(stderr, "==> #text : \"%s\" at offset %d\n", show.utf8().data(), pos);
1157             fprintf(stderr, "           ");
1158             for (int i = 0; i < caret; i++)
1159                 fprintf(stderr, " ");
1160             fprintf(stderr, "^\n");
1161         } else {
1162             if ((int)text.length() > max)
1163                 text = text.left(max - 3) + "...";
1164             else
1165                 text = text.left(max);
1166             fprintf(stderr, "    #text : \"%s\"\n", text.utf8().data());
1167         }
1168     }
1169 }
1170
1171 bool SelectionController::contains(const IntPoint& point)
1172 {
1173     Document* document = m_frame->document();
1174     
1175     // Treat a collapsed selection like no selection.
1176     if (!isRange())
1177         return false;
1178     if (!document->renderer()) 
1179         return false;
1180     
1181     HitTestRequest request(HitTestRequest::ReadOnly |
1182                            HitTestRequest::Active);
1183     HitTestResult result(point);
1184     document->renderView()->layer()->hitTest(request, result);
1185     Node* innerNode = result.innerNode();
1186     if (!innerNode || !innerNode->renderer())
1187         return false;
1188     
1189     VisiblePosition visiblePos(innerNode->renderer()->positionForPoint(result.localPoint()));
1190     if (visiblePos.isNull())
1191         return false;
1192         
1193     if (m_selection.visibleStart().isNull() || m_selection.visibleEnd().isNull())
1194         return false;
1195         
1196     Position start(m_selection.visibleStart().deepEquivalent());
1197     Position end(m_selection.visibleEnd().deepEquivalent());
1198     Position p(visiblePos.deepEquivalent());
1199
1200     return comparePositions(start, p) <= 0 && comparePositions(p, end) <= 0;
1201 }
1202
1203 // Workaround for the fact that it's hard to delete a frame.
1204 // Call this after doing user-triggered selections to make it easy to delete the frame you entirely selected.
1205 // Can't do this implicitly as part of every setSelection call because in some contexts it might not be good
1206 // for the focus to move to another frame. So instead we call it from places where we are selecting with the
1207 // mouse or the keyboard after setting the selection.
1208 void SelectionController::selectFrameElementInParentIfFullySelected()
1209 {
1210     // Find the parent frame; if there is none, then we have nothing to do.
1211     Frame* parent = m_frame->tree()->parent();
1212     if (!parent)
1213         return;
1214     Page* page = m_frame->page();
1215     if (!page)
1216         return;
1217
1218     // Check if the selection contains the entire frame contents; if not, then there is nothing to do.
1219     if (!isRange())
1220         return;
1221     if (!isStartOfDocument(selection().visibleStart()))
1222         return;
1223     if (!isEndOfDocument(selection().visibleEnd()))
1224         return;
1225
1226     // Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
1227     Document* doc = m_frame->document();
1228     Element* ownerElement = doc->ownerElement();
1229     if (!ownerElement)
1230         return;
1231     Node* ownerElementParent = ownerElement->parentNode();
1232     if (!ownerElementParent)
1233         return;
1234         
1235     // 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.
1236     if (!ownerElementParent->isContentEditable())
1237         return;
1238
1239     // Create compute positions before and after the element.
1240     unsigned ownerElementNodeIndex = ownerElement->nodeIndex();
1241     VisiblePosition beforeOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex, SEL_DEFAULT_AFFINITY));
1242     VisiblePosition afterOwnerElement(VisiblePosition(ownerElementParent, ownerElementNodeIndex + 1, VP_UPSTREAM_IF_POSSIBLE));
1243
1244     // Focus on the parent frame, and then select from before this element to after.
1245     VisibleSelection newSelection(beforeOwnerElement, afterOwnerElement);
1246     if (parent->shouldChangeSelection(newSelection)) {
1247         page->focusController()->setFocusedFrame(parent);
1248         parent->selection()->setSelection(newSelection);
1249     }
1250 }
1251
1252 void SelectionController::selectAll()
1253 {
1254     Document* document = m_frame->document();
1255     
1256     if (document->focusedNode() && document->focusedNode()->canSelectAll()) {
1257         document->focusedNode()->selectAll();
1258         return;
1259     }
1260     
1261     Node* root = 0;
1262     if (isContentEditable())
1263         root = highestEditableRoot(m_selection.start());
1264     else {
1265         root = shadowTreeRootNode();
1266         if (!root)
1267             root = document->documentElement();
1268     }
1269     if (!root)
1270         return;
1271     VisibleSelection newSelection(VisibleSelection::selectionFromContentsOfNode(root));
1272     if (m_frame->shouldChangeSelection(newSelection))
1273         setSelection(newSelection);
1274     selectFrameElementInParentIfFullySelected();
1275     m_frame->notifyRendererOfSelectionChange(true);
1276 }
1277
1278 bool SelectionController::setSelectedRange(Range* range, EAffinity affinity, bool closeTyping)
1279 {
1280     if (!range)
1281         return false;
1282
1283     ExceptionCode ec = 0;
1284     Node* startContainer = range->startContainer(ec);
1285     if (ec)
1286         return false;
1287
1288     Node* endContainer = range->endContainer(ec);
1289     if (ec)
1290         return false;
1291     
1292     ASSERT(startContainer);
1293     ASSERT(endContainer);
1294     ASSERT(startContainer->document() == endContainer->document());
1295     
1296     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1297
1298     // Non-collapsed ranges are not allowed to start at the end of a line that is wrapped,
1299     // they start at the beginning of the next line instead
1300     bool collapsed = range->collapsed(ec);
1301     if (ec)
1302         return false;
1303     
1304     int startOffset = range->startOffset(ec);
1305     if (ec)
1306         return false;
1307
1308     int endOffset = range->endOffset(ec);
1309     if (ec)
1310         return false;
1311     
1312     // FIXME: Can we provide extentAffinity?
1313     VisiblePosition visibleStart(startContainer, startOffset, collapsed ? affinity : DOWNSTREAM);
1314     VisiblePosition visibleEnd(endContainer, endOffset, SEL_DEFAULT_AFFINITY);
1315     setSelection(VisibleSelection(visibleStart, visibleEnd), closeTyping);
1316     return true;
1317 }
1318
1319 bool SelectionController::isInPasswordField() const
1320 {
1321     Node* startNode = start().node();
1322     if (!startNode)
1323         return false;
1324
1325     startNode = startNode->shadowAncestorNode();
1326     if (!startNode)
1327         return false;
1328
1329     if (!startNode->hasTagName(inputTag))
1330         return false;
1331     
1332     return static_cast<HTMLInputElement*>(startNode)->inputType() == HTMLInputElement::PASSWORD;
1333 }
1334
1335 bool SelectionController::caretRendersInsideNode(Node* node) const
1336 {
1337     if (!node)
1338         return false;
1339     return !isTableElement(node) && !editingIgnoresContent(node);
1340 }
1341
1342 void SelectionController::focusedOrActiveStateChanged()
1343 {
1344     bool activeAndFocused = isFocusedAndActive();
1345
1346     // Because RenderObject::selectionBackgroundColor() and
1347     // RenderObject::selectionForegroundColor() check if the frame is active,
1348     // we have to update places those colors were painted.
1349     if (RenderView* view = toRenderView(m_frame->document()->renderer()))
1350         view->repaintRectangleInViewAndCompositedLayers(enclosingIntRect(m_frame->selectionBounds()));
1351
1352     // Caret appears in the active frame.
1353     if (activeAndFocused)
1354         m_frame->setSelectionFromNone();
1355     setCaretVisible(activeAndFocused);
1356
1357     // Update for caps lock state
1358     m_frame->eventHandler()->capsLockStateMayHaveChanged();
1359
1360     // Because CSSStyleSelector::checkOneSelector() and
1361     // RenderTheme::isFocused() check if the frame is active, we have to
1362     // update style and theme state that depended on those.
1363     if (Node* node = m_frame->document()->focusedNode()) {
1364         node->setNeedsStyleRecalc();
1365         if (RenderObject* renderer = node->renderer())
1366             if (renderer && renderer->style()->hasAppearance())
1367                 renderer->theme()->stateChanged(renderer, FocusState);
1368     }
1369
1370     // Secure keyboard entry is set by the active frame.
1371     if (m_frame->document()->useSecureKeyboardEntryWhenActive())
1372         setUseSecureKeyboardEntry(activeAndFocused);
1373 }
1374
1375 void SelectionController::pageActivationChanged()
1376 {
1377     focusedOrActiveStateChanged();
1378 }
1379
1380 void SelectionController::updateSecureKeyboardEntryIfActive()
1381 {
1382     if (m_frame->document() && isFocusedAndActive())
1383         setUseSecureKeyboardEntry(m_frame->document()->useSecureKeyboardEntryWhenActive());
1384 }
1385
1386 void SelectionController::setUseSecureKeyboardEntry(bool enable)
1387 {
1388     if (enable)
1389         enableSecureTextInput();
1390     else
1391         disableSecureTextInput();
1392 }
1393
1394 void SelectionController::setFocused(bool flag)
1395 {
1396     if (m_focused == flag)
1397         return;
1398     m_focused = flag;
1399
1400     focusedOrActiveStateChanged();
1401 }
1402
1403 bool SelectionController::isFocusedAndActive() const
1404 {
1405     return m_focused && m_frame->page() && m_frame->page()->focusController()->isActive();
1406 }
1407
1408 void SelectionController::updateAppearance()
1409 {
1410     ASSERT(!m_isDragCaretController);
1411
1412 #if ENABLE(TEXT_CARET)
1413     bool caretRectChanged = recomputeCaretRect();
1414
1415     bool caretBrowsing = m_frame->settings() && m_frame->settings()->caretBrowsingEnabled();
1416     bool shouldBlink = m_caretVisible
1417         && isCaret() && (isContentEditable() || caretBrowsing);
1418
1419     // If the caret moved, stop the blink timer so we can restart with a
1420     // black caret in the new location.
1421     if (caretRectChanged || !shouldBlink)
1422         m_caretBlinkTimer.stop();
1423
1424     // Start blinking with a black caret. Be sure not to restart if we're
1425     // already blinking in the right location.
1426     if (shouldBlink && !m_caretBlinkTimer.isActive()) {
1427         if (double blinkInterval = m_frame->page()->theme()->caretBlinkInterval())
1428             m_caretBlinkTimer.startRepeating(blinkInterval);
1429
1430         if (!m_caretPaint) {
1431             m_caretPaint = true;
1432             invalidateCaretRect();
1433         }
1434     }
1435 #endif
1436
1437     // We need to update style in case the node containing the selection is made display:none.
1438     m_frame->document()->updateStyleIfNeeded();
1439
1440     RenderView* view = m_frame->contentRenderer();
1441     if (!view)
1442         return;
1443
1444     VisibleSelection selection = this->selection();
1445
1446     if (!selection.isRange()) {
1447         view->clearSelection();
1448         return;
1449     }
1450
1451     // Use the rightmost candidate for the start of the selection, and the leftmost candidate for the end of the selection.
1452     // Example: foo <a>bar</a>.  Imagine that a line wrap occurs after 'foo', and that 'bar' is selected.   If we pass [foo, 3]
1453     // as the start of the selection, the selection painting code will think that content on the line containing 'foo' is selected
1454     // and will fill the gap before 'bar'.
1455     Position startPos = selection.start();
1456     Position candidate = startPos.downstream();
1457     if (candidate.isCandidate())
1458         startPos = candidate;
1459     Position endPos = selection.end();
1460     candidate = endPos.upstream();
1461     if (candidate.isCandidate())
1462         endPos = candidate;
1463
1464     // We can get into a state where the selection endpoints map to the same VisiblePosition when a selection is deleted
1465     // because we don't yet notify the SelectionController of text removal.
1466     if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
1467         RenderObject* startRenderer = startPos.node()->renderer();
1468         RenderObject* endRenderer = endPos.node()->renderer();
1469         view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
1470     }
1471 }
1472
1473 void SelectionController::setCaretVisible(bool flag)
1474 {
1475     if (m_caretVisible == flag)
1476         return;
1477     clearCaretRectIfNeeded();
1478     m_caretVisible = flag;
1479     updateAppearance();
1480 }
1481
1482 void SelectionController::clearCaretRectIfNeeded()
1483 {
1484 #if ENABLE(TEXT_CARET)
1485     if (!m_caretPaint)
1486         return;
1487     m_caretPaint = false;
1488     invalidateCaretRect();
1489 #endif
1490 }
1491
1492 void SelectionController::caretBlinkTimerFired(Timer<SelectionController>*)
1493 {
1494 #if ENABLE(TEXT_CARET)
1495     ASSERT(m_caretVisible);
1496     ASSERT(isCaret());
1497     bool caretPaint = m_caretPaint;
1498     if (isCaretBlinkingSuspended() && caretPaint)
1499         return;
1500     m_caretPaint = !caretPaint;
1501     invalidateCaretRect();
1502 #endif
1503 }
1504
1505 #ifndef NDEBUG
1506
1507 void SelectionController::formatForDebugger(char* buffer, unsigned length) const
1508 {
1509     m_selection.formatForDebugger(buffer, length);
1510 }
1511
1512 void SelectionController::showTreeForThis() const
1513 {
1514     m_selection.showTreeForThis();
1515 }
1516
1517 #endif
1518
1519 }
1520
1521 #ifndef NDEBUG
1522
1523 void showTree(const WebCore::SelectionController& sel)
1524 {
1525     sel.showTreeForThis();
1526 }
1527
1528 void showTree(const WebCore::SelectionController* sel)
1529 {
1530     if (sel)
1531         sel->showTreeForThis();
1532 }
1533
1534 #endif