Reviewed by John
authorkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Sep 2004 17:51:52 +0000 (17:51 +0000)
committerkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 29 Sep 2004 17:51:52 +0000 (17:51 +0000)
        Fix for this bug:

        <rdar://problem/3815895> exception inside fontForSelection causes Mail to abort when selection hits bottom

        * khtml/editing/selection.cpp:
        (khtml::Selection::toRange): Use RangeImpl calls to detect exceptions when creating a Range
        from a Selection. Return an empty Range when there is an exception.

        Fix for this bug:

        <rdar://problem/3817268> REGRESSION (Mail): Window does not scroll when selecting out of
        visible area of view with arrow keys

        * khtml/editing/selection.cpp: Did some name changing. m_needsCaretLayout -> m_needsLayout.
        Added m_expectedVisibleRect which supplies the right rectangle to update when scrolling.
        (khtml::Selection::Selection): m_needsCaretLayout -> m_needsLayout name change.
        (khtml::Selection::init): Handle m_expectedVisibleRect in initialization.
        (khtml::Selection::operator=): Handle m_expectedVisibleRect in assignment.
        (khtml::Selection::setNeedsLayout): m_needsCaretLayout -> m_needsLayout name change.
        (khtml::Selection::layout): Changed name from layoutCaret, since m_expectedVisibleRect
        is also calculated here.
        (khtml::Selection::caretRect): m_needsCaretLayout -> m_needsLayout name change.
        (khtml::Selection::expectedVisibleRect): New. Returns m_expectedVisibleRect, doing a
        layout if needed.
        (khtml::Selection::needsCaretRepaint): m_needsCaretLayout -> m_needsLayout name change.
        (khtml::Selection::paintCaret): Ditto.
        (khtml::Selection::validate): Ditto.
        * khtml/editing/selection.h: Add m_expectedVisibleRect member variable and
        expectedVisibleRect accessor.
        * kwq/WebCoreBridge.h: Change name of ensureCaretVisible to ensureSelectionVisible, since
        this is not only about making the caret visible anymore. Now it can reveal the varying
        end of the selection when scrolling with arrow keys.
        * kwq/WebCoreBridge.mm:
        (-[WebCoreBridge alterCurrentSelection:direction:granularity:]): ensureCaretVisible to
        ensureSelectionVisible name change.
        (-[WebCoreBridge alterCurrentSelection:verticalDistance:]): Ditto
        (-[WebCoreBridge replaceSelectionWithFragment:selectReplacement:smartReplace:]): Ditto
        (-[WebCoreBridge insertNewline]): Ditto
        (-[WebCoreBridge insertText:selectInsertedText:]): Ditto
        (-[WebCoreBridge deleteKeyPressed]): Ditto
        (-[WebCoreBridge ensureSelectionVisible]): Ditto

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@7721 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/SelectionController.cpp
WebCore/khtml/editing/SelectionController.h
WebCore/khtml/editing/selection.cpp
WebCore/khtml/editing/selection.h
WebCore/kwq/WebCoreBridge.h
WebCore/kwq/WebCoreBridge.mm

