[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

kocienda kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:35:15 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 602a8600e636cc545a04794b331a648950695cea
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Apr 21 16:42:34 2004 +0000

            Reviewed by John
    
            The Selection class now uses the Position class throughout its public and
            private interface. This replaces the inconsistent use of the Position
            class here and node/offset pairs there. There are no functional changes, only
            updates to the new Selection class API.
    
            * khtml/ecma/kjs_window.cpp:
            (Selection::get):
            (SelectionFunc::tryCall):
            * khtml/editing/htmlediting_impl.cpp:
            (DeleteCollapsibleWhitespaceCommandImpl::doApply):
            (DeleteSelectionCommandImpl::joinTextNodesWithSameStyle):
            (DeleteSelectionCommandImpl::doApply):
            (InputNewlineCommandImpl::doApply):
            (InputTextCommandImpl::deleteCharacter):
            (InputTextCommandImpl::prepareForTextInsertion):
            (InputTextCommandImpl::execute):
            (PasteMarkupCommandImpl::doApply):
            (TypingCommandImpl::issueCommandForDeleteKey):
            * khtml/khtml_part.cpp:
            (KHTMLPart::findTextNext):
            (KHTMLPart::setFocusNodeIfNeeded):
            (KHTMLPart::notifySelectionChanged):
            (KHTMLPart::isPointInsideSelection):
            (KHTMLPart::handleMouseMoveEventSelection):
            (KHTMLPart::khtmlMouseReleaseEvent):
            (KHTMLPart::selectAll):
            * khtml/rendering/render_block.cpp:
            (khtml::RenderBlock::paintObject):
            * khtml/xml/dom_docimpl.cpp:
            (DocumentImpl::updateSelection):
            * khtml/xml/dom_nodeimpl.cpp:
            * khtml/xml/dom_selection.cpp:
            (DOM::emptyPosition):
            (DOM::Selection::Selection):
            (DOM::Selection::init):
            (DOM::Selection::operator=):
            (DOM::Selection::moveTo):
            (DOM::Selection::modify):
            (DOM::Selection::xPosForVerticalArrowNavigation):
            (DOM::Selection::clear):
            (DOM::Selection::setBase):
            (DOM::Selection::setExtent):
            (DOM::Selection::setBaseAndExtent):
            (DOM::Selection::setStart):
            (DOM::Selection::setEnd):
            (DOM::Selection::setStartAndEnd):
            (DOM::Selection::toRange):
            (DOM::Selection::layoutCaret):
            (DOM::Selection::needsCaretRepaint):
            (DOM::Selection::paintCaret):
            (DOM::Selection::validate):
            (DOM::Selection::moveToRenderedContent):
            (DOM::Selection::nodeIsBeforeNode):
            (DOM::startAndEndLineNodesIncludingNode):
            (DOM::Selection::debugRenderer):
            (DOM::Selection::debugPosition):
            * khtml/xml/dom_selection.h:
            (DOM::Selection::~Selection):
            (DOM::Selection::base):
            (DOM::Selection::extent):
            (DOM::Selection::start):
            (DOM::Selection::end):
            (DOM::Selection::assignBase):
            (DOM::Selection::assignExtent):
            (DOM::Selection::assignBaseAndExtent):
            (DOM::Selection::assignStart):
            (DOM::Selection::assignEnd):
            (DOM::Selection::assignStartAndEnd):
            (DOM::operator==):
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::jumpToSelection):
            (KWQKHTMLPart::selectionStartOffset):
            (KWQKHTMLPart::selectionEndOffset):
            (KWQKHTMLPart::selectionStart):
            (KWQKHTMLPart::selectionEnd):
            * kwq/KWQRenderTreeDebug.cpp:
            (writeSelection):
            * kwq/WebCoreBridge.mm:
            (-[WebCoreBridge isSelectionEditable]):
            (-[WebCoreBridge setSelectionFrom:startOffset:to:endOffset:]):
            (-[WebCoreBridge setSelectedDOMRange:]):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6435 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 0bd17f4..f29b8aa 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,89 @@
+2004-04-21  Ken Kocienda  <kocienda at apple.com>
+
+        Reviewed by John
+
+        The Selection class now uses the Position class throughout its public and
+        private interface. This replaces the inconsistent use of the Position
+        class here and node/offset pairs there. There are no functional changes, only
+        updates to the new Selection class API.
+
+        * khtml/ecma/kjs_window.cpp:
+        (Selection::get):
+        (SelectionFunc::tryCall):
+        * khtml/editing/htmlediting_impl.cpp:
+        (DeleteCollapsibleWhitespaceCommandImpl::doApply):
+        (DeleteSelectionCommandImpl::joinTextNodesWithSameStyle):
+        (DeleteSelectionCommandImpl::doApply):
+        (InputNewlineCommandImpl::doApply):
+        (InputTextCommandImpl::deleteCharacter):
+        (InputTextCommandImpl::prepareForTextInsertion):
+        (InputTextCommandImpl::execute):
+        (PasteMarkupCommandImpl::doApply):
+        (TypingCommandImpl::issueCommandForDeleteKey):
+        * khtml/khtml_part.cpp:
+        (KHTMLPart::findTextNext):
+        (KHTMLPart::setFocusNodeIfNeeded):
+        (KHTMLPart::notifySelectionChanged):
+        (KHTMLPart::isPointInsideSelection):
+        (KHTMLPart::handleMouseMoveEventSelection):
+        (KHTMLPart::khtmlMouseReleaseEvent):
+        (KHTMLPart::selectAll):
+        * khtml/rendering/render_block.cpp:
+        (khtml::RenderBlock::paintObject):
+        * khtml/xml/dom_docimpl.cpp:
+        (DocumentImpl::updateSelection):
+        * khtml/xml/dom_nodeimpl.cpp:
+        * khtml/xml/dom_selection.cpp:
+        (DOM::emptyPosition):
+        (DOM::Selection::Selection):
+        (DOM::Selection::init):
+        (DOM::Selection::operator=):
+        (DOM::Selection::moveTo):
+        (DOM::Selection::modify):
+        (DOM::Selection::xPosForVerticalArrowNavigation):
+        (DOM::Selection::clear):
+        (DOM::Selection::setBase):
+        (DOM::Selection::setExtent):
+        (DOM::Selection::setBaseAndExtent):
+        (DOM::Selection::setStart):
+        (DOM::Selection::setEnd):
+        (DOM::Selection::setStartAndEnd):
+        (DOM::Selection::toRange):
+        (DOM::Selection::layoutCaret):
+        (DOM::Selection::needsCaretRepaint):
+        (DOM::Selection::paintCaret):
+        (DOM::Selection::validate):
+        (DOM::Selection::moveToRenderedContent):
+        (DOM::Selection::nodeIsBeforeNode):
+        (DOM::startAndEndLineNodesIncludingNode):
+        (DOM::Selection::debugRenderer):
+        (DOM::Selection::debugPosition):
+        * khtml/xml/dom_selection.h:
+        (DOM::Selection::~Selection):
+        (DOM::Selection::base):
+        (DOM::Selection::extent):
+        (DOM::Selection::start):
+        (DOM::Selection::end):
+        (DOM::Selection::assignBase):
+        (DOM::Selection::assignExtent):
+        (DOM::Selection::assignBaseAndExtent):
+        (DOM::Selection::assignStart):
+        (DOM::Selection::assignEnd):
+        (DOM::Selection::assignStartAndEnd):
+        (DOM::operator==):
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::jumpToSelection):
+        (KWQKHTMLPart::selectionStartOffset):
+        (KWQKHTMLPart::selectionEndOffset):
+        (KWQKHTMLPart::selectionStart):
+        (KWQKHTMLPart::selectionEnd):
+        * kwq/KWQRenderTreeDebug.cpp:
+        (writeSelection):
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge isSelectionEditable]):
+        (-[WebCoreBridge setSelectionFrom:startOffset:to:endOffset:]):
+        (-[WebCoreBridge setSelectedDOMRange:]):
+
 2004-04-20  Ken Kocienda  <kocienda at apple.com>
 
         Reviewed by Hyatt
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index 7e8aa2f..620da5c 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -862,7 +862,7 @@
 			isa = PBXShellScriptBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "if [ -f ../Tools/Scripts/embed-into-alex ]; then sh ../Tools/Scripts/embed-into-alex; fi";
+			shellScript = "#if [ -f ../Tools/Scripts/embed-into-alex ]; then sh ../Tools/Scripts/embed-into-alex; fi";
 		};
 //250
 //251
diff --git a/WebCore/khtml/ecma/kjs_window.cpp b/WebCore/khtml/ecma/kjs_window.cpp
index ea69dc7..ca3c1e3 100644
--- a/WebCore/khtml/ecma/kjs_window.cpp
+++ b/WebCore/khtml/ecma/kjs_window.cpp
@@ -58,12 +58,14 @@
 #include "editing/htmlediting.h"
 #include "xml/dom2_eventsimpl.h"
 #include "xml/dom_docimpl.h"
+#include "xml/dom_position.h"
 #include "xml/dom_selection.h"
 #include "html/html_documentimpl.h"
 
 using DOM::DocumentImpl;
 using DOM::DOMString;
 using DOM::Node;
+using DOM::Position;
 using khtml::TypingCommand;
 
 using namespace KJS;
@@ -2157,16 +2159,16 @@ Value Selection::get(ExecState *exec, const Identifier &p) const
     switch (entry->value) {
         case AnchorNode:
         case BaseNode:
-            return getDOMNode(exec, Node(m_part->selection().baseNode()));
+            return getDOMNode(exec, Node(m_part->selection().base().node()));
         case AnchorOffset:
         case BaseOffset:
-            return Number(m_part->selection().baseOffset());
+            return Number(m_part->selection().base().offset());
         case FocusNode:
         case ExtentNode:
-            return getDOMNode(exec, Node(m_part->selection().extentNode()));
+            return getDOMNode(exec, Node(m_part->selection().extent().node()));
         case FocusOffset:
         case ExtentOffset:
-            return Number(m_part->selection().extentOffset());
+            return Number(m_part->selection().extent().offset());
         case IsCollapsed:
             return Boolean(m_part->selection().state() == DOM::Selection::CARET);
         case _Type: {
@@ -2236,27 +2238,30 @@ Value SelectionFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
         switch (id) {
             case Selection::Collapse:
                 TypingCommand::closeTyping(part->lastEditCommand());
-                part->setSelection(DOM::Selection(KJS::toNode(args[0]).handle(), args[1].toInt32(exec)));
+                part->setSelection(DOM::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec))));
                 break;
             case Selection::CollapseToEnd:
                 TypingCommand::closeTyping(part->lastEditCommand());
-                part->setSelection(DOM::Selection(part->selection().endPosition()));
+                part->setSelection(DOM::Selection(part->selection().end()));
                 break;
             case Selection::CollapseToStart:
                 TypingCommand::closeTyping(part->lastEditCommand());
-                part->setSelection(DOM::Selection(part->selection().startPosition()));
+                part->setSelection(DOM::Selection(part->selection().start()));
                 break;
             case Selection::Empty:
                 TypingCommand::closeTyping(part->lastEditCommand());
                 part->clearSelection();
                 break;
-            case Selection::SetBaseAndExtent:
+            case Selection::SetBaseAndExtent: {
                 TypingCommand::closeTyping(part->lastEditCommand());
-                part->setSelection(DOM::Selection(KJS::toNode(args[0]).handle(), args[1].toInt32(exec), KJS::toNode(args[2]).handle(), args[3].toInt32(exec)));
+                Position base(KJS::toNode(args[0]).handle(), args[1].toInt32(exec));
+                Position extent(KJS::toNode(args[2]).handle(), args[3].toInt32(exec));
+                part->setSelection(DOM::Selection(base, extent));
                 break;
+            }
             case Selection::SetPosition:
                 TypingCommand::closeTyping(part->lastEditCommand());
-                part->setSelection(DOM::Selection(KJS::toNode(args[0]).handle(), args[1].toInt32(exec)));
+                part->setSelection(DOM::Selection(Position(KJS::toNode(args[0]).handle(), args[1].toInt32(exec))));
                 break;
             case Selection::Modify: {
                 TypingCommand::closeTyping(part->lastEditCommand());
diff --git a/WebCore/khtml/editing/SelectionController.cpp b/WebCore/khtml/editing/SelectionController.cpp
index e59b11f..1ae3586 100644
--- a/WebCore/khtml/editing/SelectionController.cpp
+++ b/WebCore/khtml/editing/SelectionController.cpp
@@ -33,7 +33,6 @@
 #include "qrect.h"
 #include "dom/dom2_range.h"
 #include "dom/dom_node.h"
-#include "dom/dom_position.h"
 #include "dom/dom_string.h"
 #include "rendering/render_object.h"
 #include "rendering/render_style.h"
@@ -52,69 +51,40 @@
 #define EDIT_DEBUG 0
 #endif
 
-namespace DOM {
-
 using khtml::InlineTextBox;
 using khtml::RenderObject;
 using khtml::RenderText;
 
+namespace DOM {
+
 #if APPLE_CHANGES
 static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset);
 static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset);
-static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, Selection &selection);
+static bool startAndEndLineNodesIncludingNode(NodeImpl *node, int offset, Selection &selection);
 #endif
 
-
-Selection::Selection()
+static inline Position &emptyPosition()
 {
-    init();
+    static Position EmptyPosition = Position();
+    return EmptyPosition;
 }
 
-Selection::Selection(NodeImpl *node, long offset)
+Selection::Selection()
 {
     init();
-
-	setBaseNode(node);
-	setExtentNode(node);
-	setBaseOffset(offset);
-	setExtentOffset(offset);
-
-    validate();
 }
 
 Selection::Selection(const Position &pos)
 {
     init();
-
-	setBaseNode(pos.node());
-	setExtentNode(pos.node());
-	setBaseOffset(pos.offset());
-	setExtentOffset(pos.offset());
-
+	assignBaseAndExtent(pos, pos);
     validate();
 }
 
 Selection::Selection(const Position &base, const Position &extent)
 {
     init();
-
-	setBaseNode(base.node());
-	setExtentNode(extent.node());
-	setBaseOffset(base.offset());
-	setExtentOffset(extent.offset());
-
-    validate();
-}
-
-Selection::Selection(NodeImpl *baseNode, long baseOffset, NodeImpl *endNode, long endOffset)
-{
-    init();
-
-	setBaseNode(baseNode);
-	setExtentNode(endNode);
-	setBaseOffset(baseOffset);
-	setExtentOffset(endOffset);
-
+	assignBaseAndExtent(base, extent);
     validate();
 }
 
@@ -122,15 +92,8 @@ Selection::Selection(const Selection &o)
 {
     init();
     
-	setBaseNode(o.baseNode());
-	setExtentNode(o.extentNode());
-	setBaseOffset(o.baseOffset());
-	setExtentOffset(o.extentOffset());
-
-	setStartNode(o.startNode());
-	setEndNode(o.endNode());
-	setStartOffset(o.startOffset());
-	setEndOffset(o.endOffset());
+	assignBaseAndExtent(o.base(), o.extent());
+	assignStartAndEnd(o.start(), o.end());
 
     m_state = o.m_state;
 
@@ -152,14 +115,7 @@ Selection::Selection(const Selection &o)
 
 void Selection::init()
 {
-    m_baseNode = 0;
-    m_baseOffset = 0;
-    m_extentNode = 0; 
-    m_extentOffset = 0;
-    m_startNode = 0;
-    m_startOffset = 0;
-    m_endNode = 0;
-    m_endOffset = 0;
+    m_base = m_extent = m_start = m_end = emptyPosition();
     m_state = NONE; 
     m_caretX = 0;
     m_caretY = 0;
@@ -169,29 +125,10 @@ void Selection::init()
     m_modifyBiasSet = false;
 }
 
-Selection::~Selection()
-{
-    if (m_baseNode)
-        m_baseNode->deref();
-    if (m_extentNode)
-        m_extentNode->deref();
-    if (m_startNode)
-        m_startNode->deref();
-    if (m_endNode)
-        m_endNode->deref();
-}
-
 Selection &Selection::operator=(const Selection &o)
 {
-	setBaseNode(o.baseNode());
-	setExtentNode(o.extentNode());
-	setBaseOffset(o.baseOffset());
-	setExtentOffset(o.extentOffset());
-
-	setStartNode(o.startNode());
-	setEndNode(o.endNode());
-	setStartOffset(o.startOffset());
-	setEndOffset(o.endOffset());
+	assignBaseAndExtent(o.base(), o.extent());
+	assignStartAndEnd(o.start(), o.end());
 
     m_state = o.m_state;
 
@@ -213,34 +150,27 @@ Selection &Selection::operator=(const Selection &o)
     return *this;
 }
 
-void Selection::moveTo(DOM::NodeImpl *node, long offset)
+void Selection::moveTo(const Range &r)
 {
-    moveTo(node, offset, node, offset);
+    Position start(r.startContainer().handle(), r.startOffset());
+    Position end(r.endContainer().handle(), r.endOffset());
+	moveTo(start, end);
 }
 
-void Selection::moveTo(const DOM::Range &r)
-{
-	moveTo(r.startContainer().handle(), r.startOffset(), 
-		r.endContainer().handle(), r.endOffset());
-}
-
-void Selection::moveTo(const DOM::Position &pos)
+void Selection::moveTo(const Selection &o)
 {
-	moveTo(pos.node(), pos.offset());
+	moveTo(o.start(), o.end());
 }
 
-void Selection::moveTo(const Selection &o)
+void Selection::moveTo(const Position &pos)
 {
-	moveTo(o.baseNode(), o.baseOffset(), o.extentNode(), o.extentOffset());
+	moveTo(pos, pos);
 }
 
-void Selection::moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeImpl *extentNode, long extentOffset)
+void Selection::moveTo(const Position &base, const Position &extent)
 {
-	setBaseNode(baseNode);
-	setExtentNode(extentNode);
-	setBaseOffset(baseOffset);
-	setExtentOffset(extentOffset);
-	validate();
+	assignBaseAndExtent(base, extent);
+    validate();
 }
 
 bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
