LayoutTests:
[WebKit-https.git] / WebCore / editing / SelectionController.cpp
index d96e271..e59f017 100644 (file)
 #include "config.h"
 #include "SelectionController.h"
 
-#include "DocumentImpl.h"
+#include "Document.h"
+#include "Element.h"
+#include "EventNames.h"
 #include "Frame.h"
-#include "FrameView.h"
-#include "InlineTextBox.h"
-#include "IntRect.h"
-#include "dom_node.h"
-#include "PlatformString.h"
+#include "GraphicsContext.h"
+#include "RenderView.h"
+#include "TextIterator.h"
+#include "TypingCommand.h"
 #include "htmlediting.h"
-#include "render_canvas.h"
-#include "render_object.h"
-#include "render_style.h"
-#include "VisiblePosition.h"
-#include "visible_text.h"
 #include "visible_units.h"
-#include "dom2_rangeimpl.h"
-#include "dom2_eventsimpl.h"
-#include "dom_elementimpl.h"
-#include "EventNames.h"
-#include <kxmlcore/Assertions.h>
-#include <qevent.h>
-#include <qpainter.h>
 
 #define EDIT_DEBUG 0
 
@@ -54,192 +43,112 @@ namespace WebCore {
 
 using namespace EventNames;
 
-void MutationListener::handleEvent(EventImpl *event, bool isWindowEvent)
-{
-    if (!m_selectionController)
-        return;
-    
-    if (event->type() == DOMNodeRemovedEvent)
-        m_selectionController->nodeWillBeRemoved(event->target());
-}
-
-SelectionController::SelectionController()
-    : m_needsLayout(true)
-    , m_mutationListener(new MutationListener(this))
-{
-    setSelection(Selection());
-}
-
-SelectionController::SelectionController(const Selection &sel)
-    : m_needsLayout(true)
-    , m_modifyBiasSet(false)
-    , m_mutationListener(new MutationListener(this))
-{
-    setSelection(sel);
-}
-
-SelectionController::SelectionController(const Position &pos, EAffinity affinity)
+SelectionController::SelectionController(Frame* frame, bool isDragCaretController)
     : m_needsLayout(true)
-    , m_modifyBiasSet(false)
-    , m_mutationListener(new MutationListener(this))
+    , m_frame(frame)
+    , m_isDragCaretController(isDragCaretController)
 {
-    setSelection(Selection(pos, pos, affinity));
-}
-
-SelectionController::SelectionController(const RangeImpl *r, EAffinity affinity)
-    : m_needsLayout(true)
-    , m_modifyBiasSet(false)
-    , m_mutationListener(new MutationListener(this))
-{
-    setSelection(Selection(startPosition(r), endPosition(r), affinity));
-}
-
-SelectionController::SelectionController(const Position &base, const Position &extent, EAffinity affinity)
-    : m_needsLayout(true)
-    , m_modifyBiasSet(false)
-    , m_mutationListener(new MutationListener(this))
-{
-    setSelection(Selection(base, extent, affinity));
-}
-
-SelectionController::SelectionController(const VisiblePosition &visiblePos)
-    : m_needsLayout(true)
-    , m_modifyBiasSet(false)
-    , m_mutationListener(new MutationListener(this))
-{
-    setSelection(Selection(visiblePos.deepEquivalent(), visiblePos.deepEquivalent(), visiblePos.affinity()));
-}
-
-SelectionController::SelectionController(const VisiblePosition &base, const VisiblePosition &extent)
-    : m_needsLayout(true)
-    , m_modifyBiasSet(false)
-    , m_mutationListener(new MutationListener(this))
-{
-    setSelection(Selection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()));
-}
-
-SelectionController::SelectionController(const SelectionController &o)
-    : m_needsLayout(o.m_needsLayout)
-    , m_modifyBiasSet(o.m_modifyBiasSet)
-    , m_mutationListener(new MutationListener(this))
-{
-    setSelection(o.m_sel); 
-    // Only copy the coordinates over if the other object
-    // has had a layout, otherwise keep the current
-    // coordinates. This prevents drawing artifacts from
-    // remaining when the caret is painted and then moves,
-    // and the old rectangle needs to be repainted.
-    if (!m_needsLayout) {
-        m_caretRect = o.m_caretRect;
-        m_caretPositionOnLayout = o.m_caretPositionOnLayout;
-    }
-}
-
-SelectionController::~SelectionController()
-{
-    if (!isNone()) {
-        DocumentImpl *document = m_sel.start().node()->getDocument();
-        document->removeEventListener(DOMNodeRemovedEvent, m_mutationListener.get(), false);
-    }
-}
-
-SelectionController &SelectionController::operator=(const SelectionController &o)
-{
-    setSelection(o.m_sel);
-
-    m_needsLayout = o.m_needsLayout;
-    m_modifyBiasSet = o.m_modifyBiasSet;
-    
-    // Only copy the coordinates over if the other object
-    // has had a layout, otherwise keep the current
-    // coordinates. This prevents drawing artifacts from
-    // remaining when the caret is painted and then moves,
-    // and the old rectangle needs to be repainted.
-    if (!m_needsLayout) {
-        m_caretRect = o.m_caretRect;
-        m_caretPositionOnLayout = o.m_caretPositionOnLayout;
-    }
-    
-    return *this;
 }
 
 void SelectionController::moveTo(const VisiblePosition &pos)
 {
     setSelection(Selection(pos.deepEquivalent(), pos.deepEquivalent(), pos.affinity()));
-    m_needsLayout = true;
 }
 
 void SelectionController::moveTo(const VisiblePosition &base, const VisiblePosition &extent)
 {
     setSelection(Selection(base.deepEquivalent(), extent.deepEquivalent(), base.affinity()));
-    m_needsLayout = true;
 }
 
 void SelectionController::moveTo(const SelectionController &o)
 {
     setSelection(o.m_sel);
-    m_needsLayout = true;
 }
 
 void SelectionController::moveTo(const Position &pos, EAffinity affinity)
 {
     setSelection(Selection(pos, affinity));
-    m_needsLayout = true;
 }
 