index 117beda0c14045f2ce5addc3839982c9937a8a76..bac317fdd65fd9cff6caa11a2c07fc8f15d98a2c 100644 (file)
@@ -1,3 +1,49 @@
+2004-09-29  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by John
+
+        Fix for this bug:
+        
+        <rdar://problem/3815895> exception inside fontForSelection causes Mail to abort when selection hits bottom
+
+        * khtml/editing/selection.cpp:
+        (khtml::Selection::toRange): Use RangeImpl calls to detect exceptions when creating a Range
+        from a Selection. Return an empty Range when there is an exception.
+
+        Fix for this bug:
+        
+        <rdar://problem/3817268> REGRESSION (Mail): Window does not scroll when selecting out of 
+        visible area of view with arrow keys
+
+        * khtml/editing/selection.cpp: Did some name changing. m_needsCaretLayout -> m_needsLayout.
+        Added m_expectedVisibleRect which supplies the right rectangle to update when scrolling.
+        (khtml::Selection::Selection): m_needsCaretLayout -> m_needsLayout name change.
+        (khtml::Selection::init): Handle m_expectedVisibleRect in initialization.
+        (khtml::Selection::operator=): Handle m_expectedVisibleRect in assignment.
+        (khtml::Selection::setNeedsLayout): m_needsCaretLayout -> m_needsLayout name change.
+        (khtml::Selection::layout): Changed name from layoutCaret, since m_expectedVisibleRect
+        is also calculated here.
+        (khtml::Selection::caretRect): m_needsCaretLayout -> m_needsLayout name change.
+        (khtml::Selection::expectedVisibleRect): New. Returns m_expectedVisibleRect, doing a 
+        layout if needed.
+        (khtml::Selection::needsCaretRepaint): m_needsCaretLayout -> m_needsLayout name change.
+        (khtml::Selection::paintCaret): Ditto.
+        (khtml::Selection::validate): Ditto.
+        * khtml/editing/selection.h: Add m_expectedVisibleRect member variable and 
+        expectedVisibleRect accessor.
+        * kwq/WebCoreBridge.h: Change name of ensureCaretVisible to ensureSelectionVisible, since
+        this is not only about making the caret visible anymore. Now it can reveal the varying
+        end of the selection when scrolling with arrow keys.
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge alterCurrentSelection:direction:granularity:]): ensureCaretVisible to 
+        ensureSelectionVisible name change.
+        (-[WebCoreBridge alterCurrentSelection:verticalDistance:]): Ditto
+        (-[WebCoreBridge replaceSelectionWithFragment:selectReplacement:smartReplace:]): Ditto
+        (-[WebCoreBridge insertNewline]): Ditto
+        (-[WebCoreBridge insertText:selectInsertedText:]): Ditto
+        (-[WebCoreBridge deleteKeyPressed]): Ditto
+        (-[WebCoreBridge ensureSelectionVisible]): Ditto
+
 2004-09-29  Ken Kocienda  <kocienda@apple.com>
 
         Reviewed by Hyatt
index adb5ff8e5e87abfdde3ea5c27fefc8e5d0a6507e..ebaa9831049d13a27834efb99098dad5fc26d6b8 100644 (file)
@@ -105,7 +105,7 @@ Selection::Selection(const Selection &o)
     , m_start(o.m_start), m_end(o.m_end)
     , m_state(o.m_state), m_affinity(o.m_affinity)
     , m_baseIsStart(o.m_baseIsStart)
-    , m_needsCaretLayout(o.m_needsCaretLayout)
+    , m_needsLayout(o.m_needsLayout)
     , m_modifyBiasSet(o.m_modifyBiasSet)
 {
     // Only copy the coordinates over if the other object
@@ -113,8 +113,9 @@ Selection::Selection(const Selection &o)
     // 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_needsCaretLayout) {
+    if (!m_needsLayout) {
         m_caretRect = o.m_caretRect;
+        m_expectedVisibleRect = o.m_expectedVisibleRect;
     }
 }
 
@@ -123,7 +124,7 @@ void Selection::init()
     m_state = NONE; 
     m_affinity = DOWNSTREAM;
     m_baseIsStart = true;
-    m_needsCaretLayout = true;
+    m_needsLayout = true;
     m_modifyBiasSet = false;
 }
 
@@ -138,7 +139,7 @@ Selection &Selection::operator=(const Selection &o)
     m_affinity = o.m_affinity;
 
     m_baseIsStart = o.m_baseIsStart;
-    m_needsCaretLayout = o.m_needsCaretLayout;
+    m_needsLayout = o.m_needsLayout;
     m_modifyBiasSet = o.m_modifyBiasSet;
     
     // Only copy the coordinates over if the other object
@@ -146,8 +147,9 @@ Selection &Selection::operator=(const Selection &o)
     // 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_needsCaretLayout) {
+    if (!m_needsLayout) {
         m_caretRect = o.m_caretRect;
+        m_expectedVisibleRect = o.m_expectedVisibleRect;
     }
     
     return *this;
@@ -539,7 +541,7 @@ void Selection::setBaseAndExtent(const Position &base, const Position &extent)
 
 void Selection::setNeedsLayout(bool flag)
 {
-    m_needsCaretLayout = flag;
+    m_needsLayout = flag;
 }
 
 Range Selection::toRange() const
@@ -587,32 +589,70 @@ Range Selection::toRange() const
         e = e.equivalentRangeCompliantPosition();
     }
 