@@ -254,29 +184,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(startNode());
-                    setBaseOffset(startOffset());
-                    setExtentNode(endNode());
-                    setExtentOffset(endOffset());
+                    assignBaseAndExtent(start(), end());
                 }
                 if (granularity == CHARACTER)
-                    pos = extentPosition().nextCharacterPosition();
+                    pos = extent().nextCharacterPosition();
                 else if (granularity == WORD)
-                    pos = extentPosition().nextWordPosition();
+                    pos = extent().nextWordPosition();
             }
             else {
                 m_modifyBiasSet = false;
                 if (state() == RANGE) {
                     if (granularity == CHARACTER)
-                        pos = endPosition();
+                        pos = end();
                     else if (granularity == WORD)
-                        pos = extentPosition().nextWordPosition();
+                        pos = extent().nextWordPosition();
                 }
                 else {
                     if (granularity == CHARACTER)
-                        pos = extentPosition().nextCharacterPosition();
+                        pos = extent().nextCharacterPosition();
                     else if (granularity == WORD)
-                        pos = extentPosition().nextWordPosition();
+                        pos = extent().nextWordPosition();
                 }
             }
             break;
@@ -286,29 +213,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(endNode());
-                    setBaseOffset(endOffset());
-                    setExtentNode(startNode());
-                    setExtentOffset(startOffset());
+                    assignBaseAndExtent(end(), start());
                 }
                 if (granularity == CHARACTER)
-                    pos = extentPosition().previousCharacterPosition();
+                    pos = extent().previousCharacterPosition();
                 else if (granularity == WORD)
-                    pos = extentPosition().previousWordPosition();
+                    pos = extent().previousWordPosition();
             }
             else {
                 m_modifyBiasSet = false;
                 if (state() == RANGE) {
                     if (granularity == CHARACTER)
-                        pos = startPosition();
+                        pos = start();
                     else if (granularity == WORD)
-                        pos = extentPosition().previousWordPosition();
+                        pos = extent().previousWordPosition();
                 }
                 else {
                     if (granularity == CHARACTER)
-                        pos = extentPosition().previousCharacterPosition();
+                        pos = extent().previousCharacterPosition();
                     else if (granularity == WORD)
-                        pos = extentPosition().previousWordPosition();
+                        pos = extent().previousWordPosition();
                 }
             }
             break;
@@ -316,32 +240,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(endNode());
-                    setBaseOffset(endOffset());
-                    setExtentNode(startNode());
-                    setExtentOffset(startOffset());
+                    assignBaseAndExtent(end(), start());
                 }
-                pos = extentPosition().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+                pos = extent().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
             }
             else {
                 m_modifyBiasSet = false;
-                pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
+                pos = start().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
             }
             break;
         case DOWN:
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(startNode());
-                    setBaseOffset(startOffset());
-                    setExtentNode(endNode());
-                    setExtentOffset(endOffset());
+                    assignBaseAndExtent(start(), end());
                 }
-                pos = extentPosition().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+                pos = extent().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
             }
             else {
                 m_modifyBiasSet = false;
-                pos = endPosition().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
+                pos = end().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
             }
             break;
     }
@@ -350,9 +268,9 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
         return false;
     
     if (alter == MOVE)
-        moveTo(pos.node(), pos.offset());
+        moveTo(pos);
     else // alter == EXTEND
-        setExtent(pos.node(), pos.offset());
+        setExtent(pos);
     
     return true;
 }
@@ -376,16 +294,16 @@ int Selection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) c
     Position pos;
     switch (type) {
         case START:
-            pos = startPosition();
+            pos = start();
             break;
         case END:
-            pos = endPosition();
+            pos = end();
             break;
         case BASE:
-            pos = basePosition();
+            pos = base();
             break;
         case EXTENT:
-            pos = extentPosition();
+            pos = extent();
             break;
     }
 
@@ -407,25 +325,44 @@ int Selection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) c
 
 void Selection::clear()
 {
-	setBaseNode(0);
-	setExtentNode(0);
-	setBaseOffset(0);
-	setExtentOffset(0);
+	assignBaseAndExtent(emptyPosition(), emptyPosition());
 	validate();
 }
 
-void Selection::setBase(DOM::NodeImpl *node, long offset)
+void Selection::setBase(const Position &pos)
 {
-	setBaseNode(node);
-	setBaseOffset(offset);
-	validate();
+    assignBase(pos);
+    validate();
 }
 
-void Selection::setExtent(DOM::NodeImpl *node, long offset)
+void Selection::setExtent(const Position &pos)
 {
-	setExtentNode(node);
-	setExtentOffset(offset);
-	validate();
+    assignExtent(pos);
+    validate();
+}
+
+void Selection::setBaseAndExtent(const Position &base, const Position &extent)
+{
+    assignBaseAndExtent(base, extent);
+    validate();
+}
+
+void Selection::setStart(const Position &pos)
+{
+    assignStart(pos);
+    validate();
+}
+
+void Selection::setEnd(const Position &pos)
+{
+    assignEnd(pos);
+    validate();
+}
+
+void Selection::setStartAndEnd(const Position &start, const Position &end)
+{
+    assignStartAndEnd(start, end);
+    validate();
 }
 
 void Selection::setNeedsLayout(bool flag)
@@ -438,17 +375,17 @@ Range Selection::toRange() const
     if (isEmpty())
         return Range();
 