-void SelectionController::moveTo(const RangeImpl *r, EAffinity affinity)
+void SelectionController::moveTo(const Range *r, EAffinity affinity)
 {
     setSelection(Selection(startPosition(r), endPosition(r), affinity));
-    m_needsLayout = true;
 }
 
 void SelectionController::moveTo(const Position &base, const Position &extent, EAffinity affinity)
 {
     setSelection(Selection(base, extent, affinity));
-    m_needsLayout = true;
 }
 
-void SelectionController::setSelection(const Selection &newSelection)
+void SelectionController::setSelection(const Selection& s, bool closeTyping, bool clearTypingStyle)
 {
+    if (m_isDragCaretController) {
+        needsCaretRepaint();
+        m_sel = s;
+        m_needsLayout = true;
+        needsCaretRepaint();
+        return;
+    }
+    if (!m_frame) {
+        m_sel = s;
+        return;
+    }
+    
+    ASSERT(!s.base().node() || s.base().node()->document() == m_frame->document());
+    ASSERT(!s.extent().node() || s.extent().node()->document() == m_frame->document());
+    ASSERT(!s.start().node() || s.start().node()->document() == m_frame->document());
+    ASSERT(!s.end().node() || s.end().node()->document() == m_frame->document());
+    
+    if (closeTyping)
+        TypingCommand::closeTyping(m_frame->lastEditCommand());
+
+    if (clearTypingStyle)
+        m_frame->clearTypingStyle();
+        
+    if (m_sel == s)
+        return;
+    
+    m_frame->clearCaretRectIfNeeded();
+
     Selection oldSelection = m_sel;
-    DocumentImpl *oldDocument = oldSelection.start().node() ? oldSelection.start().node()->getDocument() : 0;
-    DocumentImpl *newDocument = newSelection.start().node() ? newSelection.start().node()->getDocument() : 0;
+
+    m_sel = s;
     
-    if (oldDocument != newDocument) {
-        if (oldDocument)
-            oldDocument->removeEventListener(DOMNodeRemovedEvent, m_mutationListener.get(), false);
-        if (newDocument)
-            newDocument->addEventListener(DOMNodeRemovedEvent, m_mutationListener.get(), false);
-    }
+    m_needsLayout = true;
     
-    m_sel = newSelection;
+    if (!s.isNone())
+        m_frame->setFocusNodeIfNeeded();
+    
+    m_frame->selectionLayoutChanged();
+    // Always clear the x position used for vertical arrow navigation.
+    // It will be restored by the vertical arrow navigation code if necessary.
+    m_frame->setXPosForVerticalArrowNavigation(Frame::NoXPosForVerticalArrowNavigation);
+    m_frame->notifyRendererOfSelectionChange(false);
+    m_frame->respondToChangedSelection(oldSelection, closeTyping);
 }
 