-    return Range(s.node(), s.offset(), e.node(), e.offset());
+    // Use this roundabout way of creating the Range in order to have defined behavior
+    // when there is a DOM exception.
+    int exceptionCode = 0;
+    Range result(s.node()->getDocument());
+    RangeImpl *handle = result.handle();
+    ASSERT(handle);
+    handle->setStart(s.node(), s.offset(), exceptionCode);
+    if (exceptionCode) {
+        ERROR("Exception setting Range start from Selection: %d", exceptionCode);
+        return Range();
+    }
+    handle->setEnd(e.node(), e.offset(), exceptionCode);
+    if (exceptionCode) {
+        ERROR("Exception setting Range end from Selection: %d", exceptionCode);
+        return Range();
+    }
+    return result;
 }
 
-void Selection::layoutCaret()
+void Selection::layout()
 {
-    if (!isCaret() || !m_start.node()->inDocument()) {
+    if (isNone() || !m_start.node()->inDocument() || !m_end.node()->inDocument()) {
         m_caretRect = QRect();
+        m_expectedVisibleRect = QRect();
         return;
     }
-    
-    // EDIT FIXME: Enhance call to pass along selection 
-    // upstream/downstream affinity to get the right position.
-    m_caretRect = m_start.node()->renderer()->caretRect(m_start.offset(), false);
+        
+    if (isCaret()) {
+        // EDIT FIXME: Enhance call to pass along selection 
+        // upstream/downstream affinity to get the right position.
+        m_caretRect = m_start.node()->renderer()->caretRect(m_start.offset(), false);
+        m_expectedVisibleRect = m_caretRect;
+    }
+    else {
+        // Calculate which position to use based on whether the base is the start.
+        // We want the position, start or end, that was calculated using the extent. 
+        // This makes the selection follow the extent position while scrolling as a 
+        // result of arrow navigation. 
+        Position pos = m_baseIsStart ? m_end : m_start;
+        m_expectedVisibleRect = pos.node()->renderer()->caretRect(pos.offset(), false);
+        m_caretRect = QRect();
+    }
 
-    m_needsCaretLayout = false;
+    m_needsLayout = false;
 }
 
 QRect Selection::caretRect() const
 {
-    if (m_needsCaretLayout) {
-        const_cast<Selection *>(this)->layoutCaret();
+    if (m_needsLayout) {
+        const_cast<Selection *>(this)->layout();
     }
 
     return m_caretRect;
 }
 
+QRect Selection::expectedVisibleRect() const
+{
+    if (m_needsLayout) {
+        const_cast<Selection *>(this)->layout();
+    }
+
+    return m_expectedVisibleRect;
+}
+
 QRect Selection::caretRepaintRect() const
 {
     // FIXME: Add one pixel of slop on each side to make sure we don't leave behind artifacts.
@@ -634,10 +674,10 @@ void Selection::needsCaretRepaint()
     if (!v)
         return;
 
-    if (m_needsCaretLayout) {
+    if (m_needsLayout) {
         // repaint old position and calculate new position
         v->updateContents(caretRepaintRect(), false);
-        layoutCaret();
+        layout();
         
         // EDIT FIXME: This is an unfortunate hack.
         // Basically, we can't trust this layout position since we 
@@ -650,7 +690,7 @@ void Selection::needsCaretRepaint()
         // changes which may have been done.
         // And, we need to leave this layout here so the caret moves right 
         // away after clicking.
-        m_needsCaretLayout = true;
+        m_needsLayout = true;
     }
     v->updateContents(caretRepaintRect(), false);
 }
@@ -660,8 +700,8 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
     if (m_state != CARET)
         return;
 
-    if (m_needsCaretLayout)
-        layoutCaret();
+    if (m_needsLayout)
+        layout();
 
     if (m_caretRect.isValid())
         p->fillRect(m_caretRect & rect, QBrush());
@@ -809,7 +849,7 @@ void Selection::validate(ETextGranularity granularity)
         m_end = m_end.upstream(StayInBlock);
     }
 
-    m_needsCaretLayout = true;
+    m_needsLayout = true;
     
 #if EDIT_DEBUG
     debugPosition();
index 5bfe19636966f1834f9f21658030f439ad01cb90..c2068689024c877186ce242c43de47c497ab1a30 100644 (file)
@@ -91,6 +91,7 @@ public:
     Position end() const { return m_end; }
 
     QRect caretRect() const;
+    QRect expectedVisibleRect() const;
     void setNeedsLayout(bool flag = true);
 
     void clearModifyBias() { m_modifyBiasSet = false; }
@@ -123,7 +124,7 @@ private:
     VisiblePosition modifyExtendingLeftBackward(ETextGranularity);
     VisiblePosition modifyMovingLeftBackward(ETextGranularity);
 
-    void layoutCaret();
+    void layout();
     void needsCaretRepaint();
     void paintCaret(QPainter *p, const QRect &rect);
     QRect caretRepaintRect() const;
@@ -139,9 +140,10 @@ private:
     EAffinity m_affinity;         // the upstream/downstream affinity of the selection
 
     QRect m_caretRect;            // caret coordinates, size, and position
+    QRect m_expectedVisibleRect;  // rectangle used to update scroll position as selection changes
     
     bool m_baseIsStart : 1;       // true if base node is before the extent node
-    bool m_needsCaretLayout : 1;  // true if the caret position needs to be calculated
+    bool m_needsLayout : 1;       // true if the caret and expectedVisible rectangles need to be calculated
     bool m_modifyBiasSet : 1;     // true if the selection has been horizontally 
                                   // modified with EAlter::EXTEND
 };
index adb5ff8e5e87abfdde3ea5c27fefc8e5d0a6507e..ebaa9831049d13a27834efb99098dad5fc26d6b8 100644 (file)
@@ -105,7 +105,7 @@ Selection::Selection(const Selection &o)
     , m_start(o.m_start), m_end(o.m_end)
     , m_state(o.m_state), m_affinity(o.m_affinity)
     , m_baseIsStart(o.m_baseIsStart)
-    , m_needsCaretLayout(o.m_needsCaretLayout)
+    , m_needsLayout(o.m_needsLayout)
     , m_modifyBiasSet(o.m_modifyBiasSet)
 {
     // Only copy the coordinates over if the other object
@@ -113,8 +113,9 @@ Selection::Selection(const Selection &o)
     // 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_needsCaretLayout) {
+    if (!m_needsLayout) {
         m_caretRect = o.m_caretRect;
+        m_expectedVisibleRect = o.m_expectedVisibleRect;
     }
 }
 
@@ -123,7 +124,7 @@ void Selection::init()
     m_state = NONE; 
     m_affinity = DOWNSTREAM;
     m_baseIsStart = true;
-    m_needsCaretLayout = true;
+    m_needsLayout = true;
     m_modifyBiasSet = false;
 }
 