-    return Range(Node(startNode()), startOffset(), Node(endNode()), endOffset());
+    return Range(Node(start().node()), start().offset(), Node(end().node()), end().offset());
 }
 
 void Selection::layoutCaret()
 {
-    if (isEmpty() || !startNode()->renderer()) {
+    if (isEmpty() || !start().node()->renderer()) {
         m_caretX = m_caretY = m_caretSize = 0;
     }
     else {
         int w;
-        startNode()->renderer()->caretPos(startOffset(), true, m_caretX, m_caretY, w, m_caretSize);
+        start().node()->renderer()->caretPos(start().offset(), true, m_caretX, m_caretY, w, m_caretSize);
     }
 
     m_needsCaretLayout = false;
@@ -465,10 +402,10 @@ void Selection::needsCaretRepaint()
     if (isEmpty())
         return;
 
-    if (!startNode()->getDocument())
+    if (!start().node()->getDocument())
         return;
 
-    KHTMLView *v = startNode()->getDocument()->view();
+    KHTMLView *v = start().node()->getDocument()->view();
     if (!v)
         return;
 
@@ -502,7 +439,7 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
         return;
 
     if (m_needsCaretLayout) {
-        Position pos = Position(startNode(), startOffset());
+        Position pos = start();
         if (!pos.inRenderedContent()) {
             moveToRenderedContent();
         }
@@ -520,126 +457,37 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
     }
 }
 
-void Selection::setBaseNode(DOM::NodeImpl *node)
-{
-	if (m_baseNode == node)
-		return;
-
-	if (m_baseNode)
-		m_baseNode->deref();
-	
-	m_baseNode = node;
-	
-	if (m_baseNode)
-		m_baseNode->ref();
-}
-
-void Selection::setBaseOffset(long offset)
-{
-	m_baseOffset = offset;
-}
-
-void Selection::setExtentNode(DOM::NodeImpl *node)
-{
-	if (m_extentNode == node)
-		return;
-
-	if (m_extentNode)
-		m_extentNode->deref();
-	
-	m_extentNode = node;
-	
-	if (m_extentNode)
-		m_extentNode->ref();
-}
-	
-void Selection::setExtentOffset(long offset)
-{
-	m_extentOffset = offset;
-}
-
-void Selection::setStartNode(DOM::NodeImpl *node)
-{
-	if (m_startNode == node)
-		return;
-
-	if (m_startNode)
-		m_startNode->deref();
-	
-	m_startNode = node;
-	
-	if (m_startNode)
-		m_startNode->ref();
-}
-
-void Selection::setStartOffset(long offset)
-{
-	m_startOffset = offset;
-}
-
-void Selection::setEndNode(DOM::NodeImpl *node)
-{
-	if (m_endNode == node)
-		return;
-
-	if (m_endNode)
-		m_endNode->deref();
-	
-	m_endNode = node;
-	
-	if (m_endNode)
-		m_endNode->ref();
-}
-	
-void Selection::setEndOffset(long offset)
-{
-	m_endOffset = offset;
-}
-
 void Selection::validate(ETextGranularity granularity)
 {
     // move the base and extent nodes to their equivalent leaf positions
-    bool baseAndExtentEqual = m_baseNode == m_extentNode && m_baseOffset == m_extentOffset;
-    if (m_baseNode) {
-        Position pos = basePosition().equivalentLeafPosition();
-        m_baseNode = pos.node();
-        m_baseOffset = pos.offset();
-        if (baseAndExtentEqual) {
-            m_extentNode = pos.node();
-            m_extentOffset = pos.offset();
-        }
+    bool baseAndExtentEqual = base() == extent();
+    if (base().notEmpty()) {
+        Position pos = base().equivalentLeafPosition();
+        assignBase(pos);
+        if (baseAndExtentEqual)
+            assignExtent(pos);
     }
-    if (m_extentNode && !baseAndExtentEqual) {
-        Position pos = extentPosition().equivalentLeafPosition();
-        m_extentNode = pos.node();
-        m_extentOffset = pos.offset();
+    if (extent().notEmpty() && !baseAndExtentEqual) {
+        assignExtent(extent().equivalentLeafPosition());
     }
 
     // make sure we do not have a dangling start or end
-	if (!m_baseNode && !m_extentNode) {
-        setBaseOffset(0);
-        setExtentOffset(0);
+	if (base().isEmpty() && extent().isEmpty()) {
+        assignStartAndEnd(emptyPosition(), emptyPosition());
         m_baseIsStart = true;
     }
-	else if (!m_baseNode) {
-		setBaseNode(m_extentNode);
-		setBaseOffset(m_extentOffset);
-        m_baseIsStart = true;
-	}
-	else if (!m_extentNode) {
-		setExtentNode(m_baseNode);
-		setExtentOffset(m_baseOffset);
+	else if (base().isEmpty() || extent().isEmpty()) {
         m_baseIsStart = true;
 	}
     else {
         // adjust m_baseIsStart as needed
-        if (m_baseNode == m_extentNode) {
-            if (m_baseOffset > m_extentOffset)
+        if (base().node() == extent().node()) {
+            if (base().offset() > extent().offset())
                 m_baseIsStart = false;
             else 
                 m_baseIsStart = true;
         }
-        else if (nodeIsBeforeNode(m_baseNode, m_extentNode))
+        else if (nodeIsBeforeNode(base().node(), extent().node()))
             m_baseIsStart = true;
         else
             m_baseIsStart = false;
@@ -647,101 +495,73 @@ void Selection::validate(ETextGranularity granularity)
 
     // calculate the correct start and end positions
 #if !APPLE_CHANGES
-    if (m_baseIsStart) {
-        setStartNode(m_baseNode);
-        setStartOffset(m_baseOffset);
-        setEndNode(m_extentNode);
-        setEndOffset(m_extentOffset);
-    }
-    else {
-        setStartNode(m_extentNode);
-        setStartOffset(m_extentOffset);
-        setEndNode(m_baseNode);
-        setEndOffset(m_baseOffset);
-    }
+    if (m_baseIsStart)
+        assignStartAndEnd(base(), extent());
+    else
+        assignStartAndEnd(extent(), base());
 #else
     if (granularity == CHARACTER) {
-        if (m_baseIsStart) {
-            setStartNode(m_baseNode);
-            setStartOffset(m_baseOffset);
-            setEndNode(m_extentNode);
-            setEndOffset(m_extentOffset);
-        }
-        else {
-            setStartNode(m_extentNode);
-            setStartOffset(m_extentOffset);
-            setEndNode(m_baseNode);
-            setEndOffset(m_baseOffset);
-        }
+        if (m_baseIsStart)
+            assignStartAndEnd(base(), extent());
+        else
+            assignStartAndEnd(extent(), base());
     }
     else if (granularity == WORD) {
-        int baseStartOffset = m_baseOffset;
-        int baseEndOffset = m_baseOffset;
-        int extentStartOffset = m_extentOffset;
-        int extentEndOffset = m_extentOffset;
-        if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            DOMString t = m_baseNode->nodeValue();
+        int baseStartOffset = base().offset();
+        int baseEndOffset = base().offset();
+        int extentStartOffset = extent().offset();
+        int extentEndOffset = extent().offset();
+        if (base().notEmpty() && (base().node()->nodeType() == Node::TEXT_NODE || base().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            DOMString t = base().node()->nodeValue();
             QChar *chars = t.unicode();
             uint len = t.length();
-            KWQFindWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
+            KWQFindWordBoundary(chars, len, base().offset(), &baseStartOffset, &baseEndOffset);
         }
-        if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            DOMString t = m_extentNode->nodeValue();
+        if (extent().notEmpty() && (extent().node()->nodeType() == Node::TEXT_NODE || extent().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            DOMString t = extent().node()->nodeValue();
             QChar *chars = t.unicode();
             uint len = t.length();
-            KWQFindWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
+            KWQFindWordBoundary(chars, len, extent().offset(), &extentStartOffset, &extentEndOffset);
         }
         if (m_baseIsStart) {
-            setStartNode(m_baseNode);
-            setStartOffset(baseStartOffset);
-            setEndNode(m_extentNode);
-            setEndOffset(extentEndOffset);
+            assignStart(Position(base().node(), baseStartOffset));
+            assignEnd(Position(extent().node(), extentEndOffset));
         }
         else {
-            setStartNode(m_extentNode);
-            setStartOffset(extentStartOffset);
-            setEndNode(m_baseNode);
-            setEndOffset(baseEndOffset);
+            assignStart(Position(extent().node(), extentStartOffset));
+            assignEnd(Position(base().node(), baseEndOffset));
         }
     }
-    else {  // granularity == LINE
+    else {  // granularity == LINE 
         Selection baseSelection = *this;
         Selection extentSelection = *this;
-        if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            if (startAndEndLineNodesIncludingNode(m_baseNode, m_baseOffset, baseSelection)) {
-                setStartNode(baseSelection.baseNode());
-                setStartOffset(baseSelection.baseOffset());
-                setEndNode(baseSelection.extentNode());
-                setEndOffset(baseSelection.extentOffset());
+        if (base().notEmpty() && (base().node()->nodeType() == Node::TEXT_NODE || base().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            if (startAndEndLineNodesIncludingNode(base().node(), base().offset(), baseSelection)) {
+                assignStart(Position(baseSelection.base().node(), baseSelection.base().offset()));
+                assignEnd(Position(baseSelection.extent().node(), baseSelection.extent().offset()));
             }
         }
-        if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            if (startAndEndLineNodesIncludingNode(m_extentNode, m_extentOffset, extentSelection)) {
-                setStartNode(extentSelection.baseNode());
-                setStartOffset(extentSelection.baseOffset());
-                setEndNode(extentSelection.extentNode());
-                setEndOffset(extentSelection.extentOffset());
+        if (extent().notEmpty() && (extent().node()->nodeType() == Node::TEXT_NODE || extent().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            if (startAndEndLineNodesIncludingNode(extent().node(), extent().offset(), extentSelection)) {
+                assignStart(Position(extentSelection.base().node(), extentSelection.base().offset()));
+                assignEnd(Position(extentSelection.extent().node(), extentSelection.extent().offset()));
             }
         }
         if (m_baseIsStart) {
-            setStartNode(baseSelection.startNode());
-            setStartOffset(baseSelection.startOffset());
-            setEndNode(extentSelection.endNode());
-            setEndOffset(extentSelection.endOffset());
+            assignStart(baseSelection.start());
+            assignEnd(extentSelection.end());
         }
         else {
-            setStartNode(extentSelection.startNode());
-            setStartOffset(extentSelection.startOffset());
-            setEndNode(baseSelection.endNode());
-            setEndOffset(baseSelection.endOffset());
+            assignStart(extentSelection.start());
+            assignEnd(baseSelection.end());
         }
     }
 #endif  // APPLE_CHANGES
 
 	// adjust the state
-	if (!m_startNode && !m_endNode)
+	if (start().isEmpty() && end().isEmpty())
 		m_state = NONE;
-	else if (m_startNode == m_endNode && m_startOffset == m_endOffset)
+	else if (start() == end())
 		m_state = CARET;
 	else
 		m_state = RANGE;
@@ -761,7 +581,7 @@ bool Selection::moveToRenderedContent()
     if (m_state != CARET)
         return false;
 
-    Position pos = Position(startNode(), startOffset());
+    Position pos = start();
     if (pos.inRenderedContent())
         return true;
         
@@ -782,26 +602,6 @@ bool Selection::moveToRenderedContent()
     return false;
 }
 
-Position Selection::basePosition() const
-{
-    return Position(baseNode(), baseOffset());
-}
-
-Position Selection::extentPosition() const
-{
-    return Position(extentNode(), extentOffset());
-}
-
-Position Selection::startPosition() const
-{
-    return Position(startNode(), startOffset());
-}
-
-Position Selection::endPosition() const
-{
-    return Position(endNode(), endOffset());
-}
-
 bool Selection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2) 
 {
 	if (!n1 || !n2) 
@@ -815,7 +615,7 @@ bool Selection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2)
     int n2Depth = 0;
 
     // First we find the depths of the two nodes in the tree (n1Depth, n2Depth)
-    DOM::NodeImpl *n = n1;
+    NodeImpl *n = n1;
     while (n->parentNode()) {
         n = n->parentNode();
         n1Depth++;
@@ -914,7 +714,7 @@ static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long
     }
 }
 
-static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, Selection &selection)
+static bool startAndEndLineNodesIncludingNode(NodeImpl *node, int offset, Selection &selection)
 {
     if (node && (node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE)) {
         int pos;
@@ -935,8 +735,8 @@ static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, S
         
         renderNode = renderNode->firstChild();
         
-        DOM::NodeImpl *startNode = 0;
-        DOM::NodeImpl *endNode = 0;
+        NodeImpl *startNode = 0;
+        NodeImpl *endNode = 0;
         long startOffset;
         long endOffset;
         
@@ -950,7 +750,7 @@ static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, S
         if (!lastRunAt (renderNode, selectionPointY, endNode, endOffset))
             return false;
         
-        selection.moveTo(startNode, startOffset, endNode, endOffset);
+        selection.moveTo(Position(startNode, startOffset), Position(endNode, endOffset));
         
         return true;
     }
@@ -975,10 +775,10 @@ void Selection::debugRenderer(RenderObject *r, bool selected) const
         int textLength = text.length();
         if (selected) {
             int offset = 0;
-            if (r->node() == startNode())
-                offset = startOffset();
-            else if (r->node() == endNode())
-                offset = endOffset();
+            if (r->node() == start().node())
+                offset = start().offset();
+            else if (r->node() == end().node())
+                offset = end().offset();
                 
             int pos;
             InlineTextBox *box = textRenderer->findNextInlineTextBox(offset, pos);
@@ -1032,7 +832,7 @@ void Selection::debugRenderer(RenderObject *r, bool selected) const
 
 void Selection::debugPosition() const
 {
-    if (!startNode())
+    if (!start().node())
         return;
 
     //static int context = 5;
@@ -1041,8 +841,8 @@ void Selection::debugPosition() const
 
     fprintf(stderr, "Selection =================\n");
 
-    if (startPosition() == endPosition()) {
-        Position pos = startPosition();
+    if (start() == end()) {
+        Position pos = start();
         Position upstream = pos.equivalentUpstreamPosition();
         Position downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
@@ -1050,14 +850,14 @@ void Selection::debugPosition() const
         fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
     }
     else {
-        Position pos = startPosition();
+        Position pos = start();
         Position upstream = pos.equivalentUpstreamPosition();
         Position downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
         fprintf(stderr, "start:      %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
         fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
         fprintf(stderr, "-----------------------------------\n");
-        pos = endPosition();
+        pos = end();
         upstream = pos.equivalentUpstreamPosition();
         downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
@@ -1068,7 +868,7 @@ void Selection::debugPosition() const
           
 #if 0
     int back = 0;
-    r = startNode()->renderer();
+    r = start().node()->renderer();
     for (int i = 0; i < context; i++, back++) {
         if (r->previousRenderer())
             r = r->previousRenderer();
@@ -1083,15 +883,15 @@ void Selection::debugPosition() const
 
     fprintf(stderr, "\n");
 
-    if (startNode() == endNode())
-        debugRenderer(startNode()->renderer(), true);
+    if (start().node() == end().node())
+        debugRenderer(start().node()->renderer(), true);
     else
-        for (r = startNode()->renderer(); r && r != endNode()->renderer(); r = r->nextRenderer())
+        for (r = start().node()->renderer(); r && r != end().node()->renderer(); r = r->nextRenderer())
             debugRenderer(r, true);
     
     fprintf(stderr, "\n");
     
-    r = endNode()->renderer();
+    r = end().node()->renderer();
     for (int i = 0; i < context; i++) {
         if (r->nextRenderer()) {
             r = r->nextRenderer();
diff --git a/WebCore/khtml/editing/SelectionController.h b/WebCore/khtml/editing/SelectionController.h
index 01fcb1b..1e67737 100644
--- a/WebCore/khtml/editing/SelectionController.h
+++ b/WebCore/khtml/editing/SelectionController.h
@@ -26,6 +26,8 @@
 #ifndef __dom_selection_h__
 #define __dom_selection_h__
 
+#include "xml/dom_position.h"
+
 class KHTMLPart;
 class QPainter;
 class QRect;
@@ -44,12 +46,10 @@ class Selection
 {
 public:
     Selection();
-    Selection(NodeImpl *node, long offset);
     Selection(const Position &);
     Selection(const Position &, const Position &);
-    Selection(NodeImpl *startNode, long startOffset, NodeImpl *endNode, long endOffset);
     Selection(const Selection &);
-    ~Selection();
+    ~Selection() {}
 
 	enum EState { NONE, CARET, RANGE };
 	enum EAlter { MOVE, EXTEND };
@@ -58,36 +58,27 @@ public:
 
 	EState state() const { return m_state; }
 
-    void moveTo(NodeImpl *node, long offset);
     void moveTo(const Range &);
-    void moveTo(const Position &);
     void moveTo(const Selection &);
-    void moveTo(NodeImpl *baseNode, long baseOffset, NodeImpl *extentNode, long extentOffset);
+    void moveTo(const Position &);
+    void moveTo(const Position &, const Position &);
     bool modify(EAlter, EDirection, ETextGranularity);
     bool expandUsingGranularity(ETextGranularity);
     void clear();
 
     bool moveToRenderedContent();
     
-    void setBase(NodeImpl *node, long offset);
-    void setExtent(NodeImpl *node, long offset);
-
-    NodeImpl *baseNode() const { return m_baseNode; }
-    long baseOffset() const { return m_baseOffset; }
-
-    NodeImpl *extentNode() const { return m_extentNode; }
-    long extentOffset() const { return m_extentOffset; }
-
-    NodeImpl *startNode() const { return m_startNode; }
-    long startOffset() const { return m_startOffset; }
-
-    NodeImpl *endNode() const { return m_endNode; }
-    long endOffset() const { return m_endOffset; }
-
-    Position basePosition() const;
-    Position extentPosition() const;
-    Position startPosition() const;
-    Position endPosition() const;
+    void setBase(const Position &pos);
+    void setExtent(const Position &pos);
+    void setBaseAndExtent(const Position &base, const Position &extent);
+    void setStart(const Position &pos);
+    void setEnd(const Position &pos);
+    void setStartAndEnd(const Position &start, const Position &end);
+
+    Position base() const { return m_base; }
+    Position extent() const { return m_extent; }
+    Position start() const { return m_start; }
+    Position end() const { return m_end; }
 
     void setNeedsLayout(bool flag=true);
     void clearModifyBias() { m_modifyBiasSet = false; }
@@ -96,7 +87,6 @@ public:
     bool notEmpty() const { return !isEmpty(); }
     Range toRange() const;
 
-    
     void debugPosition() const;
     void debugRenderer(khtml::RenderObject *r, bool selected) const;
 
@@ -112,53 +102,42 @@ private:
 
     void init();
     void validate(ETextGranularity granularity=CHARACTER);
+    void assignBase(const Position &pos) { m_base = pos; }
+    void assignExtent(const Position &pos) { m_extent = pos; }
+    void assignBaseAndExtent(const Position &base, const Position &extent) { m_base = base; m_extent = extent; }
+    void assignStart(const Position &pos) { m_start = pos; }
+    void assignEnd(const Position &pos) { m_end = pos; }
+    void assignStartAndEnd(const Position &start, const Position &end) { m_start = start; m_end = end; }
 
     void layoutCaret();
     void needsCaretRepaint();
     QRect getRepaintRect();
     void paintCaret(QPainter *p, const QRect &rect);
 
-	void setBaseNode(NodeImpl *);
-	void setBaseOffset(long);
-	void setExtentNode(NodeImpl *);
-	void setExtentOffset(long);
-
-	void setStartNode(NodeImpl *);
-	void setStartOffset(long);
-	void setEndNode(NodeImpl *);
-	void setEndOffset(long);
-
     bool nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2);
-
-    void calculateStartAndEnd(ETextGranularity select=CHARACTER);
     int xPosForVerticalArrowNavigation(EPositionType, bool recalc=false) const;
-    
-    NodeImpl *m_baseNode;    // base node for the selection
-    long m_baseOffset;            // offset into base node where selection is
-    NodeImpl *m_extentNode;  // extent node for the selection
-    long m_extentOffset;          // offset into extent node where selection is
 
-    NodeImpl *m_startNode;   // start node for the selection (read-only)
-    long m_startOffset;           // offset into start node where selection is (read-only)
-    NodeImpl *m_endNode;     // end node for the selection (read-only)
-    long m_endOffset;             // offset into end node where selection is (read-only)
+    Position m_base;              // base position for the selection
+    Position m_extent;            // extent position for the selection
+    Position m_start;             // start position for the selection
+    Position m_end;               // end position for the selection
 
 	EState m_state;               // the state of the selection
 
-	int m_caretX;
+	int m_caretX;                 // caret coordinates and size
 	int m_caretY;
 	int m_caretSize;
 
 	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_modifyBiasSet : 1;     // true if the selection has been modified with EAlter::EXTEND
+	bool m_modifyBiasSet : 1;     // true if the selection has been horizontally 
+                                  // modified with EAlter::EXTEND
 };
 
 
 inline bool operator==(const Selection &a, const Selection &b)
 {
-    return a.startNode() == b.startNode() && a.startOffset() == b.startOffset() &&
-        a.endNode() == b.endNode() && a.endOffset() == b.endOffset();
+    return a.start() == b.start() && a.end() == b.end();
 }
 
 inline bool operator!=(const Selection &a, const Selection &b)
diff --git a/WebCore/khtml/editing/htmlediting_impl.cpp b/WebCore/khtml/editing/htmlediting_impl.cpp
index 9aea952..86ff634 100644
--- a/WebCore/khtml/editing/htmlediting_impl.cpp
+++ b/WebCore/khtml/editing/htmlediting_impl.cpp
@@ -726,14 +726,14 @@ void DeleteCollapsibleWhitespaceCommandImpl::doApply()
 {
     int state = m_selectionToCollapse.state();
     if (state == Selection::CARET) {
-        Position endPosition = deleteWhitespace(m_selectionToCollapse.startPosition());
+        Position endPosition = deleteWhitespace(m_selectionToCollapse.start());
         setEndingSelection(endPosition);
         LOG(Editing, "-----------------------------------------------------\n");
     }
     else if (state == Selection::RANGE) {
-        Position startPosition = deleteWhitespace(m_selectionToCollapse.startPosition());
+        Position startPosition = deleteWhitespace(m_selectionToCollapse.start());
         LOG(Editing, "-----------------------------------------------------\n");
-        Position endPosition = m_selectionToCollapse.endPosition();
+        Position endPosition = m_selectionToCollapse.end();
         if (m_charactersDeleted > 0 && startPosition.node() == endPosition.node()) {
             LOG(Editing, "adjust end position by %d\n", m_charactersDeleted);
             endPosition = Position(endPosition.node(), endPosition.offset() - m_charactersDeleted);
@@ -775,7 +775,7 @@ void DeleteSelectionCommandImpl::joinTextNodesWithSameStyle()
     if (selection.state() != Selection::CARET)
         return;
 
-    Position pos = selection.startPosition();
+    Position pos(selection.start());
     
     if (!pos.node()->isTextNode())
         return;
@@ -844,10 +844,10 @@ void DeleteSelectionCommandImpl::doApply()
     Position endingPosition;
     bool adjustEndingPositionDownstream = false;
 
-    Position upstreamStart = selection.startPosition().equivalentUpstreamPosition();
-    Position downstreamStart = selection.startPosition().equivalentDownstreamPosition();
-    Position upstreamEnd = selection.endPosition().equivalentUpstreamPosition();
-    Position downstreamEnd = selection.endPosition().equivalentDownstreamPosition();
+    Position upstreamStart(selection.start().equivalentUpstreamPosition());
+    Position downstreamStart(selection.start().equivalentDownstreamPosition());
+    Position upstreamEnd(selection.end().equivalentUpstreamPosition());
+    Position downstreamEnd(selection.end().equivalentDownstreamPosition());
 
     bool onlyWhitespace = containsOnlyWhitespace(upstreamStart, downstreamEnd);
  
@@ -1081,7 +1081,7 @@ void InputNewlineCommandImpl::doApply()
     ElementImpl *breakNode = document()->createHTMLElement("BR", exceptionCode);
     ASSERT(exceptionCode == 0);
 
-    Position pos = selection.startPosition().equivalentDownstreamPosition();
+    Position pos(selection.start().equivalentDownstreamPosition());
     bool atEnd = pos.offset() >= pos.node()->caretMaxOffset();
     bool atStart = pos.offset() <= pos.node()->caretMinOffset();
     bool atEndOfBlock = pos.isLastRenderedPositionInEditableBlock();
@@ -1110,8 +1110,8 @@ void InputNewlineCommandImpl::doApply()
         LOG(Editing, "input newline case 4");
         ASSERT(pos.node()->isTextNode());
         TextImpl *textNode = static_cast<TextImpl *>(pos.node());
-        TextImpl *textBeforeNode = document()->createTextNode(textNode->substringData(0, selection.startOffset(), exceptionCode));
-        deleteText(textNode, 0, selection.startOffset());
+        TextImpl *textBeforeNode = document()->createTextNode(textNode->substringData(0, selection.start().offset(), exceptionCode));
+        deleteText(textNode, 0, selection.start().offset());
         insertNodeBefore(textBeforeNode, textNode);
         insertNodeBefore(breakNode, textNode);
         textBeforeNode->deref();
@@ -1155,16 +1155,16 @@ void InputTextCommandImpl::deleteCharacter()
 
     Selection selection = endingSelection();
 
-    if (!selection.startNode()->isTextNode())
+    if (!selection.start().node()->isTextNode())
         return;
 
     int exceptionCode = 0;
-    int offset = selection.startOffset() - 1;
-    if (offset >= selection.startNode()->caretMinOffset()) {
-        TextImpl *textNode = static_cast<TextImpl *>(selection.startNode());
+    int offset = selection.start().offset() - 1;
+    if (offset >= selection.start().node()->caretMinOffset()) {
+        TextImpl *textNode = static_cast<TextImpl *>(selection.start().node());
         textNode->deleteData(offset, 1, exceptionCode);
         ASSERT(exceptionCode == 0);
-        selection = Selection(textNode, offset);
+        selection = Selection(Position(textNode, offset));
         setEndingSelection(selection);
         m_charactersAdded--;
     }
@@ -1177,7 +1177,7 @@ Position InputTextCommandImpl::prepareForTextInsertion(bool adjustDownstream)
     Selection selection = endingSelection();
     ASSERT(selection.state() == Selection::CARET);
     
-    Position pos = selection.startPosition();
+    Position pos = selection.start();
     if (adjustDownstream)
         pos = pos.equivalentDownstreamPosition();
     else
@@ -1217,7 +1217,7 @@ Position InputTextCommandImpl::prepareForTextInsertion(bool adjustDownstream)
 void InputTextCommandImpl::execute(const DOMString &text)
 {
     Selection selection = endingSelection();
-    bool adjustDownstream = selection.startPosition().isFirstRenderedPositionOnLine();
+    bool adjustDownstream = selection.start().isFirstRenderedPositionOnLine();
 
     // Delete the current selection, or collapse whitespace, as needed
     if (selection.state() == Selection::RANGE)
@@ -1507,7 +1507,7 @@ void PasteMarkupCommandImpl::doApply()
         NodeImpl *beforeNode = firstChild;
         NodeImpl *node = firstChild->nextSibling();
 
-        insertNodeAt(firstChild, selection.startNode(), selection.startOffset());
+        insertNodeAt(firstChild, selection.start().node(), selection.start().offset());
         
         // Insert the nodes from the fragment
         while (node) {
@@ -1755,7 +1755,7 @@ void TypingCommandImpl::issueCommandForDeleteKey()
     ASSERT(selectionToDelete.state() != Selection::NONE);
     
     if (selectionToDelete.state() == Selection::CARET)
-        selectionToDelete = Selection(selectionToDelete.startPosition().previousCharacterPosition(), selectionToDelete.startPosition());
+        selectionToDelete = Selection(selectionToDelete.start().previousCharacterPosition(), selectionToDelete.start());
     deleteSelection(selectionToDelete);
 }
 
diff --git a/WebCore/khtml/editing/selection.cpp b/WebCore/khtml/editing/selection.cpp
index e59b11f..1ae3586 100644
--- a/WebCore/khtml/editing/selection.cpp
+++ b/WebCore/khtml/editing/selection.cpp
@@ -33,7 +33,6 @@
 #include "qrect.h"
 #include "dom/dom2_range.h"
 #include "dom/dom_node.h"
-#include "dom/dom_position.h"
 #include "dom/dom_string.h"
 #include "rendering/render_object.h"
 #include "rendering/render_style.h"
@@ -52,69 +51,40 @@
 #define EDIT_DEBUG 0
 #endif
 
-namespace DOM {
-
 using khtml::InlineTextBox;
 using khtml::RenderObject;
 using khtml::RenderText;
 
+namespace DOM {
+
 #if APPLE_CHANGES
 static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset);
 static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset);
-static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, Selection &selection);
+static bool startAndEndLineNodesIncludingNode(NodeImpl *node, int offset, Selection &selection);
 #endif
 
-
-Selection::Selection()
+static inline Position &emptyPosition()
 {
-    init();
+    static Position EmptyPosition = Position();
+    return EmptyPosition;
 }
 
-Selection::Selection(NodeImpl *node, long offset)
+Selection::Selection()
 {
     init();
-
-	setBaseNode(node);
-	setExtentNode(node);
-	setBaseOffset(offset);
-	setExtentOffset(offset);
-
-    validate();
 }
 
 Selection::Selection(const Position &pos)
 {
     init();
-
-	setBaseNode(pos.node());
-	setExtentNode(pos.node());
-	setBaseOffset(pos.offset());
-	setExtentOffset(pos.offset());
-
+	assignBaseAndExtent(pos, pos);
     validate();
 }
 
 Selection::Selection(const Position &base, const Position &extent)
 {
     init();
-
-	setBaseNode(base.node());
-	setExtentNode(extent.node());
-	setBaseOffset(base.offset());
-	setExtentOffset(extent.offset());
-
-    validate();
-}
-
-Selection::Selection(NodeImpl *baseNode, long baseOffset, NodeImpl *endNode, long endOffset)
-{
-    init();
-
-	setBaseNode(baseNode);
-	setExtentNode(endNode);
-	setBaseOffset(baseOffset);
-	setExtentOffset(endOffset);
-
+	assignBaseAndExtent(base, extent);
     validate();
 }
 
@@ -122,15 +92,8 @@ Selection::Selection(const Selection &o)
 {
     init();
     
-	setBaseNode(o.baseNode());
-	setExtentNode(o.extentNode());
-	setBaseOffset(o.baseOffset());
-	setExtentOffset(o.extentOffset());
-
-	setStartNode(o.startNode());
-	setEndNode(o.endNode());
-	setStartOffset(o.startOffset());
-	setEndOffset(o.endOffset());
+	assignBaseAndExtent(o.base(), o.extent());
+	assignStartAndEnd(o.start(), o.end());
 
     m_state = o.m_state;
 
@@ -152,14 +115,7 @@ Selection::Selection(const Selection &o)
 
 void Selection::init()
 {
-    m_baseNode = 0;
-    m_baseOffset = 0;
-    m_extentNode = 0; 
-    m_extentOffset = 0;
-    m_startNode = 0;
-    m_startOffset = 0;
-    m_endNode = 0;
-    m_endOffset = 0;
+    m_base = m_extent = m_start = m_end = emptyPosition();
     m_state = NONE; 
     m_caretX = 0;
     m_caretY = 0;
@@ -169,29 +125,10 @@ void Selection::init()
     m_modifyBiasSet = false;
 }
 
-Selection::~Selection()
-{
-    if (m_baseNode)
-        m_baseNode->deref();
-    if (m_extentNode)
-        m_extentNode->deref();
-    if (m_startNode)
-        m_startNode->deref();
-    if (m_endNode)
-        m_endNode->deref();
-}
-
 Selection &Selection::operator=(const Selection &o)
 {
-	setBaseNode(o.baseNode());
-	setExtentNode(o.extentNode());
-	setBaseOffset(o.baseOffset());
-	setExtentOffset(o.extentOffset());
-
-	setStartNode(o.startNode());
-	setEndNode(o.endNode());
-	setStartOffset(o.startOffset());
-	setEndOffset(o.endOffset());
+	assignBaseAndExtent(o.base(), o.extent());
+	assignStartAndEnd(o.start(), o.end());
 
     m_state = o.m_state;
 
@@ -213,34 +150,27 @@ Selection &Selection::operator=(const Selection &o)
     return *this;
 }
 
-void Selection::moveTo(DOM::NodeImpl *node, long offset)
+void Selection::moveTo(const Range &r)
 {
-    moveTo(node, offset, node, offset);
+    Position start(r.startContainer().handle(), r.startOffset());
+    Position end(r.endContainer().handle(), r.endOffset());
+	moveTo(start, end);
 }
 
-void Selection::moveTo(const DOM::Range &r)
-{
-	moveTo(r.startContainer().handle(), r.startOffset(), 
-		r.endContainer().handle(), r.endOffset());
-}
-
-void Selection::moveTo(const DOM::Position &pos)
+void Selection::moveTo(const Selection &o)
 {
-	moveTo(pos.node(), pos.offset());
+	moveTo(o.start(), o.end());
 }
 
-void Selection::moveTo(const Selection &o)
+void Selection::moveTo(const Position &pos)
 {
-	moveTo(o.baseNode(), o.baseOffset(), o.extentNode(), o.extentOffset());
+	moveTo(pos, pos);
 }
 
-void Selection::moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeImpl *extentNode, long extentOffset)
+void Selection::moveTo(const Position &base, const Position &extent)
 {
-	setBaseNode(baseNode);
-	setExtentNode(extentNode);
-	setBaseOffset(baseOffset);
-	setExtentOffset(extentOffset);
-	validate();
+	assignBaseAndExtent(base, extent);
+    validate();
 }
 
 bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
@@ -254,29 +184,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(startNode());
-                    setBaseOffset(startOffset());
-                    setExtentNode(endNode());
-                    setExtentOffset(endOffset());
+                    assignBaseAndExtent(start(), end());
                 }
                 if (granularity == CHARACTER)
-                    pos = extentPosition().nextCharacterPosition();
+                    pos = extent().nextCharacterPosition();
                 else if (granularity == WORD)
-                    pos = extentPosition().nextWordPosition();
+                    pos = extent().nextWordPosition();
             }
             else {
                 m_modifyBiasSet = false;
                 if (state() == RANGE) {
                     if (granularity == CHARACTER)
-                        pos = endPosition();
+                        pos = end();
                     else if (granularity == WORD)
-                        pos = extentPosition().nextWordPosition();
+                        pos = extent().nextWordPosition();
                 }
                 else {
                     if (granularity == CHARACTER)
-                        pos = extentPosition().nextCharacterPosition();
+                        pos = extent().nextCharacterPosition();
                     else if (granularity == WORD)
-                        pos = extentPosition().nextWordPosition();
+                        pos = extent().nextWordPosition();
                 }
             }
             break;
@@ -286,29 +213,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(endNode());
-                    setBaseOffset(endOffset());
-                    setExtentNode(startNode());
-                    setExtentOffset(startOffset());
+                    assignBaseAndExtent(end(), start());
                 }
                 if (granularity == CHARACTER)
-                    pos = extentPosition().previousCharacterPosition();
+                    pos = extent().previousCharacterPosition();
                 else if (granularity == WORD)
-                    pos = extentPosition().previousWordPosition();
+                    pos = extent().previousWordPosition();
             }
             else {
                 m_modifyBiasSet = false;
                 if (state() == RANGE) {
                     if (granularity == CHARACTER)
-                        pos = startPosition();
+                        pos = start();
                     else if (granularity == WORD)
-                        pos = extentPosition().previousWordPosition();
+                        pos = extent().previousWordPosition();
                 }
                 else {
                     if (granularity == CHARACTER)
-                        pos = extentPosition().previousCharacterPosition();
+                        pos = extent().previousCharacterPosition();
                     else if (granularity == WORD)
-                        pos = extentPosition().previousWordPosition();
+                        pos = extent().previousWordPosition();
                 }
             }
             break;
@@ -316,32 +240,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(endNode());
-                    setBaseOffset(endOffset());
-                    setExtentNode(startNode());
-                    setExtentOffset(startOffset());
+                    assignBaseAndExtent(end(), start());
                 }
-                pos = extentPosition().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+                pos = extent().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
             }
             else {
                 m_modifyBiasSet = false;
-                pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
+                pos = start().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
             }
             break;
         case DOWN:
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(startNode());
-                    setBaseOffset(startOffset());
-                    setExtentNode(endNode());
-                    setExtentOffset(endOffset());
+                    assignBaseAndExtent(start(), end());
                 }
-                pos = extentPosition().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+                pos = extent().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
             }
             else {
                 m_modifyBiasSet = false;
-                pos = endPosition().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
+                pos = end().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
             }
             break;
     }
@@ -350,9 +268,9 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
         return false;
     
     if (alter == MOVE)
-        moveTo(pos.node(), pos.offset());
+        moveTo(pos);
     else // alter == EXTEND
-        setExtent(pos.node(), pos.offset());
+        setExtent(pos);
     
     return true;
 }
@@ -376,16 +294,16 @@ int Selection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) c
     Position pos;
     switch (type) {
         case START:
-            pos = startPosition();
+            pos = start();
             break;
         case END:
-            pos = endPosition();
+            pos = end();
             break;
         case BASE:
-            pos = basePosition();
+            pos = base();
             break;
         case EXTENT:
-            pos = extentPosition();
+            pos = extent();
             break;
     }
 
@@ -407,25 +325,44 @@ int Selection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) c
 
 void Selection::clear()
 {
-	setBaseNode(0);
-	setExtentNode(0);
-	setBaseOffset(0);
-	setExtentOffset(0);
+	assignBaseAndExtent(emptyPosition(), emptyPosition());
 	validate();
 }
 
-void Selection::setBase(DOM::NodeImpl *node, long offset)
+void Selection::setBase(const Position &pos)
 {
-	setBaseNode(node);
-	setBaseOffset(offset);
-	validate();
+    assignBase(pos);
+    validate();
 }
 
-void Selection::setExtent(DOM::NodeImpl *node, long offset)
+void Selection::setExtent(const Position &pos)
 {
-	setExtentNode(node);
-	setExtentOffset(offset);
-	validate();
+    assignExtent(pos);
+    validate();
+}
+
+void Selection::setBaseAndExtent(const Position &base, const Position &extent)
+{
+    assignBaseAndExtent(base, extent);
+    validate();
+}
+
+void Selection::setStart(const Position &pos)
+{
+    assignStart(pos);
+    validate();
+}
+
+void Selection::setEnd(const Position &pos)
+{
+    assignEnd(pos);
+    validate();
+}
+
+void Selection::setStartAndEnd(const Position &start, const Position &end)
+{
+    assignStartAndEnd(start, end);
+    validate();
 }
 
 void Selection::setNeedsLayout(bool flag)
@@ -438,17 +375,17 @@ Range Selection::toRange() const
     if (isEmpty())
         return Range();
 
-    return Range(Node(startNode()), startOffset(), Node(endNode()), endOffset());
+    return Range(Node(start().node()), start().offset(), Node(end().node()), end().offset());
 }
 
 void Selection::layoutCaret()
 {
-    if (isEmpty() || !startNode()->renderer()) {
+    if (isEmpty() || !start().node()->renderer()) {
         m_caretX = m_caretY = m_caretSize = 0;
     }
     else {
         int w;
-        startNode()->renderer()->caretPos(startOffset(), true, m_caretX, m_caretY, w, m_caretSize);
+        start().node()->renderer()->caretPos(start().offset(), true, m_caretX, m_caretY, w, m_caretSize);
     }
 
     m_needsCaretLayout = false;
@@ -465,10 +402,10 @@ void Selection::needsCaretRepaint()
     if (isEmpty())
         return;
 
-    if (!startNode()->getDocument())
+    if (!start().node()->getDocument())
         return;
 
-    KHTMLView *v = startNode()->getDocument()->view();
+    KHTMLView *v = start().node()->getDocument()->view();
     if (!v)
         return;
 
@@ -502,7 +439,7 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
         return;
 
     if (m_needsCaretLayout) {
-        Position pos = Position(startNode(), startOffset());
+        Position pos = start();
         if (!pos.inRenderedContent()) {
             moveToRenderedContent();
         }
@@ -520,126 +457,37 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
     }
 }
 
-void Selection::setBaseNode(DOM::NodeImpl *node)
-{
-	if (m_baseNode == node)
-		return;
-
-	if (m_baseNode)
-		m_baseNode->deref();
-	
-	m_baseNode = node;
-	
-	if (m_baseNode)
-		m_baseNode->ref();
-}
-
-void Selection::setBaseOffset(long offset)
-{
-	m_baseOffset = offset;
-}
-
-void Selection::setExtentNode(DOM::NodeImpl *node)
-{
-	if (m_extentNode == node)
-		return;
-
-	if (m_extentNode)
-		m_extentNode->deref();
-	
-	m_extentNode = node;
-	
-	if (m_extentNode)
-		m_extentNode->ref();
-}
-	
-void Selection::setExtentOffset(long offset)
-{
-	m_extentOffset = offset;
-}
-
-void Selection::setStartNode(DOM::NodeImpl *node)
-{
-	if (m_startNode == node)
-		return;
-
-	if (m_startNode)
-		m_startNode->deref();
-	
-	m_startNode = node;
-	
-	if (m_startNode)
-		m_startNode->ref();
-}
-
-void Selection::setStartOffset(long offset)
-{
-	m_startOffset = offset;
-}
-
-void Selection::setEndNode(DOM::NodeImpl *node)
-{
-	if (m_endNode == node)
-		return;
-
-	if (m_endNode)
-		m_endNode->deref();
-	
-	m_endNode = node;
-	
-	if (m_endNode)
-		m_endNode->ref();
-}
-	
-void Selection::setEndOffset(long offset)
-{
-	m_endOffset = offset;
-}
-
 void Selection::validate(ETextGranularity granularity)
 {
     // move the base and extent nodes to their equivalent leaf positions
-    bool baseAndExtentEqual = m_baseNode == m_extentNode && m_baseOffset == m_extentOffset;
-    if (m_baseNode) {
-        Position pos = basePosition().equivalentLeafPosition();
-        m_baseNode = pos.node();
-        m_baseOffset = pos.offset();
-        if (baseAndExtentEqual) {
-            m_extentNode = pos.node();
-            m_extentOffset = pos.offset();
-        }
+    bool baseAndExtentEqual = base() == extent();
+    if (base().notEmpty()) {
+        Position pos = base().equivalentLeafPosition();
+        assignBase(pos);
+        if (baseAndExtentEqual)
+            assignExtent(pos);
     }
-    if (m_extentNode && !baseAndExtentEqual) {
-        Position pos = extentPosition().equivalentLeafPosition();
-        m_extentNode = pos.node();
-        m_extentOffset = pos.offset();
+    if (extent().notEmpty() && !baseAndExtentEqual) {
+        assignExtent(extent().equivalentLeafPosition());
     }
 
     // make sure we do not have a dangling start or end
-	if (!m_baseNode && !m_extentNode) {
-        setBaseOffset(0);
-        setExtentOffset(0);
+	if (base().isEmpty() && extent().isEmpty()) {
+        assignStartAndEnd(emptyPosition(), emptyPosition());
         m_baseIsStart = true;
     }
-	else if (!m_baseNode) {
-		setBaseNode(m_extentNode);
-		setBaseOffset(m_extentOffset);
-        m_baseIsStart = true;
-	}
-	else if (!m_extentNode) {
-		setExtentNode(m_baseNode);
-		setExtentOffset(m_baseOffset);
+	else if (base().isEmpty() || extent().isEmpty()) {
         m_baseIsStart = true;
 	}
     else {
         // adjust m_baseIsStart as needed
-        if (m_baseNode == m_extentNode) {
-            if (m_baseOffset > m_extentOffset)
+        if (base().node() == extent().node()) {
+            if (base().offset() > extent().offset())
                 m_baseIsStart = false;
             else 
                 m_baseIsStart = true;
         }
-        else if (nodeIsBeforeNode(m_baseNode, m_extentNode))
+        else if (nodeIsBeforeNode(base().node(), extent().node()))
             m_baseIsStart = true;
         else
             m_baseIsStart = false;
@@ -647,101 +495,73 @@ void Selection::validate(ETextGranularity granularity)
 
     // calculate the correct start and end positions
 #if !APPLE_CHANGES
-    if (m_baseIsStart) {
-        setStartNode(m_baseNode);
-        setStartOffset(m_baseOffset);
-        setEndNode(m_extentNode);
-        setEndOffset(m_extentOffset);
-    }
-    else {
-        setStartNode(m_extentNode);
-        setStartOffset(m_extentOffset);
-        setEndNode(m_baseNode);
-        setEndOffset(m_baseOffset);
-    }
+    if (m_baseIsStart)
+        assignStartAndEnd(base(), extent());
+    else
+        assignStartAndEnd(extent(), base());
 #else
     if (granularity == CHARACTER) {
-        if (m_baseIsStart) {
-            setStartNode(m_baseNode);
-            setStartOffset(m_baseOffset);
-            setEndNode(m_extentNode);
-            setEndOffset(m_extentOffset);
-        }
-        else {
-            setStartNode(m_extentNode);
-            setStartOffset(m_extentOffset);
-            setEndNode(m_baseNode);
-            setEndOffset(m_baseOffset);
-        }
+        if (m_baseIsStart)
+            assignStartAndEnd(base(), extent());
+        else
+            assignStartAndEnd(extent(), base());
     }
     else if (granularity == WORD) {
-        int baseStartOffset = m_baseOffset;
-        int baseEndOffset = m_baseOffset;
-        int extentStartOffset = m_extentOffset;
-        int extentEndOffset = m_extentOffset;
-        if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            DOMString t = m_baseNode->nodeValue();
+        int baseStartOffset = base().offset();
+        int baseEndOffset = base().offset();
+        int extentStartOffset = extent().offset();
+        int extentEndOffset = extent().offset();
+        if (base().notEmpty() && (base().node()->nodeType() == Node::TEXT_NODE || base().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            DOMString t = base().node()->nodeValue();
             QChar *chars = t.unicode();
             uint len = t.length();
-            KWQFindWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
+            KWQFindWordBoundary(chars, len, base().offset(), &baseStartOffset, &baseEndOffset);
         }
-        if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            DOMString t = m_extentNode->nodeValue();
+        if (extent().notEmpty() && (extent().node()->nodeType() == Node::TEXT_NODE || extent().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            DOMString t = extent().node()->nodeValue();
             QChar *chars = t.unicode();
             uint len = t.length();
-            KWQFindWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
+            KWQFindWordBoundary(chars, len, extent().offset(), &extentStartOffset, &extentEndOffset);
         }
         if (m_baseIsStart) {
-            setStartNode(m_baseNode);
-            setStartOffset(baseStartOffset);
-            setEndNode(m_extentNode);
-            setEndOffset(extentEndOffset);
+            assignStart(Position(base().node(), baseStartOffset));
+            assignEnd(Position(extent().node(), extentEndOffset));
         }
         else {
-            setStartNode(m_extentNode);
-            setStartOffset(extentStartOffset);
-            setEndNode(m_baseNode);
-            setEndOffset(baseEndOffset);
+            assignStart(Position(extent().node(), extentStartOffset));
+            assignEnd(Position(base().node(), baseEndOffset));
         }
     }
-    else {  // granularity == LINE
+    else {  // granularity == LINE 
         Selection baseSelection = *this;
         Selection extentSelection = *this;
-        if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            if (startAndEndLineNodesIncludingNode(m_baseNode, m_baseOffset, baseSelection)) {
-                setStartNode(baseSelection.baseNode());
-                setStartOffset(baseSelection.baseOffset());
-                setEndNode(baseSelection.extentNode());
-                setEndOffset(baseSelection.extentOffset());
+        if (base().notEmpty() && (base().node()->nodeType() == Node::TEXT_NODE || base().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            if (startAndEndLineNodesIncludingNode(base().node(), base().offset(), baseSelection)) {
+                assignStart(Position(baseSelection.base().node(), baseSelection.base().offset()));
+                assignEnd(Position(baseSelection.extent().node(), baseSelection.extent().offset()));
             }
         }
-        if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            if (startAndEndLineNodesIncludingNode(m_extentNode, m_extentOffset, extentSelection)) {
-                setStartNode(extentSelection.baseNode());
-                setStartOffset(extentSelection.baseOffset());
-                setEndNode(extentSelection.extentNode());
-                setEndOffset(extentSelection.extentOffset());
+        if (extent().notEmpty() && (extent().node()->nodeType() == Node::TEXT_NODE || extent().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            if (startAndEndLineNodesIncludingNode(extent().node(), extent().offset(), extentSelection)) {
+                assignStart(Position(extentSelection.base().node(), extentSelection.base().offset()));
+                assignEnd(Position(extentSelection.extent().node(), extentSelection.extent().offset()));
             }
         }
         if (m_baseIsStart) {
-            setStartNode(baseSelection.startNode());
-            setStartOffset(baseSelection.startOffset());
-            setEndNode(extentSelection.endNode());
-            setEndOffset(extentSelection.endOffset());
+            assignStart(baseSelection.start());
+            assignEnd(extentSelection.end());
         }
         else {
-            setStartNode(extentSelection.startNode());
-            setStartOffset(extentSelection.startOffset());
-            setEndNode(baseSelection.endNode());
-            setEndOffset(baseSelection.endOffset());
+            assignStart(extentSelection.start());
+            assignEnd(baseSelection.end());
         }
     }
 #endif  // APPLE_CHANGES
 
 	// adjust the state
-	if (!m_startNode && !m_endNode)
+	if (start().isEmpty() && end().isEmpty())
 		m_state = NONE;
-	else if (m_startNode == m_endNode && m_startOffset == m_endOffset)
+	else if (start() == end())
 		m_state = CARET;
 	else
 		m_state = RANGE;
@@ -761,7 +581,7 @@ bool Selection::moveToRenderedContent()
     if (m_state != CARET)
         return false;
 
-    Position pos = Position(startNode(), startOffset());
+    Position pos = start();
     if (pos.inRenderedContent())
         return true;
         
@@ -782,26 +602,6 @@ bool Selection::moveToRenderedContent()
     return false;
 }
 
-Position Selection::basePosition() const
-{
-    return Position(baseNode(), baseOffset());
-}
-
-Position Selection::extentPosition() const
-{
-    return Position(extentNode(), extentOffset());
-}
-
-Position Selection::startPosition() const
-{
-    return Position(startNode(), startOffset());
-}
-
-Position Selection::endPosition() const
-{
-    return Position(endNode(), endOffset());
-}
-
 bool Selection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2) 
 {
 	if (!n1 || !n2) 
@@ -815,7 +615,7 @@ bool Selection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2)
     int n2Depth = 0;
 
     // First we find the depths of the two nodes in the tree (n1Depth, n2Depth)
-    DOM::NodeImpl *n = n1;
+    NodeImpl *n = n1;
     while (n->parentNode()) {
         n = n->parentNode();
         n1Depth++;
@@ -914,7 +714,7 @@ static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long
     }
 }
 
-static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, Selection &selection)
+static bool startAndEndLineNodesIncludingNode(NodeImpl *node, int offset, Selection &selection)
 {
     if (node && (node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE)) {
         int pos;
@@ -935,8 +735,8 @@ static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, S
         
         renderNode = renderNode->firstChild();
         
-        DOM::NodeImpl *startNode = 0;
-        DOM::NodeImpl *endNode = 0;
+        NodeImpl *startNode = 0;
+        NodeImpl *endNode = 0;
         long startOffset;
         long endOffset;
         
@@ -950,7 +750,7 @@ static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, S
         if (!lastRunAt (renderNode, selectionPointY, endNode, endOffset))
             return false;
         
-        selection.moveTo(startNode, startOffset, endNode, endOffset);
+        selection.moveTo(Position(startNode, startOffset), Position(endNode, endOffset));
         
         return true;
     }
@@ -975,10 +775,10 @@ void Selection::debugRenderer(RenderObject *r, bool selected) const
         int textLength = text.length();
         if (selected) {
             int offset = 0;
-            if (r->node() == startNode())
-                offset = startOffset();
-            else if (r->node() == endNode())
-                offset = endOffset();
+            if (r->node() == start().node())
+                offset = start().offset();
+            else if (r->node() == end().node())
+                offset = end().offset();
                 
             int pos;
             InlineTextBox *box = textRenderer->findNextInlineTextBox(offset, pos);
@@ -1032,7 +832,7 @@ void Selection::debugRenderer(RenderObject *r, bool selected) const
 
 void Selection::debugPosition() const
 {
-    if (!startNode())
+    if (!start().node())
         return;
 
     //static int context = 5;
@@ -1041,8 +841,8 @@ void Selection::debugPosition() const
 
     fprintf(stderr, "Selection =================\n");
 
-    if (startPosition() == endPosition()) {
-        Position pos = startPosition();
+    if (start() == end()) {
+        Position pos = start();
         Position upstream = pos.equivalentUpstreamPosition();
         Position downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
@@ -1050,14 +850,14 @@ void Selection::debugPosition() const
         fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
     }
     else {
-        Position pos = startPosition();
+        Position pos = start();
         Position upstream = pos.equivalentUpstreamPosition();
         Position downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
         fprintf(stderr, "start:      %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
         fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
         fprintf(stderr, "-----------------------------------\n");
-        pos = endPosition();
+        pos = end();
         upstream = pos.equivalentUpstreamPosition();
         downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
@@ -1068,7 +868,7 @@ void Selection::debugPosition() const
           
 #if 0
     int back = 0;
-    r = startNode()->renderer();
+    r = start().node()->renderer();
     for (int i = 0; i < context; i++, back++) {
         if (r->previousRenderer())
             r = r->previousRenderer();
@@ -1083,15 +883,15 @@ void Selection::debugPosition() const
 
     fprintf(stderr, "\n");
 
-    if (startNode() == endNode())
-        debugRenderer(startNode()->renderer(), true);
+    if (start().node() == end().node())
+        debugRenderer(start().node()->renderer(), true);
     else
-        for (r = startNode()->renderer(); r && r != endNode()->renderer(); r = r->nextRenderer())
+        for (r = start().node()->renderer(); r && r != end().node()->renderer(); r = r->nextRenderer())
             debugRenderer(r, true);
     
     fprintf(stderr, "\n");
     
-    r = endNode()->renderer();
+    r = end().node()->renderer();
     for (int i = 0; i < context; i++) {
         if (r->nextRenderer()) {
             r = r->nextRenderer();
diff --git a/WebCore/khtml/editing/selection.h b/WebCore/khtml/editing/selection.h
index 01fcb1b..1e67737 100644
--- a/WebCore/khtml/editing/selection.h
+++ b/WebCore/khtml/editing/selection.h
@@ -26,6 +26,8 @@
 #ifndef __dom_selection_h__
 #define __dom_selection_h__
 
+#include "xml/dom_position.h"
+
 class KHTMLPart;
 class QPainter;
 class QRect;
@@ -44,12 +46,10 @@ class Selection
 {
 public:
     Selection();
-    Selection(NodeImpl *node, long offset);
     Selection(const Position &);
     Selection(const Position &, const Position &);
-    Selection(NodeImpl *startNode, long startOffset, NodeImpl *endNode, long endOffset);
     Selection(const Selection &);
-    ~Selection();
+    ~Selection() {}
 
 	enum EState { NONE, CARET, RANGE };
 	enum EAlter { MOVE, EXTEND };
@@ -58,36 +58,27 @@ public:
 
 	EState state() const { return m_state; }
 
-    void moveTo(NodeImpl *node, long offset);
     void moveTo(const Range &);
-    void moveTo(const Position &);
     void moveTo(const Selection &);
-    void moveTo(NodeImpl *baseNode, long baseOffset, NodeImpl *extentNode, long extentOffset);
+    void moveTo(const Position &);
+    void moveTo(const Position &, const Position &);
     bool modify(EAlter, EDirection, ETextGranularity);
     bool expandUsingGranularity(ETextGranularity);
     void clear();
 
     bool moveToRenderedContent();
     
-    void setBase(NodeImpl *node, long offset);
-    void setExtent(NodeImpl *node, long offset);
-
-    NodeImpl *baseNode() const { return m_baseNode; }
-    long baseOffset() const { return m_baseOffset; }
-
-    NodeImpl *extentNode() const { return m_extentNode; }
-    long extentOffset() const { return m_extentOffset; }
-
-    NodeImpl *startNode() const { return m_startNode; }
-    long startOffset() const { return m_startOffset; }
-
-    NodeImpl *endNode() const { return m_endNode; }
-    long endOffset() const { return m_endOffset; }
-
-    Position basePosition() const;
-    Position extentPosition() const;
-    Position startPosition() const;
-    Position endPosition() const;
+    void setBase(const Position &pos);
+    void setExtent(const Position &pos);
+    void setBaseAndExtent(const Position &base, const Position &extent);
+    void setStart(const Position &pos);
+    void setEnd(const Position &pos);
+    void setStartAndEnd(const Position &start, const Position &end);
+
+    Position base() const { return m_base; }
+    Position extent() const { return m_extent; }
+    Position start() const { return m_start; }
+    Position end() const { return m_end; }
 
     void setNeedsLayout(bool flag=true);
     void clearModifyBias() { m_modifyBiasSet = false; }
@@ -96,7 +87,6 @@ public:
     bool notEmpty() const { return !isEmpty(); }
     Range toRange() const;
 
-    
     void debugPosition() const;
     void debugRenderer(khtml::RenderObject *r, bool selected) const;
 
@@ -112,53 +102,42 @@ private:
 
     void init();
     void validate(ETextGranularity granularity=CHARACTER);
+    void assignBase(const Position &pos) { m_base = pos; }
+    void assignExtent(const Position &pos) { m_extent = pos; }
+    void assignBaseAndExtent(const Position &base, const Position &extent) { m_base = base; m_extent = extent; }
+    void assignStart(const Position &pos) { m_start = pos; }
+    void assignEnd(const Position &pos) { m_end = pos; }
+    void assignStartAndEnd(const Position &start, const Position &end) { m_start = start; m_end = end; }
 
     void layoutCaret();
     void needsCaretRepaint();
     QRect getRepaintRect();
     void paintCaret(QPainter *p, const QRect &rect);
 
-	void setBaseNode(NodeImpl *);
-	void setBaseOffset(long);
-	void setExtentNode(NodeImpl *);
-	void setExtentOffset(long);
-
-	void setStartNode(NodeImpl *);
-	void setStartOffset(long);
-	void setEndNode(NodeImpl *);
-	void setEndOffset(long);
-
     bool nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2);
-
-    void calculateStartAndEnd(ETextGranularity select=CHARACTER);
     int xPosForVerticalArrowNavigation(EPositionType, bool recalc=false) const;
-    
-    NodeImpl *m_baseNode;    // base node for the selection
-    long m_baseOffset;            // offset into base node where selection is
-    NodeImpl *m_extentNode;  // extent node for the selection
-    long m_extentOffset;          // offset into extent node where selection is
 
-    NodeImpl *m_startNode;   // start node for the selection (read-only)
-    long m_startOffset;           // offset into start node where selection is (read-only)
-    NodeImpl *m_endNode;     // end node for the selection (read-only)
-    long m_endOffset;             // offset into end node where selection is (read-only)
+    Position m_base;              // base position for the selection
+    Position m_extent;            // extent position for the selection
+    Position m_start;             // start position for the selection
+    Position m_end;               // end position for the selection
 
 	EState m_state;               // the state of the selection
 
-	int m_caretX;
+	int m_caretX;                 // caret coordinates and size
 	int m_caretY;
 	int m_caretSize;
 
 	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_modifyBiasSet : 1;     // true if the selection has been modified with EAlter::EXTEND
+	bool m_modifyBiasSet : 1;     // true if the selection has been horizontally 
+                                  // modified with EAlter::EXTEND
 };
 
 
 inline bool operator==(const Selection &a, const Selection &b)
 {
-    return a.startNode() == b.startNode() && a.startOffset() == b.startOffset() &&
-        a.endNode() == b.endNode() && a.endOffset() == b.endOffset();
+    return a.start() == b.start() && a.end() == b.end();
 }
 
 inline bool operator!=(const Selection &a, const Selection &b)
diff --git a/WebCore/khtml/khtml_part.cpp b/WebCore/khtml/khtml_part.cpp
index d4eac1c..ea837ab 100644
--- a/WebCore/khtml/khtml_part.cpp
+++ b/WebCore/khtml/khtml_part.cpp
@@ -2226,9 +2226,9 @@ bool KHTMLPart::findTextNext( const QString &str, bool forward, bool caseSensiti
                   ->posOfChar(d->m_findPos, x, y);
                 d->m_view->setContentsPos(x-50, y-50);
 #endif
-                Selection s = selection();
-                s.moveTo(d->m_findNode, d->m_findPos, d->m_findNode, d->m_findPos + matchLen);
-                setSelection(s);
+                Position p1(d->m_findNode, d->m_findPos);
+                Position p2(d->m_findNode, d->m_findPos + matchLen);
+                setSelection(Selection(p1, p2));
                 return true;
             }
         }
@@ -2542,10 +2542,10 @@ void KHTMLPart::setFocusNodeIfNeeded(const Selection &s)
     if (!xmlDocImpl() || s.state() == Selection::NONE)
         return;
 
-    NodeImpl *n = s.startNode();
+    NodeImpl *n = s.start().node();
     NodeImpl *target = n->isContentEditable() ? n : 0;
     if (!target) {
-        while (n != s.endNode()) {
+        while (n != s.end().node()) {
             if (n->isContentEditable()) {
                 target = n;
                 break;
@@ -2574,7 +2574,7 @@ void KHTMLPart::notifySelectionChanged(bool endTyping)
 
     // see if a new caret blink timer needs to be started
     if (d->m_caretVisible && d->m_caretBlinks && 
-        d->m_selection.state() == Selection::CARET && d->m_selection.startNode()->isContentEditable()) {
+        d->m_selection.state() == Selection::CARET && d->m_selection.start().node()->isContentEditable()) {
         d->m_caretBlinkTimer = startTimer(CARET_BLINK_FREQUENCY);
         d->m_caretPaint = true;
         d->m_selection.needsCaretRepaint();
@@ -4506,16 +4506,16 @@ bool KHTMLPart::isPointInsideSelection(int x, int y)
         return false;
     }
 
-    DOM::NodeImpl *n = d->m_selection.startNode();
+    DOM::NodeImpl *n = d->m_selection.start().node();
     while (n) {
         if (n == pos.node()) {
-            if ((n == d->m_selection.startNode() && pos.offset() < d->m_selection.startOffset()) ||
-                (n == d->m_selection.endNode() && pos.offset() > d->m_selection.endOffset())) {
+            if ((n == d->m_selection.start().node() && pos.offset() < d->m_selection.start().offset()) ||
+                (n == d->m_selection.end().node() && pos.offset() > d->m_selection.end().offset())) {
                 return false;
             }
             return true;
         }
-        if (n == d->m_selection.endNode()) {
+        if (n == d->m_selection.end().node()) {
             break;
         }
         DOM::NodeImpl *next = n->firstChild();
@@ -4814,7 +4814,7 @@ void KHTMLPart::handleMouseMoveEventSelection(khtml::MouseMoveEvent *event)
 	}
 #endif        
 
-    sel.setExtent(pos.node(), pos.offset());
+    sel.setExtent(pos);
 
 #if APPLE_CHANGES
     if (d->m_textElement != Selection::CHARACTER) {
@@ -4885,8 +4885,8 @@ void KHTMLPart::khtmlMouseReleaseEvent( khtml::MouseReleaseEvent *event )
 		d->m_selection.state() == Selection::RANGE &&
         d->m_textElement == Selection::CHARACTER) {
             Selection selection;
-            if (isEditingAtNode(d->m_selection.baseNode()))
-                selection.moveTo(d->m_selection.baseNode()->positionForCoordinates(event->x(), event->y()));
+            if (isEditingAtNode(d->m_selection.base().node()))
+                selection.moveTo(d->m_selection.base().node()->positionForCoordinates(event->x(), event->y()));
             setSelection(selection);
 	}
 #endif
@@ -5093,7 +5093,7 @@ void KHTMLPart::selectAll()
     return;
   Q_ASSERT(first->renderer());
   Q_ASSERT(last->renderer());
-  Selection selection(first, 0, last, last->nodeValue().length());
+  Selection selection(Position(first, 0), Position(last, last->nodeValue().length()));
   setSelection(selection);
 }
 
diff --git a/WebCore/khtml/rendering/render_block.cpp b/WebCore/khtml/rendering/render_block.cpp
index 8bef8bc..0334057 100644
--- a/WebCore/khtml/rendering/render_block.cpp
+++ b/WebCore/khtml/rendering/render_block.cpp
@@ -1286,7 +1286,7 @@ void RenderBlock::paintObject(PaintInfo& i, int _tx, int _ty)
     */
     if (paintAction == PaintActionForeground) {
         const Selection &s = document()->part()->selection();
-        NodeImpl *baseNode = s.baseNode();
+        NodeImpl *baseNode = s.base().node();
         RenderObject *renderer = baseNode ? baseNode->renderer() : 0;
         if (renderer && renderer->containingBlock() == this && baseNode->isContentEditable()) {
             document()->part()->paintCaret(i.p, i.r);
diff --git a/WebCore/khtml/xml/dom_docimpl.cpp b/WebCore/khtml/xml/dom_docimpl.cpp
index 2649775..c98b9be 100644
--- a/WebCore/khtml/xml/dom_docimpl.cpp
+++ b/WebCore/khtml/xml/dom_docimpl.cpp
@@ -1212,9 +1212,9 @@ void DocumentImpl::updateSelection()
         canvas->clearSelection();
     }
     else {
-        RenderObject *startRenderer = s.startNode() ? s.startNode()->renderer() : 0;
-        RenderObject *endRenderer = s.endNode() ? s.endNode()->renderer() : 0;
-        static_cast<RenderCanvas*>(m_render)->setSelection(startRenderer, s.startOffset(), endRenderer, s.endOffset());
+        RenderObject *startRenderer = s.start().node() ? s.start().node()->renderer() : 0;
+        RenderObject *endRenderer = s.end().node() ? s.end().node()->renderer() : 0;
+        static_cast<RenderCanvas*>(m_render)->setSelection(startRenderer, s.start().offset(), endRenderer, s.end().offset());
     }
 }
 
diff --git a/WebCore/khtml/xml/dom_nodeimpl.cpp b/WebCore/khtml/xml/dom_nodeimpl.cpp
index 83ff7db..01870c8 100644
--- a/WebCore/khtml/xml/dom_nodeimpl.cpp
+++ b/WebCore/khtml/xml/dom_nodeimpl.cpp
@@ -2068,7 +2068,7 @@ void NodeBaseImpl::setFocus(bool received)
 
     if (received && isEditableBlock() && !hasChildNodes()) {
         KHTMLPart *part = getDocument()->part();
-        part->setSelection(Selection(this, 0));
+        part->setSelection(Selection(Position(this, 0)));
     }
 
     // note that we need to recalc the style
diff --git a/WebCore/khtml/xml/dom_selection.cpp b/WebCore/khtml/xml/dom_selection.cpp
index e59b11f..1ae3586 100644
--- a/WebCore/khtml/xml/dom_selection.cpp
+++ b/WebCore/khtml/xml/dom_selection.cpp
@@ -33,7 +33,6 @@
 #include "qrect.h"
 #include "dom/dom2_range.h"
 #include "dom/dom_node.h"
-#include "dom/dom_position.h"
 #include "dom/dom_string.h"
 #include "rendering/render_object.h"
 #include "rendering/render_style.h"
@@ -52,69 +51,40 @@
 #define EDIT_DEBUG 0
 #endif
 
-namespace DOM {
-
 using khtml::InlineTextBox;
 using khtml::RenderObject;
 using khtml::RenderText;
 
+namespace DOM {
+
 #if APPLE_CHANGES
 static bool firstRunAt(RenderObject *renderNode, int y, NodeImpl *&startNode, long &startOffset);
 static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long &endOffset);
-static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, Selection &selection);
+static bool startAndEndLineNodesIncludingNode(NodeImpl *node, int offset, Selection &selection);
 #endif
 
-
-Selection::Selection()
+static inline Position &emptyPosition()
 {
-    init();
+    static Position EmptyPosition = Position();
+    return EmptyPosition;
 }
 
-Selection::Selection(NodeImpl *node, long offset)
+Selection::Selection()
 {
     init();
-
-	setBaseNode(node);
-	setExtentNode(node);
-	setBaseOffset(offset);
-	setExtentOffset(offset);
-
-    validate();
 }
 
 Selection::Selection(const Position &pos)
 {
     init();
-
-	setBaseNode(pos.node());
-	setExtentNode(pos.node());
-	setBaseOffset(pos.offset());
-	setExtentOffset(pos.offset());
-
+	assignBaseAndExtent(pos, pos);
     validate();
 }
 
 Selection::Selection(const Position &base, const Position &extent)
 {
     init();
-
-	setBaseNode(base.node());
-	setExtentNode(extent.node());
-	setBaseOffset(base.offset());
-	setExtentOffset(extent.offset());
-
-    validate();
-}
-
-Selection::Selection(NodeImpl *baseNode, long baseOffset, NodeImpl *endNode, long endOffset)
-{
-    init();
-
-	setBaseNode(baseNode);
-	setExtentNode(endNode);
-	setBaseOffset(baseOffset);
-	setExtentOffset(endOffset);
-
+	assignBaseAndExtent(base, extent);
     validate();
 }
 
@@ -122,15 +92,8 @@ Selection::Selection(const Selection &o)
 {
     init();
     
-	setBaseNode(o.baseNode());
-	setExtentNode(o.extentNode());
-	setBaseOffset(o.baseOffset());
-	setExtentOffset(o.extentOffset());
-
-	setStartNode(o.startNode());
-	setEndNode(o.endNode());
-	setStartOffset(o.startOffset());
-	setEndOffset(o.endOffset());
+	assignBaseAndExtent(o.base(), o.extent());
+	assignStartAndEnd(o.start(), o.end());
 
     m_state = o.m_state;
 
@@ -152,14 +115,7 @@ Selection::Selection(const Selection &o)
 
 void Selection::init()
 {
-    m_baseNode = 0;
-    m_baseOffset = 0;
-    m_extentNode = 0; 
-    m_extentOffset = 0;
-    m_startNode = 0;
-    m_startOffset = 0;
-    m_endNode = 0;
-    m_endOffset = 0;
+    m_base = m_extent = m_start = m_end = emptyPosition();
     m_state = NONE; 
     m_caretX = 0;
     m_caretY = 0;
@@ -169,29 +125,10 @@ void Selection::init()
     m_modifyBiasSet = false;
 }
 
-Selection::~Selection()
-{
-    if (m_baseNode)
-        m_baseNode->deref();
-    if (m_extentNode)
-        m_extentNode->deref();
-    if (m_startNode)
-        m_startNode->deref();
-    if (m_endNode)
-        m_endNode->deref();
-}
-
 Selection &Selection::operator=(const Selection &o)
 {
-	setBaseNode(o.baseNode());
-	setExtentNode(o.extentNode());
-	setBaseOffset(o.baseOffset());
-	setExtentOffset(o.extentOffset());
-
-	setStartNode(o.startNode());
-	setEndNode(o.endNode());
-	setStartOffset(o.startOffset());
-	setEndOffset(o.endOffset());
+	assignBaseAndExtent(o.base(), o.extent());
+	assignStartAndEnd(o.start(), o.end());
 
     m_state = o.m_state;
 
@@ -213,34 +150,27 @@ Selection &Selection::operator=(const Selection &o)
     return *this;
 }
 
-void Selection::moveTo(DOM::NodeImpl *node, long offset)
+void Selection::moveTo(const Range &r)
 {
-    moveTo(node, offset, node, offset);
+    Position start(r.startContainer().handle(), r.startOffset());
+    Position end(r.endContainer().handle(), r.endOffset());
+	moveTo(start, end);
 }
 
-void Selection::moveTo(const DOM::Range &r)
-{
-	moveTo(r.startContainer().handle(), r.startOffset(), 
-		r.endContainer().handle(), r.endOffset());
-}
-
-void Selection::moveTo(const DOM::Position &pos)
+void Selection::moveTo(const Selection &o)
 {
-	moveTo(pos.node(), pos.offset());
+	moveTo(o.start(), o.end());
 }
 
-void Selection::moveTo(const Selection &o)
+void Selection::moveTo(const Position &pos)
 {
-	moveTo(o.baseNode(), o.baseOffset(), o.extentNode(), o.extentOffset());
+	moveTo(pos, pos);
 }
 
-void Selection::moveTo(DOM::NodeImpl *baseNode, long baseOffset, DOM::NodeImpl *extentNode, long extentOffset)
+void Selection::moveTo(const Position &base, const Position &extent)
 {
-	setBaseNode(baseNode);
-	setExtentNode(extentNode);
-	setBaseOffset(baseOffset);
-	setExtentOffset(extentOffset);
-	validate();
+	assignBaseAndExtent(base, extent);
+    validate();
 }
 
 bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularity)
@@ -254,29 +184,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(startNode());
-                    setBaseOffset(startOffset());
-                    setExtentNode(endNode());
-                    setExtentOffset(endOffset());
+                    assignBaseAndExtent(start(), end());
                 }
                 if (granularity == CHARACTER)
-                    pos = extentPosition().nextCharacterPosition();
+                    pos = extent().nextCharacterPosition();
                 else if (granularity == WORD)
-                    pos = extentPosition().nextWordPosition();
+                    pos = extent().nextWordPosition();
             }
             else {
                 m_modifyBiasSet = false;
                 if (state() == RANGE) {
                     if (granularity == CHARACTER)
-                        pos = endPosition();
+                        pos = end();
                     else if (granularity == WORD)
-                        pos = extentPosition().nextWordPosition();
+                        pos = extent().nextWordPosition();
                 }
                 else {
                     if (granularity == CHARACTER)
-                        pos = extentPosition().nextCharacterPosition();
+                        pos = extent().nextCharacterPosition();
                     else if (granularity == WORD)
-                        pos = extentPosition().nextWordPosition();
+                        pos = extent().nextWordPosition();
                 }
             }
             break;
@@ -286,29 +213,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(endNode());
-                    setBaseOffset(endOffset());
-                    setExtentNode(startNode());
-                    setExtentOffset(startOffset());
+                    assignBaseAndExtent(end(), start());
                 }
                 if (granularity == CHARACTER)
-                    pos = extentPosition().previousCharacterPosition();
+                    pos = extent().previousCharacterPosition();
                 else if (granularity == WORD)
-                    pos = extentPosition().previousWordPosition();
+                    pos = extent().previousWordPosition();
             }
             else {
                 m_modifyBiasSet = false;
                 if (state() == RANGE) {
                     if (granularity == CHARACTER)
-                        pos = startPosition();
+                        pos = start();
                     else if (granularity == WORD)
-                        pos = extentPosition().previousWordPosition();
+                        pos = extent().previousWordPosition();
                 }
                 else {
                     if (granularity == CHARACTER)
-                        pos = extentPosition().previousCharacterPosition();
+                        pos = extent().previousCharacterPosition();
                     else if (granularity == WORD)
-                        pos = extentPosition().previousWordPosition();
+                        pos = extent().previousWordPosition();
                 }
             }
             break;
@@ -316,32 +240,26 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(endNode());
-                    setBaseOffset(endOffset());
-                    setExtentNode(startNode());
-                    setExtentOffset(startOffset());
+                    assignBaseAndExtent(end(), start());
                 }
-                pos = extentPosition().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+                pos = extent().previousLinePosition(xPosForVerticalArrowNavigation(EXTENT));
             }
             else {
                 m_modifyBiasSet = false;
-                pos = startPosition().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
+                pos = start().previousLinePosition(xPosForVerticalArrowNavigation(START, state()==RANGE));
             }
             break;
         case DOWN:
             if (alter == EXTEND) {
                 if (!m_modifyBiasSet) {
                     m_modifyBiasSet = true;
-                    setBaseNode(startNode());
-                    setBaseOffset(startOffset());
-                    setExtentNode(endNode());
-                    setExtentOffset(endOffset());
+                    assignBaseAndExtent(start(), end());
                 }
-                pos = extentPosition().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
+                pos = extent().nextLinePosition(xPosForVerticalArrowNavigation(EXTENT));
             }
             else {
                 m_modifyBiasSet = false;
-                pos = endPosition().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
+                pos = end().nextLinePosition(xPosForVerticalArrowNavigation(END, state()==RANGE));
             }
             break;
     }
@@ -350,9 +268,9 @@ bool Selection::modify(EAlter alter, EDirection dir, ETextGranularity granularit
         return false;
     
     if (alter == MOVE)
-        moveTo(pos.node(), pos.offset());
+        moveTo(pos);
     else // alter == EXTEND
-        setExtent(pos.node(), pos.offset());
+        setExtent(pos);
     
     return true;
 }
@@ -376,16 +294,16 @@ int Selection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) c
     Position pos;
     switch (type) {
         case START:
-            pos = startPosition();
+            pos = start();
             break;
         case END:
-            pos = endPosition();
+            pos = end();
             break;
         case BASE:
-            pos = basePosition();
+            pos = base();
             break;
         case EXTENT:
-            pos = extentPosition();
+            pos = extent();
             break;
     }
 
@@ -407,25 +325,44 @@ int Selection::xPosForVerticalArrowNavigation(EPositionType type, bool recalc) c
 
 void Selection::clear()
 {
-	setBaseNode(0);
-	setExtentNode(0);
-	setBaseOffset(0);
-	setExtentOffset(0);
+	assignBaseAndExtent(emptyPosition(), emptyPosition());
 	validate();
 }
 
-void Selection::setBase(DOM::NodeImpl *node, long offset)
+void Selection::setBase(const Position &pos)
 {
-	setBaseNode(node);
-	setBaseOffset(offset);
-	validate();
+    assignBase(pos);
+    validate();
 }
 
-void Selection::setExtent(DOM::NodeImpl *node, long offset)
+void Selection::setExtent(const Position &pos)
 {
-	setExtentNode(node);
-	setExtentOffset(offset);
-	validate();
+    assignExtent(pos);
+    validate();
+}
+
+void Selection::setBaseAndExtent(const Position &base, const Position &extent)
+{
+    assignBaseAndExtent(base, extent);
+    validate();
+}
+
+void Selection::setStart(const Position &pos)
+{
+    assignStart(pos);
+    validate();
+}
+
+void Selection::setEnd(const Position &pos)
+{
+    assignEnd(pos);
+    validate();
+}
+
+void Selection::setStartAndEnd(const Position &start, const Position &end)
+{
+    assignStartAndEnd(start, end);
+    validate();
 }
 
 void Selection::setNeedsLayout(bool flag)
@@ -438,17 +375,17 @@ Range Selection::toRange() const
     if (isEmpty())
         return Range();
 
-    return Range(Node(startNode()), startOffset(), Node(endNode()), endOffset());
+    return Range(Node(start().node()), start().offset(), Node(end().node()), end().offset());
 }
 
 void Selection::layoutCaret()
 {
-    if (isEmpty() || !startNode()->renderer()) {
+    if (isEmpty() || !start().node()->renderer()) {
         m_caretX = m_caretY = m_caretSize = 0;
     }
     else {
         int w;
-        startNode()->renderer()->caretPos(startOffset(), true, m_caretX, m_caretY, w, m_caretSize);
+        start().node()->renderer()->caretPos(start().offset(), true, m_caretX, m_caretY, w, m_caretSize);
     }
 
     m_needsCaretLayout = false;
@@ -465,10 +402,10 @@ void Selection::needsCaretRepaint()
     if (isEmpty())
         return;
 
-    if (!startNode()->getDocument())
+    if (!start().node()->getDocument())
         return;
 
-    KHTMLView *v = startNode()->getDocument()->view();
+    KHTMLView *v = start().node()->getDocument()->view();
     if (!v)
         return;
 
@@ -502,7 +439,7 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
         return;
 
     if (m_needsCaretLayout) {
-        Position pos = Position(startNode(), startOffset());
+        Position pos = start();
         if (!pos.inRenderedContent()) {
             moveToRenderedContent();
         }
@@ -520,126 +457,37 @@ void Selection::paintCaret(QPainter *p, const QRect &rect)
     }
 }
 
-void Selection::setBaseNode(DOM::NodeImpl *node)
-{
-	if (m_baseNode == node)
-		return;
-
-	if (m_baseNode)
-		m_baseNode->deref();
-	
-	m_baseNode = node;
-	
-	if (m_baseNode)
-		m_baseNode->ref();
-}
-
-void Selection::setBaseOffset(long offset)
-{
-	m_baseOffset = offset;
-}
-
-void Selection::setExtentNode(DOM::NodeImpl *node)
-{
-	if (m_extentNode == node)
-		return;
-
-	if (m_extentNode)
-		m_extentNode->deref();
-	
-	m_extentNode = node;
-	
-	if (m_extentNode)
-		m_extentNode->ref();
-}
-	
-void Selection::setExtentOffset(long offset)
-{
-	m_extentOffset = offset;
-}
-
-void Selection::setStartNode(DOM::NodeImpl *node)
-{
-	if (m_startNode == node)
-		return;
-
-	if (m_startNode)
-		m_startNode->deref();
-	
-	m_startNode = node;
-	
-	if (m_startNode)
-		m_startNode->ref();
-}
-
-void Selection::setStartOffset(long offset)
-{
-	m_startOffset = offset;
-}
-
-void Selection::setEndNode(DOM::NodeImpl *node)
-{
-	if (m_endNode == node)
-		return;
-
-	if (m_endNode)
-		m_endNode->deref();
-	
-	m_endNode = node;
-	
-	if (m_endNode)
-		m_endNode->ref();
-}
-	
-void Selection::setEndOffset(long offset)
-{
-	m_endOffset = offset;
-}
-
 void Selection::validate(ETextGranularity granularity)
 {
     // move the base and extent nodes to their equivalent leaf positions
-    bool baseAndExtentEqual = m_baseNode == m_extentNode && m_baseOffset == m_extentOffset;
-    if (m_baseNode) {
-        Position pos = basePosition().equivalentLeafPosition();
-        m_baseNode = pos.node();
-        m_baseOffset = pos.offset();
-        if (baseAndExtentEqual) {
-            m_extentNode = pos.node();
-            m_extentOffset = pos.offset();
-        }
+    bool baseAndExtentEqual = base() == extent();
+    if (base().notEmpty()) {
+        Position pos = base().equivalentLeafPosition();
+        assignBase(pos);
+        if (baseAndExtentEqual)
+            assignExtent(pos);
     }
-    if (m_extentNode && !baseAndExtentEqual) {
-        Position pos = extentPosition().equivalentLeafPosition();
-        m_extentNode = pos.node();
-        m_extentOffset = pos.offset();
+    if (extent().notEmpty() && !baseAndExtentEqual) {
+        assignExtent(extent().equivalentLeafPosition());
     }
 
     // make sure we do not have a dangling start or end
-	if (!m_baseNode && !m_extentNode) {
-        setBaseOffset(0);
-        setExtentOffset(0);
+	if (base().isEmpty() && extent().isEmpty()) {
+        assignStartAndEnd(emptyPosition(), emptyPosition());
         m_baseIsStart = true;
     }
-	else if (!m_baseNode) {
-		setBaseNode(m_extentNode);
-		setBaseOffset(m_extentOffset);
-        m_baseIsStart = true;
-	}
-	else if (!m_extentNode) {
-		setExtentNode(m_baseNode);
-		setExtentOffset(m_baseOffset);
+	else if (base().isEmpty() || extent().isEmpty()) {
         m_baseIsStart = true;
 	}
     else {
         // adjust m_baseIsStart as needed
-        if (m_baseNode == m_extentNode) {
-            if (m_baseOffset > m_extentOffset)
+        if (base().node() == extent().node()) {
+            if (base().offset() > extent().offset())
                 m_baseIsStart = false;
             else 
                 m_baseIsStart = true;
         }
-        else if (nodeIsBeforeNode(m_baseNode, m_extentNode))
+        else if (nodeIsBeforeNode(base().node(), extent().node()))
             m_baseIsStart = true;
         else
             m_baseIsStart = false;
@@ -647,101 +495,73 @@ void Selection::validate(ETextGranularity granularity)
 
     // calculate the correct start and end positions
 #if !APPLE_CHANGES
-    if (m_baseIsStart) {
-        setStartNode(m_baseNode);
-        setStartOffset(m_baseOffset);
-        setEndNode(m_extentNode);
-        setEndOffset(m_extentOffset);
-    }
-    else {
-        setStartNode(m_extentNode);
-        setStartOffset(m_extentOffset);
-        setEndNode(m_baseNode);
-        setEndOffset(m_baseOffset);
-    }
+    if (m_baseIsStart)
+        assignStartAndEnd(base(), extent());
+    else
+        assignStartAndEnd(extent(), base());
 #else
     if (granularity == CHARACTER) {
-        if (m_baseIsStart) {
-            setStartNode(m_baseNode);
-            setStartOffset(m_baseOffset);
-            setEndNode(m_extentNode);
-            setEndOffset(m_extentOffset);
-        }
-        else {
-            setStartNode(m_extentNode);
-            setStartOffset(m_extentOffset);
-            setEndNode(m_baseNode);
-            setEndOffset(m_baseOffset);
-        }
+        if (m_baseIsStart)
+            assignStartAndEnd(base(), extent());
+        else
+            assignStartAndEnd(extent(), base());
     }
     else if (granularity == WORD) {
-        int baseStartOffset = m_baseOffset;
-        int baseEndOffset = m_baseOffset;
-        int extentStartOffset = m_extentOffset;
-        int extentEndOffset = m_extentOffset;
-        if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            DOMString t = m_baseNode->nodeValue();
+        int baseStartOffset = base().offset();
+        int baseEndOffset = base().offset();
+        int extentStartOffset = extent().offset();
+        int extentEndOffset = extent().offset();
+        if (base().notEmpty() && (base().node()->nodeType() == Node::TEXT_NODE || base().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            DOMString t = base().node()->nodeValue();
             QChar *chars = t.unicode();
             uint len = t.length();
-            KWQFindWordBoundary(chars, len, m_baseOffset, &baseStartOffset, &baseEndOffset);
+            KWQFindWordBoundary(chars, len, base().offset(), &baseStartOffset, &baseEndOffset);
         }
-        if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            DOMString t = m_extentNode->nodeValue();
+        if (extent().notEmpty() && (extent().node()->nodeType() == Node::TEXT_NODE || extent().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            DOMString t = extent().node()->nodeValue();
             QChar *chars = t.unicode();
             uint len = t.length();
-            KWQFindWordBoundary(chars, len, m_extentOffset, &extentStartOffset, &extentEndOffset);
+            KWQFindWordBoundary(chars, len, extent().offset(), &extentStartOffset, &extentEndOffset);
         }
         if (m_baseIsStart) {
-            setStartNode(m_baseNode);
-            setStartOffset(baseStartOffset);
-            setEndNode(m_extentNode);
-            setEndOffset(extentEndOffset);
+            assignStart(Position(base().node(), baseStartOffset));
+            assignEnd(Position(extent().node(), extentEndOffset));
         }
         else {
-            setStartNode(m_extentNode);
-            setStartOffset(extentStartOffset);
-            setEndNode(m_baseNode);
-            setEndOffset(baseEndOffset);
+            assignStart(Position(extent().node(), extentStartOffset));
+            assignEnd(Position(base().node(), baseEndOffset));
         }
     }
-    else {  // granularity == LINE
+    else {  // granularity == LINE 
         Selection baseSelection = *this;
         Selection extentSelection = *this;
-        if (m_baseNode && (m_baseNode->nodeType() == Node::TEXT_NODE || m_baseNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            if (startAndEndLineNodesIncludingNode(m_baseNode, m_baseOffset, baseSelection)) {
-                setStartNode(baseSelection.baseNode());
-                setStartOffset(baseSelection.baseOffset());
-                setEndNode(baseSelection.extentNode());
-                setEndOffset(baseSelection.extentOffset());
+        if (base().notEmpty() && (base().node()->nodeType() == Node::TEXT_NODE || base().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            if (startAndEndLineNodesIncludingNode(base().node(), base().offset(), baseSelection)) {
+                assignStart(Position(baseSelection.base().node(), baseSelection.base().offset()));
+                assignEnd(Position(baseSelection.extent().node(), baseSelection.extent().offset()));
             }
         }
-        if (m_extentNode && (m_extentNode->nodeType() == Node::TEXT_NODE || m_extentNode->nodeType() == Node::CDATA_SECTION_NODE)) {
-            if (startAndEndLineNodesIncludingNode(m_extentNode, m_extentOffset, extentSelection)) {
-                setStartNode(extentSelection.baseNode());
-                setStartOffset(extentSelection.baseOffset());
-                setEndNode(extentSelection.extentNode());
-                setEndOffset(extentSelection.extentOffset());
+        if (extent().notEmpty() && (extent().node()->nodeType() == Node::TEXT_NODE || extent().node()->nodeType() == Node::CDATA_SECTION_NODE)) {
+            if (startAndEndLineNodesIncludingNode(extent().node(), extent().offset(), extentSelection)) {
+                assignStart(Position(extentSelection.base().node(), extentSelection.base().offset()));
+                assignEnd(Position(extentSelection.extent().node(), extentSelection.extent().offset()));
             }
         }
         if (m_baseIsStart) {
-            setStartNode(baseSelection.startNode());
-            setStartOffset(baseSelection.startOffset());
-            setEndNode(extentSelection.endNode());
-            setEndOffset(extentSelection.endOffset());
+            assignStart(baseSelection.start());
+            assignEnd(extentSelection.end());
         }
         else {
-            setStartNode(extentSelection.startNode());
-            setStartOffset(extentSelection.startOffset());
-            setEndNode(baseSelection.endNode());
-            setEndOffset(baseSelection.endOffset());
+            assignStart(extentSelection.start());
+            assignEnd(baseSelection.end());
         }
     }
 #endif  // APPLE_CHANGES
 
 	// adjust the state
-	if (!m_startNode && !m_endNode)
+	if (start().isEmpty() && end().isEmpty())
 		m_state = NONE;
-	else if (m_startNode == m_endNode && m_startOffset == m_endOffset)
+	else if (start() == end())
 		m_state = CARET;
 	else
 		m_state = RANGE;
@@ -761,7 +581,7 @@ bool Selection::moveToRenderedContent()
     if (m_state != CARET)
         return false;
 
-    Position pos = Position(startNode(), startOffset());
+    Position pos = start();
     if (pos.inRenderedContent())
         return true;
         
@@ -782,26 +602,6 @@ bool Selection::moveToRenderedContent()
     return false;
 }
 
-Position Selection::basePosition() const
-{
-    return Position(baseNode(), baseOffset());
-}
-
-Position Selection::extentPosition() const
-{
-    return Position(extentNode(), extentOffset());
-}
-
-Position Selection::startPosition() const
-{
-    return Position(startNode(), startOffset());
-}
-
-Position Selection::endPosition() const
-{
-    return Position(endNode(), endOffset());
-}
-
 bool Selection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2) 
 {
 	if (!n1 || !n2) 
@@ -815,7 +615,7 @@ bool Selection::nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2)
     int n2Depth = 0;
 
     // First we find the depths of the two nodes in the tree (n1Depth, n2Depth)
-    DOM::NodeImpl *n = n1;
+    NodeImpl *n = n1;
     while (n->parentNode()) {
         n = n->parentNode();
         n1Depth++;
@@ -914,7 +714,7 @@ static bool lastRunAt(RenderObject *renderNode, int y, NodeImpl *&endNode, long
     }
 }
 
-static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, Selection &selection)
+static bool startAndEndLineNodesIncludingNode(NodeImpl *node, int offset, Selection &selection)
 {
     if (node && (node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE)) {
         int pos;
@@ -935,8 +735,8 @@ static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, S
         
         renderNode = renderNode->firstChild();
         
-        DOM::NodeImpl *startNode = 0;
-        DOM::NodeImpl *endNode = 0;
+        NodeImpl *startNode = 0;
+        NodeImpl *endNode = 0;
         long startOffset;
         long endOffset;
         
@@ -950,7 +750,7 @@ static bool startAndEndLineNodesIncludingNode(DOM::NodeImpl *node, int offset, S
         if (!lastRunAt (renderNode, selectionPointY, endNode, endOffset))
             return false;
         
-        selection.moveTo(startNode, startOffset, endNode, endOffset);
+        selection.moveTo(Position(startNode, startOffset), Position(endNode, endOffset));
         
         return true;
     }
@@ -975,10 +775,10 @@ void Selection::debugRenderer(RenderObject *r, bool selected) const
         int textLength = text.length();
         if (selected) {
             int offset = 0;
-            if (r->node() == startNode())
-                offset = startOffset();
-            else if (r->node() == endNode())
-                offset = endOffset();
+            if (r->node() == start().node())
+                offset = start().offset();
+            else if (r->node() == end().node())
+                offset = end().offset();
                 
             int pos;
             InlineTextBox *box = textRenderer->findNextInlineTextBox(offset, pos);
@@ -1032,7 +832,7 @@ void Selection::debugRenderer(RenderObject *r, bool selected) const
 
 void Selection::debugPosition() const
 {
-    if (!startNode())
+    if (!start().node())
         return;
 
     //static int context = 5;
@@ -1041,8 +841,8 @@ void Selection::debugPosition() const
 
     fprintf(stderr, "Selection =================\n");
 
-    if (startPosition() == endPosition()) {
-        Position pos = startPosition();
+    if (start() == end()) {
+        Position pos = start();
         Position upstream = pos.equivalentUpstreamPosition();
         Position downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
@@ -1050,14 +850,14 @@ void Selection::debugPosition() const
         fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
     }
     else {
-        Position pos = startPosition();
+        Position pos = start();
         Position upstream = pos.equivalentUpstreamPosition();
         Position downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
         fprintf(stderr, "start:      %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
         fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
         fprintf(stderr, "-----------------------------------\n");
-        pos = endPosition();
+        pos = end();
         upstream = pos.equivalentUpstreamPosition();
         downstream = pos.equivalentDownstreamPosition();
         fprintf(stderr, "upstream:   %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
@@ -1068,7 +868,7 @@ void Selection::debugPosition() const
           
 #if 0
     int back = 0;
-    r = startNode()->renderer();
+    r = start().node()->renderer();
     for (int i = 0; i < context; i++, back++) {
         if (r->previousRenderer())
             r = r->previousRenderer();
@@ -1083,15 +883,15 @@ void Selection::debugPosition() const
 
     fprintf(stderr, "\n");
 
-    if (startNode() == endNode())
-        debugRenderer(startNode()->renderer(), true);
+    if (start().node() == end().node())
+        debugRenderer(start().node()->renderer(), true);
     else
-        for (r = startNode()->renderer(); r && r != endNode()->renderer(); r = r->nextRenderer())
+        for (r = start().node()->renderer(); r && r != end().node()->renderer(); r = r->nextRenderer())
             debugRenderer(r, true);
     
     fprintf(stderr, "\n");
     
-    r = endNode()->renderer();
+    r = end().node()->renderer();
     for (int i = 0; i < context; i++) {
         if (r->nextRenderer()) {
             r = r->nextRenderer();
diff --git a/WebCore/khtml/xml/dom_selection.h b/WebCore/khtml/xml/dom_selection.h
index 01fcb1b..1e67737 100644
--- a/WebCore/khtml/xml/dom_selection.h
+++ b/WebCore/khtml/xml/dom_selection.h
@@ -26,6 +26,8 @@
 #ifndef __dom_selection_h__
 #define __dom_selection_h__
 
+#include "xml/dom_position.h"
+
 class KHTMLPart;
 class QPainter;
 class QRect;
@@ -44,12 +46,10 @@ class Selection
 {
 public:
     Selection();
-    Selection(NodeImpl *node, long offset);
     Selection(const Position &);
     Selection(const Position &, const Position &);
-    Selection(NodeImpl *startNode, long startOffset, NodeImpl *endNode, long endOffset);
     Selection(const Selection &);
-    ~Selection();
+    ~Selection() {}
 
 	enum EState { NONE, CARET, RANGE };
 	enum EAlter { MOVE, EXTEND };
@@ -58,36 +58,27 @@ public:
 
 	EState state() const { return m_state; }
 
-    void moveTo(NodeImpl *node, long offset);
     void moveTo(const Range &);
-    void moveTo(const Position &);
     void moveTo(const Selection &);
-    void moveTo(NodeImpl *baseNode, long baseOffset, NodeImpl *extentNode, long extentOffset);
+    void moveTo(const Position &);
+    void moveTo(const Position &, const Position &);
     bool modify(EAlter, EDirection, ETextGranularity);
     bool expandUsingGranularity(ETextGranularity);
     void clear();
 
     bool moveToRenderedContent();
     
-    void setBase(NodeImpl *node, long offset);
-    void setExtent(NodeImpl *node, long offset);
-
-    NodeImpl *baseNode() const { return m_baseNode; }
-    long baseOffset() const { return m_baseOffset; }
-
-    NodeImpl *extentNode() const { return m_extentNode; }
-    long extentOffset() const { return m_extentOffset; }
-
-    NodeImpl *startNode() const { return m_startNode; }
-    long startOffset() const { return m_startOffset; }
-
-    NodeImpl *endNode() const { return m_endNode; }
-    long endOffset() const { return m_endOffset; }
-
-    Position basePosition() const;
-    Position extentPosition() const;
-    Position startPosition() const;
-    Position endPosition() const;
+    void setBase(const Position &pos);
+    void setExtent(const Position &pos);
+    void setBaseAndExtent(const Position &base, const Position &extent);
+    void setStart(const Position &pos);
+    void setEnd(const Position &pos);
+    void setStartAndEnd(const Position &start, const Position &end);
+
+    Position base() const { return m_base; }
+    Position extent() const { return m_extent; }
+    Position start() const { return m_start; }
+    Position end() const { return m_end; }
 
     void setNeedsLayout(bool flag=true);
     void clearModifyBias() { m_modifyBiasSet = false; }
@@ -96,7 +87,6 @@ public:
     bool notEmpty() const { return !isEmpty(); }
     Range toRange() const;
 
-    
     void debugPosition() const;
     void debugRenderer(khtml::RenderObject *r, bool selected) const;
 
@@ -112,53 +102,42 @@ private:
 
     void init();
     void validate(ETextGranularity granularity=CHARACTER);
+    void assignBase(const Position &pos) { m_base = pos; }
+    void assignExtent(const Position &pos) { m_extent = pos; }
+    void assignBaseAndExtent(const Position &base, const Position &extent) { m_base = base; m_extent = extent; }
+    void assignStart(const Position &pos) { m_start = pos; }
+    void assignEnd(const Position &pos) { m_end = pos; }
+    void assignStartAndEnd(const Position &start, const Position &end) { m_start = start; m_end = end; }
 
     void layoutCaret();
     void needsCaretRepaint();
     QRect getRepaintRect();
     void paintCaret(QPainter *p, const QRect &rect);
 
-	void setBaseNode(NodeImpl *);
-	void setBaseOffset(long);
-	void setExtentNode(NodeImpl *);
-	void setExtentOffset(long);
-
-	void setStartNode(NodeImpl *);
-	void setStartOffset(long);
-	void setEndNode(NodeImpl *);
-	void setEndOffset(long);
-
     bool nodeIsBeforeNode(NodeImpl *n1, NodeImpl *n2);
-
-    void calculateStartAndEnd(ETextGranularity select=CHARACTER);
     int xPosForVerticalArrowNavigation(EPositionType, bool recalc=false) const;
-    
-    NodeImpl *m_baseNode;    // base node for the selection
-    long m_baseOffset;            // offset into base node where selection is
-    NodeImpl *m_extentNode;  // extent node for the selection
-    long m_extentOffset;          // offset into extent node where selection is
 
-    NodeImpl *m_startNode;   // start node for the selection (read-only)
-    long m_startOffset;           // offset into start node where selection is (read-only)
-    NodeImpl *m_endNode;     // end node for the selection (read-only)
-    long m_endOffset;             // offset into end node where selection is (read-only)
+    Position m_base;              // base position for the selection
+    Position m_extent;            // extent position for the selection
+    Position m_start;             // start position for the selection
+    Position m_end;               // end position for the selection
 
 	EState m_state;               // the state of the selection
 
-	int m_caretX;
+	int m_caretX;                 // caret coordinates and size
 	int m_caretY;
 	int m_caretSize;
 
 	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_modifyBiasSet : 1;     // true if the selection has been modified with EAlter::EXTEND
+	bool m_modifyBiasSet : 1;     // true if the selection has been horizontally 
+                                  // modified with EAlter::EXTEND
 };
 
 
 inline bool operator==(const Selection &a, const Selection &b)
 {
-    return a.startNode() == b.startNode() && a.startOffset() == b.startOffset() &&
-        a.endNode() == b.endNode() && a.endOffset() == b.endOffset();
+    return a.start() == b.start() && a.end() == b.end();
 }
 
 inline bool operator!=(const Selection &a, const Selection &b)
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index e8ae832..b45be74 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -819,11 +819,11 @@ void KWQKHTMLPart::jumpToSelection()
 {
     // Assumes that selection will only ever be text nodes. This is currently
     // true, but will it always be so?
-    if (d->m_selection.startNode()) {
-        RenderText *rt = dynamic_cast<RenderText *>(d->m_selection.startNode()->renderer());
+    if (d->m_selection.start().notEmpty()) {
+        RenderText *rt = dynamic_cast<RenderText *>(d->m_selection.start().node()->renderer());
         if (rt) {
             int x = 0, y = 0;
-            rt->posOfChar(d->m_selection.startOffset(), x, y);
+            rt->posOfChar(d->m_selection.start().offset(), x, y);
             // The -50 offset is copied from KHTMLPart::findTextNext, which sets the contents position
             // after finding a matched text string.
            d->m_view->setContentsPos(x - 50, y - 50);
@@ -2727,22 +2727,22 @@ KWQWindowWidget *KWQKHTMLPart::topLevelWidget()
 
 int KWQKHTMLPart::selectionStartOffset() const
 {
-    return d->m_selection.startOffset();
+    return d->m_selection.start().offset();
 }
 
 int KWQKHTMLPart::selectionEndOffset() const
 {
-    return d->m_selection.endOffset();
+    return d->m_selection.end().offset();
 }
 
 NodeImpl *KWQKHTMLPart::selectionStart() const
 {
-    return d->m_selection.startNode();
+    return d->m_selection.start().node();
 }
 
 NodeImpl *KWQKHTMLPart::selectionEnd() const
 {
-    return d->m_selection.endNode();
+    return d->m_selection.end().node();
 }
 
 void KWQKHTMLPart::setBridge(WebCoreBridge *p)
diff --git a/WebCore/kwq/KWQRenderTreeDebug.cpp b/WebCore/kwq/KWQRenderTreeDebug.cpp
index aa038c6..26547de 100644
--- a/WebCore/kwq/KWQRenderTreeDebug.cpp
+++ b/WebCore/kwq/KWQRenderTreeDebug.cpp
@@ -359,11 +359,11 @@ static void writeSelection(QTextStream &ts, const RenderObject *o)
     if (selection.state() == Selection::NONE)
         return;
 
-    if (!selection.startPosition().node()->isContentEditable() || !selection.endPosition().node()->isContentEditable())
+    if (!selection.start().node()->isContentEditable() || !selection.end().node()->isContentEditable())
         return;
 
-    Position startPosition = selection.startPosition();
-    Position endPosition = selection.endPosition();
+    Position startPosition = selection.start();
+    Position endPosition = selection.end();
 
     QString startNodeTagName(getTagName(startPosition.node()->id()).string());
     QString endNodeTagName(getTagName(endPosition.node()->id()).string());
diff --git a/WebCore/kwq/WebCoreBridge.mm b/WebCore/kwq/WebCoreBridge.mm
index 850a609..c2b93f2 100644
--- a/WebCore/kwq/WebCoreBridge.mm
+++ b/WebCore/kwq/WebCoreBridge.mm
@@ -29,6 +29,7 @@
 #import "dom_node.h"
 #import "dom_docimpl.h"
 #import "dom_nodeimpl.h"
+#import "dom_position.h"
 #import "dom_selection.h"
 #import "dom2_rangeimpl.h"
 #import "htmlediting.h"
@@ -88,6 +89,7 @@ using DOM::HTMLImageElementImpl;
 using DOM::HTMLInputElementImpl;
 using DOM::Node;
 using DOM::NodeImpl;
+using DOM::Position;
 using DOM::Range;
 using DOM::Selection;
 
@@ -387,7 +389,7 @@ static bool initializedKJS = FALSE;
 - (BOOL)isSelectionEditable
 {
     // EDIT FIXME: This needs to consider the entire selected range
-	NodeImpl *startNode = _part->selection().startNode();
+	NodeImpl *startNode = _part->selection().start().node();
 	return startNode ? startNode->isContentEditable() : NO;
 }
 
@@ -1079,10 +1081,9 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 
 - (void)setSelectionFrom:(DOMNode *)start startOffset:(int)startOffset to:(DOMNode *)end endOffset:(int) endOffset
 {
-    DOMNode *startNode = start;
-    DOMNode *endNode = end;
-    Selection selection([startNode _nodeImpl], startOffset, [endNode _nodeImpl], endOffset);
-    _part->setSelection(selection);
+    Position s([start _nodeImpl], startOffset);
+    Position e([end _nodeImpl], endOffset);
+    _part->setSelection(Selection(s, e));
 }
 
 - (NSAttributedString *)selectedAttributedString
@@ -1365,7 +1366,7 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
     
     DocumentImpl *doc = startContainer->getDocument();
     doc->updateLayout();
-    Selection selection(startContainer, [range startOffset], endContainer, [range endOffset]);
+    Selection selection(Position(startContainer, [range startOffset]), Position(endContainer, [range endOffset]));
     _part->setSelection(selection);
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list