-void SelectionController::nodeWillBeRemoved(NodeImpl *node)
+void SelectionController::nodeWillBeRemoved(Node *node)
 {
     if (isNone())
         return;
     
-    NodeImpl *base = m_sel.base().node();
-    NodeImpl *extent = m_sel.extent().node();
-    NodeImpl *start = m_sel.start().node();
-    NodeImpl *end = m_sel.end().node();
+    Nodebase = m_sel.base().node();
+    Nodeextent = m_sel.extent().node();
+    Nodestart = m_sel.start().node();
+    Nodeend = m_sel.end().node();
     
-    bool baseRemoved = node == base || base->isAncestor(node);
-    bool extentRemoved = node == extent || extent->isAncestor(node);
-    bool startRemoved = node == start || start->isAncestor(node);
-    bool endRemoved = node == end || end->isAncestor(node);
+    bool baseRemoved = node == base || (base && base->isAncestor(node));
+    bool extentRemoved = node == extent || (extent && extent->isAncestor(node));
+    bool startRemoved = node == start || (start && start->isAncestor(node));
+    bool endRemoved = node == end || (end && end->isAncestor(node));
     
+    bool clearRenderTreeSelection = false;
+    bool clearDOMTreeSelection = false;
+
     if (startRemoved || endRemoved) {
-    
-        // FIXME (6498): This doesn't notify the editing delegate of a selection change.
         // FIXME: When endpoints are removed, we should just alter the selection, instead of blowing it away.
-        // FIXME: The SelectionController should be responsible for scheduling a repaint, 
-        // but it can't do a proper job of it until it handles the other types of DOM mutations.
-        // For now, we'll continue to let RenderObjects handle it when they are destroyed.
-        
-        setSelection(Selection());
-        
+        clearRenderTreeSelection = true;
+        clearDOMTreeSelection = true;
     } else if (baseRemoved || extentRemoved) {
         if (m_sel.isBaseFirst()) {
             m_sel.setBase(m_sel.start());
@@ -248,7 +157,26 @@ void SelectionController::nodeWillBeRemoved(NodeImpl *node)
             m_sel.setBase(m_sel.start());
             m_sel.setExtent(m_sel.end());
         }
+    // FIXME: This could be more efficient if we had an isNodeInRange function on Ranges.
+    } else if (Range::compareBoundaryPoints(m_sel.start(), Position(node, 0)) == -1 &&
+               Range::compareBoundaryPoints(m_sel.end(), Position(node, 0)) == 1) {
+        // If we did nothing here, when this node's renderer was destroyed, the rect that it 
+        // occupied would be invalidated, but, selection gaps that change as a result of 
+        // the removal wouldn't be invalidated.
+        // FIXME: Don't do so much unnecessary invalidation.
+        clearRenderTreeSelection = true;
+    }
+
+    if (clearRenderTreeSelection) {
+        RefPtr<Document> document = start->document();
+        document->updateRendering();
+        if (RenderView* view = static_cast<RenderView*>(document->renderer()))
+            view->clearSelection();
     }
+
+    if (clearDOMTreeSelection)
+        // FIXME (6498): This doesn't notify the editing delegate of a selection change.
+        setSelection(Selection(), false, false);
 }
 
 void SelectionController::setModifyBias(EAlter alter, EDirection direction)
@@ -278,59 +206,70 @@ void SelectionController::setModifyBias(EAlter alter, EDirection direction)
     }
 }
 