@@ -138,7 +139,7 @@ Selection &Selection::operator=(const Selection &o)
     m_affinity = o.m_affinity;
 
     m_baseIsStart = o.m_baseIsStart;
-    m_needsCaretLayout = o.m_needsCaretLayout;
+    m_needsLayout = o.m_needsLayout;
     m_modifyBiasSet = o.m_modifyBiasSet;
     
     // Only copy the coordinates over if the other object
@@ -146,8 +147,9 @@ Selection &Selection::operator=(const Selection &o)
     // 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_needsCaretLayout) {
+    if (!m_needsLayout) {
         m_caretRect = o.m_caretRect;
+        m_expectedVisibleRect = o.m_expectedVisibleRect;
     }
     
     return *this;
@@ -539,7 +541,7 @@ void Selection::setBaseAndExtent(const Position &base, const Position &extent)
 
 void Selection::setNeedsLayout(bool flag)
 {
-    m_needsCaretLayout = flag;
+    m_needsLayout = flag;
 }
 
 Range Selection::toRange() const
@@ -587,32 +589,70 @@ Range Selection::toRange() const
         e = e.equivalentRangeCompliantPosition();
     }
 
-    return Range(s.node(), s.offset(), e.node(), e.offset());
+    // Use this roundabout way of creating the Range in order to have defined behavior
+    // when there is a DOM exception.
+    int exceptionCode = 0;
+    Range result(s.node()->getDocument());
+    RangeImpl *handle = result.handle();
+    ASSERT(handle);
+    handle->setStart(s.node(), s.offset(), exceptionCode);
+    if (exceptionCode) {
+        ERROR("Exception setting Range start from Selection: %d", exceptionCode);
+        return Range();
+    }
+    handle->setEnd(e.node(), e.offset(), exceptionCode);
+    if (exceptionCode) {
+        ERROR("Exception setting Range end from Selection: %d", exceptionCode);
+        return Range();
+    }
+    return result;
 }
 
