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