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