-void Selection::layoutCaret()
+void Selection::layout()
 {
-    if (!isCaret() || !m_start.node()->inDocument()) {
+    if (isNone() || !m_start.node()->inDocument() || !m_end.node()->inDocument()) {
         m_caretRect = QRect();
+        m_expectedVisibleRect = QRect();
         return;
     }
-    
-    // EDIT FIXME: Enhance call to pass along selection 
-    // upstream/downstream affinity to get the right position.
-    m_caretRect = m_start.node()->renderer()->caretRect(m_start.offset(), false);
+        
+    if (isCaret()) {
+        // EDIT FIXME: Enhance call to pass along selection 
+        // upstream/downstream affinity to get the right position.
+        m_caretRect = m_start.node()->renderer()->caretRect(m_start.offset(), false);
+        m_expectedVisibleRect = m_caretRect;
+    }
+    else {
+        // Calculate which position to use based on whether the base is the start.
+        // We want the position, start or end, that was calculated using the extent. 
+        // This makes the selection follow the extent position while scrolling as a 
+        // result of arrow navigation. 
+        Position pos = m_baseIsStart ? m_end : m_start;
+        m_expectedVisibleRect = pos.node()->renderer()->caretRect(pos.offset(), false);
+        m_caretRect = QRect();
+    }
 
-    m_needsCaretLayout = false;
+    m_needsLayout = false;
 }
 
 QRect Selection::caretRect() const
 {
-    if (m_needsCaretLayout) {
-        const_cast<Selection *>(this)->layoutCaret();
+    if (m_needsLayout) {
+        const_cast<Selection *>(this)->layout();
     }
 
     return m_caretRect;
 }
 
+QRect Selection::expectedVisibleRect() const
+{
+    if (m_needsLayout) {
+        const_cast<Selection *>(this)->layout();
+    }
+
+    return m_expectedVisibleRect;
+}
+
 QRect Selection::caretRepaintRect() const
 {
     // FIXME: Add one pixel of slop on each side to make sure we don't leave behind artifacts.
@@ -634,10 +674,10 @@ void Selection::needsCaretRepaint()
     if (!v)
         return;
 
-    if (m_needsCaretLayout) {
+    if (m_needsLayout) {
         // repaint old position and calculate new position
         v->updateContents(caretRepaintRect(), false);
-        layoutCaret();
+        layout();
         
         // EDIT FIXME: This is an unfortunate hack.
         // Basically, we can't trust this layout position since we 
@@ -650,7 +690,7 @@ void Selection::needsCaretRepaint()
         // changes which may have been done.
         // And, we need to leave this layout here so the caret moves right 
         // away after clicking.
-        m_needsCaretLayout = true;
+        m_needsLayout = true;
     }
     v->updateContents(caretRepaintRect(), false);
 }
@@ -660,8 +700,8 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
     if (m_state != CARET)
         return;
 
-    if (m_needsCaretLayout)
-        layoutCaret();
+    if (m_needsLayout)
+        layout();
 
     if (m_caretRect.isValid())
         p->fillRect(m_caretRect & rect, QBrush());
@@ -809,7 +849,7 @@ void Selection::validate(ETextGranularity granularity)
         m_end = m_end.upstream(StayInBlock);
     }
 
-    m_needsCaretLayout = true;
+    m_needsLayout = true;
     
 #if EDIT_DEBUG
     debugPosition();
index 5bfe19636966f1834f9f21658030f439ad01cb90..c2068689024c877186ce242c43de47c497ab1a30 100644 (file)
@@ -91,6 +91,7 @@ public:
     Position end() const { return m_end; }
 
     QRect caretRect() const;
+    QRect expectedVisibleRect() const;
     void setNeedsLayout(bool flag = true);
 
     void clearModifyBias() { m_modifyBiasSet = false; }
@@ -123,7 +124,7 @@ private:
     VisiblePosition modifyExtendingLeftBackward(ETextGranularity);
     VisiblePosition modifyMovingLeftBackward(ETextGranularity);
 
-    void layoutCaret();
+    void layout();
     void needsCaretRepaint();
     void paintCaret(QPainter *p, const QRect &rect);
     QRect caretRepaintRect() const;
@@ -139,9 +140,10 @@ private:
     EAffinity m_affinity;         // the upstream/downstream affinity of the selection
 
     QRect m_caretRect;            // caret coordinates, size, and position
+    QRect m_expectedVisibleRect;  // rectangle used to update scroll position as selection changes
     
     bool m_baseIsStart : 1;       // true if base node is before the extent node
-    bool m_needsCaretLayout : 1;  // true if the caret position needs to be calculated
+    bool m_needsLayout : 1;       // true if the caret and expectedVisible rectangles need to be calculated
     bool m_modifyBiasSet : 1;     // true if the selection has been horizontally 
                                   // modified with EAlter::EXTEND
 };
index 4130170fc9abad267408748869749110b749ed49..cfe7a576e18f8f212831e92e4091b99d58a5a4d5 100644 (file)
@@ -331,7 +331,7 @@ typedef enum {
 - (void)applyStyle:(DOMCSSStyleDeclaration *)style;
 - (BOOL)selectionStartHasStyle:(DOMCSSStyleDeclaration *)style;
 
-- (void)ensureCaretVisible;
+- (void)ensureSelectionVisible;
 
 - (WebScriptObject *)windowScriptObject;
 - (NPObject *)windowScriptNPObject;
index 08bb376b14ffd88d4851c9974c3e7b0bf3785ce3..b59761f3f2ae62715e35e6a87e5b8e891d3d18ed 100644 (file)
@@ -1405,7 +1405,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     if (xPos != KHTMLPart::NoXPosForVerticalArrowNavigation)
         _part->setXPosForVerticalArrowNavigation(xPos);
 
-    [self ensureCaretVisible];
+    [self ensureSelectionVisible];
 }
 
 - (DOMRange *)rangeByAlteringCurrentSelection:(WebSelectionAlteration)alteration verticalDistance:(float)verticalDistance
@@ -1431,7 +1431,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     _part->setSelection(selection);
     _part->setXPosForVerticalArrowNavigation(xPos);
 
-    [self ensureCaretVisible];
+    [self ensureSelectionVisible];
 }
 
 - (WebSelectionGranularity)selectionGranularity