-VisiblePosition SelectionController::modifyExtendingRightForward(ETextGranularity granularity)
+VisiblePosition SelectionController::modifyExtendingRightForward(TextGranularity granularity)
 {
     VisiblePosition pos(m_sel.extent(), m_sel.affinity());
     switch (granularity) {
-        case CHARACTER:
+        case CharacterGranularity:
             if (isLastVisiblePositionBeforeTableElement(pos.deepEquivalent()))
                 pos = VisiblePosition(positionAfterFollowingTableElement(pos.deepEquivalent()), VP_DEFAULT_AFFINITY);
             else
                 pos = pos.next();
             break;
-        case WORD:
+        case WordGranularity:
             if (isLastVisiblePositionBeforeTableElement(pos.deepEquivalent()))
                 pos = VisiblePosition(positionAfterFollowingTableElement(pos.deepEquivalent()), VP_DEFAULT_AFFINITY);
             else
                 pos = nextWordPosition(pos);
             break;
-        case PARAGRAPH:
-            pos = nextParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
+        case SentenceGranularity:
+            pos = nextSentencePosition(pos);
             break;
-        case LINE:
+        case LineGranularity:
             pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
             break;
-        case LINE_BOUNDARY:
+        case ParagraphGranularity:
+            pos = nextParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
+            break;
+        case SentenceBoundary:
+            pos = endOfSentence(VisiblePosition(m_sel.end(), m_sel.affinity()));
+            break;
+        case LineBoundary:
             pos = endOfLine(VisiblePosition(m_sel.end(), m_sel.affinity()));
             break;
-        case PARAGRAPH_BOUNDARY:
+        case ParagraphBoundary:
             pos = endOfParagraph(VisiblePosition(m_sel.end(), m_sel.affinity()));
             break;
-        case DOCUMENT_BOUNDARY:
-            pos = endOfDocument(pos);
+        case DocumentBoundary:
+            pos = VisiblePosition(m_sel.end(), m_sel.affinity());
+            if (pos.deepEquivalent().node()->isContentEditable())
+                pos = endOfEditableContent(pos);
+            else
+                pos = endOfDocument(pos);
             break;
     }
     
     return pos;
 }
 
