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