@@ -1522,7 +1522,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     
     EditCommandPtr cmd(new ReplaceSelectionCommand(_part->xmlDocImpl(), [fragment _fragmentImpl], selectReplacement, smartReplace));
     cmd.apply();
-    [self ensureCaretVisible];
+    [self ensureSelectionVisible];
 }
 
 - (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
@@ -1549,7 +1549,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
         return;
     
     TypingCommand::insertNewline(_part->xmlDocImpl());
-    [self ensureCaretVisible];
+    [self ensureSelectionVisible];
 }
 
 - (void)insertText:(NSString *)text selectInsertedText:(BOOL)selectInsertedText
@@ -1558,7 +1558,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
         return;
     
     TypingCommand::insertText(_part->xmlDocImpl(), text, selectInsertedText);
-    [self ensureCaretVisible];
+    [self ensureSelectionVisible];
 }
 
 - (void)setSelectionToDragCaret
@@ -1627,7 +1627,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
         return;
     
     TypingCommand::deleteKeyPressed(_part->xmlDocImpl());
-    [self ensureCaretVisible];
+    [self ensureSelectionVisible];
 }
 
 - (void)applyStyle:(DOMCSSStyleDeclaration *)style
@@ -1655,16 +1655,16 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     return font;
 }
 
-- (void)ensureCaretVisible
+- (void)ensureSelectionVisible
 {
-    if (!_part || !_part->selection().isCaret())
+    if (!_part || _part->selection().isNone())
         return;
     
     KHTMLView *v = _part->view();
     if (!v)
         return;
 
-    QRect r(_part->selection().caretRect());
+    QRect r(_part->selection().expectedVisibleRect());
     v->ensureVisible(r.right(), r.bottom());
     v->ensureVisible(r.left(), r.top());
 }