-VisiblePosition SelectionController::modifyMovingRightForward(ETextGranularity granularity)
+VisiblePosition SelectionController::modifyMovingRightForward(TextGranularity granularity)
 {
     VisiblePosition pos;
+    // FIXME: Stay in editable content for the less common granularities.
     switch (granularity) {
-        case CHARACTER:
+        case CharacterGranularity:
             if (isRange()) 
                 pos = VisiblePosition(m_sel.end(), m_sel.affinity());
             else
-                pos = VisiblePosition(m_sel.extent(), m_sel.affinity()).next();
+                pos = VisiblePosition(m_sel.extent(), m_sel.affinity()).next(true);
             break;
-        case WORD:
+        case WordGranularity:
             pos = nextWordPosition(VisiblePosition(m_sel.extent(), m_sel.affinity()));
             break;
-        case PARAGRAPH:
-            pos = nextParagraphPosition(VisiblePosition(m_sel.end(), m_sel.affinity()), xPosForVerticalArrowNavigation(END, isRange()));
+        case SentenceGranularity:
+            pos = nextSentencePosition(VisiblePosition(m_sel.extent(), m_sel.affinity()));
             break;
-        case LINE: {
+        case LineGranularity: {
             // down-arrowing from a range selection that ends at the start of a line needs
             // to leave the selection at that line start (no need to call nextLinePosition!)
             pos = VisiblePosition(m_sel.end(), m_sel.affinity());
@@ -338,20 +277,31 @@ VisiblePosition SelectionController::modifyMovingRightForward(ETextGranularity g
                 pos = nextLinePosition(pos, xPosForVerticalArrowNavigation(END, isRange()));
             break;
         }
-        case LINE_BOUNDARY:
+        case ParagraphGranularity:
+            pos = nextParagraphPosition(VisiblePosition(m_sel.end(), m_sel.affinity()), xPosForVerticalArrowNavigation(END, isRange()));
+            break;
+        case SentenceBoundary:
+            pos = endOfSentence(VisiblePosition(m_sel.end(), m_sel.affinity()));
+            break;
+        case LineBoundary:
             pos = endOfLine(VisiblePosition(m_sel.end(), m_sel.affinity()));
             break;
-        case PARAGRAPH_BOUNDARY:
+        case ParagraphBoundary:
             pos = endOfParagraph(VisiblePosition(m_sel.end(), m_sel.affinity()));
             break;
-        case DOCUMENT_BOUNDARY:
-            pos = endOfDocument(VisiblePosition(m_sel.end(), m_sel.affinity()));
+        case DocumentBoundary:
+            pos = VisiblePosition(m_sel.end(), m_sel.affinity());
+            if (pos.deepEquivalent().node()->isContentEditable())
+                pos = endOfEditableContent(pos);
+            else
+                pos = endOfDocument(pos);
             break;
+            
     }
     return pos;
 }
 
-VisiblePosition SelectionController::modifyExtendingLeftBackward(ETextGranularity granularity)
+VisiblePosition SelectionController::modifyExtendingLeftBackward(TextGranularity granularity)
 {
     VisiblePosition pos(m_sel.extent(), m_sel.affinity());
         
@@ -360,72 +310,93 @@ VisiblePosition SelectionController::modifyExtendingLeftBackward(ETextGranularit
     // It was done here instead of in VisiblePosition because we want VPs to iterate
     // over everything.
     switch (granularity) {
-        case CHARACTER:
+        case CharacterGranularity:
             if (isFirstVisiblePositionAfterTableElement(pos.deepEquivalent()))
                 pos = VisiblePosition(positionBeforePrecedingTableElement(pos.deepEquivalent()), VP_DEFAULT_AFFINITY);
             else
                 pos = pos.previous();
             break;
-        case WORD:
+        case WordGranularity:
             if (isFirstVisiblePositionAfterTableElement(pos.deepEquivalent()))
                 pos = VisiblePosition(positionBeforePrecedingTableElement(pos.deepEquivalent()), VP_DEFAULT_AFFINITY);
             else
                 pos = previousWordPosition(pos);
             break;
-        case PARAGRAPH:
-            pos = previousParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
+        case SentenceGranularity:
+            pos = previousSentencePosition(pos);
             break;
-        case LINE:
+        case LineGranularity:
             pos = previousLinePosition(pos, xPosForVerticalArrowNavigation(EXTENT));
             break;
-        case LINE_BOUNDARY:
+        case ParagraphGranularity:
+            pos = previousParagraphPosition(pos, xPosForVerticalArrowNavigation(EXTENT));
+            break;
+        case SentenceBoundary:
+            pos = startOfSentence(VisiblePosition(m_sel.start(), m_sel.affinity()));
+            break;
+        case LineBoundary:
             pos = startOfLine(VisiblePosition(m_sel.start(), m_sel.affinity()));
             break;
-        case PARAGRAPH_BOUNDARY:
+        case ParagraphBoundary:
             pos = startOfParagraph(VisiblePosition(m_sel.start(), m_sel.affinity()));
             break;
-        case DOCUMENT_BOUNDARY:
-            pos = startOfDocument(pos);
+        case DocumentBoundary:
+            pos = VisiblePosition(m_sel.start(), m_sel.affinity());
+            if (pos.deepEquivalent().node()->isContentEditable())
+                pos = startOfEditableContent(pos);
+            else 
+                pos = startOfDocument(VisiblePosition(m_sel.start(), m_sel.affinity()));
             break;
     }
     return pos;
 }
 
-VisiblePosition SelectionController::modifyMovingLeftBackward(ETextGranularity granularity)
+VisiblePosition SelectionController::modifyMovingLeftBackward(TextGranularity granularity)
 {
     VisiblePosition pos;
+    // FIXME: Stay in editable content for the less common granularities.
     switch (granularity) {
-        case CHARACTER:
+        case CharacterGranularity:
             if (isRange()) 
                 pos = VisiblePosition(m_sel.start(), m_sel.affinity());
             else
-                pos = VisiblePosition(m_sel.extent(), m_sel.affinity()).previous();
+                pos = VisiblePosition(m_sel.extent(), m_sel.affinity()).previous(true);
             break;
-        case WORD:
+        case WordGranularity:
             pos = previousWordPosition(VisiblePosition(m_sel.extent(), m_sel.affinity()));
             break;
-        case PARAGRAPH:
-            pos = previousParagraphPosition(VisiblePosition(m_sel.start(), m_sel.affinity()), xPosForVerticalArrowNavigation(START, isRange()));
+        case SentenceGranularity:
+            pos = previousSentencePosition(VisiblePosition(m_sel.extent(), m_sel.affinity()));
             break;
-        case LINE:
+        case LineGranularity:
             pos = previousLinePosition(VisiblePosition(m_sel.start(), m_sel.affinity()), xPosForVerticalArrowNavigation(START, isRange()));
             break;
-        case LINE_BOUNDARY:
+        case ParagraphGranularity:
+            pos = previousParagraphPosition(VisiblePosition(m_sel.start(), m_sel.affinity()), xPosForVerticalArrowNavigation(START, isRange()));
+            break;
+        case SentenceBoundary:
+            pos = startOfSentence(VisiblePosition(m_sel.start(), m_sel.affinity()));
+            break;
+        case LineBoundary:
             pos = startOfLine(VisiblePosition(m_sel.start(), m_sel.affinity()));
             break;
-        case PARAGRAPH_BOUNDARY:
+        case ParagraphBoundary:
             pos = startOfParagraph(VisiblePosition(m_sel.start(), m_sel.affinity()));
             break;
-        case DOCUMENT_BOUNDARY:
-            pos = startOfDocument(VisiblePosition(m_sel.start(), m_sel.affinity()));
+        case DocumentBoundary:
+            pos = VisiblePosition(m_sel.start(), m_sel.affinity());
+            if (pos.deepEquivalent().node()->isContentEditable())
+                pos = startOfEditableContent(pos);
+            else 
+                pos = startOfDocument(VisiblePosition(m_sel.start(), m_sel.affinity()));
             break;
     }
     return pos;
 }
 
-bool SelectionController::modify(const DOMString &alterString, const DOMString &directionString, const DOMString &granularityString)
+bool SelectionController::modify(const String &alterString, const String &directionString, const String &granularityString)
 {
-    DOMString alterStringLower = alterString.lower();
+    String alterStringLower = alterString.lower();
     EAlter alter;
     if (alterStringLower == "extend")
         alter = EXTEND;
@@ -434,7 +405,7 @@ bool SelectionController::modify(const DOMString &alterString, const DOMString &
     else 
         return false;
     
-    DOMString directionStringLower = directionString.lower();
+    String directionStringLower = directionString.lower();
     EDirection direction;
     if (directionStringLower == "forward")
         direction = FORWARD;
@@ -447,26 +418,28 @@ bool SelectionController::modify(const DOMString &alterString, const DOMString &
     else
         return false;
         
-    DOMString granularityStringLower = granularityString.lower();
-    ETextGranularity granularity;
+    String granularityStringLower = granularityString.lower();
+    TextGranularity granularity;
     if (granularityStringLower == "character")
-        granularity = CHARACTER;
+        granularity = CharacterGranularity;
     else if (granularityStringLower == "word")
-        granularity = WORD;
+        granularity = WordGranularity;
+    else if (granularityStringLower == "sentence")
+        granularity = SentenceGranularity;
     else if (granularityStringLower == "line")
-        granularity = LINE;
+        granularity = LineGranularity;
     else if (granularityStringLower == "paragraph")
-        granularity = PARAGRAPH;
+        granularity = ParagraphGranularity;
     else
         return false;
                 
     return modify(alter, direction, granularity);
 }
 
-bool SelectionController::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
+bool SelectionController::modify(EAlter alter, EDirection dir, TextGranularity granularity)
 {
-    if (frame())
-        frame()->setSelectionGranularity(granularity);
+    if (m_frame)
+        m_frame->setSelectionGranularity(granularity);
     
     setModifyBias(alter, dir);
 
@@ -510,7 +483,7 @@ bool SelectionController::modify(EAlter alter, EDirection dir, ETextGranularity
 static bool caretY(const VisiblePosition &c, int &y)
 {
     Position p = c.deepEquivalent();
-    NodeImpl *n = p.node();
+    Node *n = p.node();
     if (!n)
         return false;
     RenderObject *r = p.node()->renderer();
@@ -590,7 +563,7 @@ bool SelectionController::modify(EAlter alter, int verticalDistance)
     return true;
 }
 
-bool SelectionController::expandUsingGranularity(ETextGranularity granularity)
+bool SelectionController::expandUsingGranularity(TextGranularity granularity)
 {
     if (isNone())
         return false;
@@ -623,7 +596,7 @@ int SelectionController::xPosForVerticalArrowNavigation(EPositionType type, bool
             break;
     }
 
-    Frame *frame = pos.node()->getDocument()->frame();
+    Frame *frame = pos.node()->document()->frame();
     if (!frame)
         return x;
         
@@ -641,31 +614,26 @@ int SelectionController::xPosForVerticalArrowNavigation(EPositionType type, bool
 void SelectionController::clear()
 {
     setSelection(Selection());
-    m_needsLayout = true;
 }
 
 void SelectionController::setBase(const VisiblePosition &pos)
 {
     setSelection(Selection(pos.deepEquivalent(), m_sel.extent(), pos.affinity()));
-    m_needsLayout = true;
 }
 
 void SelectionController::setExtent(const VisiblePosition &pos)
 {
     setSelection(Selection(m_sel.base(), pos.deepEquivalent(), pos.affinity()));
-    m_needsLayout = true;
 }
 
 void SelectionController::setBase(const Position &pos, EAffinity affinity)
 {
     setSelection(Selection(pos, m_sel.extent(), affinity));
-    m_needsLayout = true;
 }
 
 void SelectionController::setExtent(const Position &pos, EAffinity affinity)
 {
     setSelection(Selection(m_sel.base(), pos, affinity));
-    m_needsLayout = true;
 }
 
 void SelectionController::setNeedsLayout(bool flag)
@@ -673,32 +641,27 @@ void SelectionController::setNeedsLayout(bool flag)
     m_needsLayout = flag;
 }
 
-DOMString SelectionController::type() const
+String SelectionController::type() const
 {
     if (isNone())
-        return DOMString("None");
+        return "None";
     else if (isCaret())
-        return DOMString("Caret");
+        return "Caret";
     else
-        return DOMString("Range");
+        return "Range";
 }
 
-DOMString SelectionController::toString() const
+String SelectionController::toString() const
 {
-    return DOMString(plainText(m_sel.toRange().get()));
+    return String(plainText(m_sel.toRange().get()));
 }
 
-PassRefPtr<RangeImpl> SelectionController::getRangeAt(int index) const
+PassRefPtr<Range> SelectionController::getRangeAt(int index) const
 {
     return index == 0 ? m_sel.toRange() : 0;
 }
 
-Frame *SelectionController::frame() const
-{
-    return !isNone() ? m_sel.start().node()->getDocument()->frame() : 0;
-}
-
-void SelectionController::setBaseAndExtent(NodeImpl *baseNode, int baseOffset, NodeImpl *extentNode, int extentOffset)
+void SelectionController::setBaseAndExtent(Node *baseNode, int baseOffset, Node *extentNode, int extentOffset)
 {
     VisiblePosition visibleBase = VisiblePosition(baseNode, baseOffset, DOWNSTREAM);
     VisiblePosition visibleExtent = VisiblePosition(extentNode, extentOffset, DOWNSTREAM);
@@ -706,12 +669,12 @@ void SelectionController::setBaseAndExtent(NodeImpl *baseNode, int baseOffset, N
     moveTo(visibleBase, visibleExtent);
 }
 
-void SelectionController::setPosition(NodeImpl *node, int offset)
+void SelectionController::setPosition(Node *node, int offset)
 {
     moveTo(VisiblePosition(node, offset, DOWNSTREAM));
 }
 
-void SelectionController::collapse(NodeImpl *node, int offset)
+void SelectionController::collapse(Node *node, int offset)
 {
     moveTo(VisiblePosition(node, offset, DOWNSTREAM));
 }
@@ -731,7 +694,7 @@ void SelectionController::empty()
     moveTo(SelectionController());
 }
 
-void SelectionController::extend(NodeImpl *node, int offset)
+void SelectionController::extend(Node *node, int offset)
 {
     moveTo(VisiblePosition(node, offset, DOWNSTREAM));
 }
@@ -744,7 +707,7 @@ void SelectionController::layout()
         return;
     }
 
-    m_sel.start().node()->getDocument()->updateRendering();
+    m_sel.start().node()->document()->updateRendering();
     
     m_caretRect = IntRect();
     m_caretPositionOnLayout = IntPoint();
@@ -757,7 +720,7 @@ void SelectionController::layout()
             m_caretRect = pos.node()->renderer()->caretRect(pos.offset(), m_sel.affinity());
             
             int x, y;
-            pos.node()->renderer()->absolutePosition(x, y);
+            pos.node()->renderer()->absolutePositionForContent(x, y);
             m_caretPositionOnLayout = IntPoint(x, y);
         }
     }
@@ -774,7 +737,7 @@ IntRect SelectionController::caretRect() const
 
     if (m_sel.start().node() && m_sel.start().node()->renderer()) {
         int x, y;
-        m_sel.start().node()->renderer()->absolutePosition(x, y);
+        m_sel.start().node()->renderer()->absolutePositionForContent(x, y);
         caret.move(IntPoint(x, y) - m_caretPositionOnLayout);
     }
 
@@ -795,10 +758,7 @@ void SelectionController::needsCaretRepaint()
     if (!isCaret())
         return;
 
-    if (!m_sel.start().node()->getDocument())
-        return;
-
-    FrameView *v = m_sel.start().node()->getDocument()->view();
+    FrameView *v = m_sel.start().node()->document()->view();
     if (!v)
         return;
 
@@ -823,7 +783,7 @@ void SelectionController::needsCaretRepaint()
     v->updateContents(caretRepaintRect(), false);
 }
 
-void SelectionController::paintCaret(QPainter *p, const IntRect &rect)
+void SelectionController::paintCaret(GraphicsContext *p, const IntRect &rect)
 {
     if (! m_sel.isCaret())
         return;
@@ -833,14 +793,14 @@ void SelectionController::paintCaret(QPainter *p, const IntRect &rect)
         
     IntRect caret = intersection(caretRect(), rect);
     if (!caret.isEmpty())
-        p->fillRect(caret, Brush());
+        p->fillRect(caret, Color::black);
 }
 
 void SelectionController::debugRenderer(RenderObject *r, bool selected) const
 {
     if (r->node()->isElementNode()) {
-        ElementImpl *element = static_cast<ElementImpl *>(r->node());
-        fprintf(stderr, "%s%s\n", selected ? "==> " : "    ", element->localName().qstring().latin1());
+        Element *element = static_cast<Element *>(r->node());
+        fprintf(stderr, "%s%s\n", selected ? "==> " : "    ", element->localName().deprecatedString().latin1());
     }
     else if (r->isText()) {
         RenderText *textRenderer = static_cast<RenderText *>(r);
@@ -850,7 +810,7 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
         }
         
         static const int max = 36;
-        QString text = DOMString(textRenderer->string()).qstring();
+        DeprecatedString text = String(textRenderer->string()).deprecatedString();
         int textLength = text.length();
         if (selected) {
             int offset = 0;
@@ -863,7 +823,7 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
             InlineTextBox *box = textRenderer->findNextInlineTextBox(offset, pos);
             text = text.mid(box->m_start, box->m_len);
             
-            QString show;
+            DeprecatedString show;
             int mid = max / 2;
             int caret = 0;
             
@@ -910,45 +870,32 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
 }
 
 #ifndef NDEBUG
-#define FormatBufferSize 1024
-void SelectionController::formatForDebugger(char *buffer, unsigned length) const
+
+void SelectionController::formatForDebugger(charbuffer, unsigned length) const
 {
-    DOMString result;
-    DOMString s;
-    
-    if (isNone()) {
-        result = "<none>";
-    }
-    else {
-        char s[FormatBufferSize];
-        result += "from ";
-        m_sel.start().formatForDebugger(s, FormatBufferSize);
-        result += s;
-        result += " to ";
-        m_sel.end().formatForDebugger(s, FormatBufferSize);
-        result += s;
-    }
-          
-    strncpy(buffer, result.qstring().latin1(), length - 1);
+    m_sel.formatForDebugger(buffer, length);
 }
-#undef FormatBufferSize
 
-void SelectionController::showTree() const
+void SelectionController::showTreeForThis() const
 {
-    if (m_sel.start().node())
-        m_sel.start().node()->showTreeAndMark(m_sel.start().node(), "S", m_sel.end().node(), "E");
+    m_sel.showTreeForThis();
 }
 
-void showTree(const SelectionController &sel)
+#endif
+
+}
+
+#ifndef NDEBUG
+
+void showTree(const WebCore::SelectionController& sel)
 {
-    sel.showTree();
+    sel.showTreeForThis();
 }
 
-void showTree(const SelectionController *sel)
+void showTree(const WebCore::SelectionController* sel)
 {
     if (sel)
-        sel->showTree();
+        sel->showTreeForThis();
 }
-#endif
 
-}
+#endif