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