[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:26:31 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 49e09fae0a165b87e904e475d59e27a8cf4d73f2
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Feb 12 22:40:52 2004 +0000

            Reviewed by Hyatt
    
    	Refactored object design for edit commands into something that's
    	starting to feel more solid. Added some accessors to edit
    	commands.
    
            * WebCore.pbproj/project.pbxproj:
            * khtml/editing/htmlediting_impl.h: Added.
            * khtml/editing/htmlediting_impl.m: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6081 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 907b85b..340ba5c 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,15 @@
+2004-02-12  Ken Kocienda  <kocienda at apple.com>
+
+        Reviewed by Hyatt
+
+	Refactored object design for edit commands into something that's
+	starting to feel more solid. Added some accessors to edit 
+	commands.
+
+        * WebCore.pbproj/project.pbxproj:
+        * khtml/editing/htmlediting_impl.h: Added.
+        * khtml/editing/htmlediting_impl.m: Added.
+
 2004-02-11  David Hyatt  <hyatt at apple.com>
 
 	Fix for 3550005, 936 leaks when loading checkbox page of pain.  Make sure to nuke the inline box
diff --git a/WebCore/WebCore.pbproj/project.pbxproj b/WebCore/WebCore.pbproj/project.pbxproj
index c609a6d..5032427 100644
--- a/WebCore/WebCore.pbproj/project.pbxproj
+++ b/WebCore/WebCore.pbproj/project.pbxproj
@@ -523,6 +523,7 @@
 				BC7E782205C5EB700088A50F,
 				BC3B364905C9D5E200E42902,
 				BC3B364A05C9D5E200E42902,
+				BE9580F905DA973B00EC5B54,
 			);
 			isa = PBXHeadersBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -798,6 +799,7 @@
 				BC7FDE3305C1D9AB0070A902,
 				BC3B364805C9D5E200E42902,
 				BC433AD005D3046F003A5A14,
+				BE9580F805DA973B00EC5B54,
 			);
 			isa = PBXSourcesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 0;
@@ -2541,6 +2543,36 @@
 			settings = {
 			};
 		};
+		BE9580F605DA973B00EC5B54 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.cpp.cpp;
+			name = htmlediting_impl.cpp;
+			path = editing/htmlediting_impl.cpp;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		BE9580F705DA973B00EC5B54 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = sourcecode.c.h;
+			name = htmlediting_impl.h;
+			path = editing/htmlediting_impl.h;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		BE9580F805DA973B00EC5B54 = {
+			fileRef = BE9580F605DA973B00EC5B54;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		BE9580F905DA973B00EC5B54 = {
+			fileRef = BE9580F705DA973B00EC5B54;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 		BE983D95052A2E0A00892D85 = {
 			fileEncoding = 30;
 			isa = PBXFileReference;
@@ -2562,6 +2594,8 @@
 			children = (
 				BEB1DD2605C197F800DD1F43,
 				BEB1DD2505C197F800DD1F43,
+				BE9580F605DA973B00EC5B54,
+				BE9580F705DA973B00EC5B54,
 			);
 			isa = PBXGroup;
 			name = editing;
diff --git a/WebCore/khtml/editing/htmlediting.cpp b/WebCore/khtml/editing/htmlediting.cpp
index ea5fd19..050c2c8 100644
--- a/WebCore/khtml/editing/htmlediting.cpp
+++ b/WebCore/khtml/editing/htmlediting.cpp
@@ -24,52 +24,56 @@
  */
 
 #include "htmlediting.h"
+#include "htmlediting_impl.h"
 
 #if APPLE_CHANGES
 #include "KWQAssertions.h"
 #include "KWQLogging.h"
 #endif
 
-#include "khtmlview.h"
 #include "khtml_part.h"
 #include "khtml_selection.h"
 #include "dom/dom_position.h"
-#include "html/html_elementimpl.h"
-#include "rendering/render_object.h"
 #include "xml/dom_docimpl.h"
-#include "xml/dom_elementimpl.h"
 #include "xml/dom_nodeimpl.h"
-#include "xml/dom2_rangeimpl.h"
 #include "xml/dom_textimpl.h"
 
-using DOM::DocumentFragmentImpl;
 using DOM::DocumentImpl;
 using DOM::DOMPosition;
 using DOM::DOMString;
-using DOM::ElementImpl;
-using DOM::HTMLElementImpl;
-using DOM::Node;
 using DOM::NodeImpl;
-using DOM::NodeListImpl;
-using DOM::Range;
-using DOM::RangeImpl;
 using DOM::TextImpl;
 
 using khtml::AppendNodeCommand;
+using khtml::AppendNodeCommandImpl;
 using khtml::CompositeEditCommand;
+using khtml::CompositeEditCommandImpl;
 using khtml::DeleteKeyCommand;
+using khtml::DeleteKeyCommandImpl;
 using khtml::DeleteSelectionCommand;
+using khtml::DeleteSelectionCommandImpl;
 using khtml::DeleteTextCommand;
+using khtml::DeleteTextCommandImpl;
 using khtml::EditCommand;
+using khtml::EditCommandImpl;
 using khtml::InputTextCommand;
+using khtml::InputTextCommandImpl;
 using khtml::InsertNodeBeforeCommand;
+using khtml::InsertNodeBeforeCommandImpl;
 using khtml::InsertTextCommand;
+using khtml::InsertTextCommandImpl;
 using khtml::JoinTextNodesCommand;
+using khtml::JoinTextNodesCommandImpl;
 using khtml::ModifyTextNodeCommand;
+using khtml::ModifyTextNodeCommandImpl;
 using khtml::RemoveNodeCommand;
+using khtml::RemoveNodeCommandImpl;
 using khtml::MoveSelectionToCommand;
+using khtml::MoveSelectionToCommandImpl;
 using khtml::PasteHTMLCommand;
+using khtml::PasteHTMLCommandImpl;
 using khtml::SplitTextNodeCommand;
+using khtml::SplitTextNodeCommandImpl;
 
 #if !APPLE_CHANGES
 #define ASSERT(assertion) ((void)0)
@@ -79,497 +83,236 @@ using khtml::SplitTextNodeCommand;
 #define ERROR(formatAndArgs...) ((void)0)
 #endif
 
+#define IF_IMPL_NULL_RETURN_ARG(arg) do { \
+        if (isNull()) { LOG(Editing, "impl is null"); return arg; } \
+    } while (0)
+        
+#define IF_IMPL_NULL_RETURN do { \
+        if (isNull()) { LOG(Editing, "impl is null"); return; } \
+    } while (0)
+        
 //------------------------------------------------------------------------------------------
 // EditCommand
 
-EditCommand::EditCommand(DocumentImpl *document) : m_document(document), m_state(NOT_APPLIED)
+EditCommand::EditCommand() : SharedPtr<SharedCommandImpl>()
 {
-    ASSERT(m_document);
-    ASSERT(m_document->part());
-    m_document->ref();
-    m_startingSelection = m_document->part()->selection();
-    m_endingSelection = m_startingSelection;
 }
 
-EditCommand::~EditCommand()
+EditCommand::EditCommand(EditCommandImpl *impl) : SharedPtr<SharedCommandImpl>(impl)
 {
-    ASSERT(m_document);
-    m_document->deref();
 }
 
-int EditCommand::commandID() const
+EditCommand::EditCommand(const EditCommand &o) : SharedPtr<SharedCommandImpl>(o.get())
 {
-    return EditCommandID;
 }
 
-void EditCommand::reapply()
-{
-    apply();
-}
-
-inline void EditCommand::beginApply()
+EditCommand::~EditCommand()
 {
-    ASSERT(state() == NOT_APPLIED);
 }
 
-inline void EditCommand::endApply()
+int EditCommand::commandID() const
 {
-    m_state = APPLIED;
-    moveToEndingSelection();
+    IF_IMPL_NULL_RETURN_ARG(0);        
+    return get()->commandID();
 }
 
-inline void EditCommand::beginUnapply()
+QString EditCommand::name() const
 {
-    ASSERT(state() == APPLIED);
+    IF_IMPL_NULL_RETURN_ARG(QString());        
+    return get()->name();
 }
 
-inline void EditCommand::endUnapply()
+void EditCommand::apply()
 {
-    m_state = NOT_APPLIED;
-    moveToStartingSelection();
+    IF_IMPL_NULL_RETURN;
+    get()->apply();
 }
 
-inline void EditCommand::beginReapply()
+void EditCommand::unapply()
 {
-    beginApply();
+    IF_IMPL_NULL_RETURN;
+    get()->unapply();
 }
 
-inline void EditCommand::endReapply()
+void EditCommand::reapply()
 {
-    endApply();
+    IF_IMPL_NULL_RETURN;
+    get()->reapply();
 }
 
-const KHTMLSelection &EditCommand::currentSelection() const
+bool EditCommand::coalesce(const EditCommand &cmd)
 {
-    ASSERT(m_document);
-    ASSERT(m_document->part());
-    return m_document->part()->selection();
+    IF_IMPL_NULL_RETURN_ARG(false);
+    return get()->coalesce(cmd);
 }
 
-bool EditCommand::coalesce(const EditCommandPtr &cmd)
+bool EditCommand::groupForUndo(const EditCommand &cmd) const
 {
-    // default is no coalescing
-    return false;
+    IF_IMPL_NULL_RETURN_ARG(false);
+    return get()->groupForUndo(cmd);
 }
 
-bool EditCommand::groupForUndo(const EditCommandPtr &) const
+bool EditCommand::groupForRedo(const EditCommand &cmd) const
 {
-    // default is not continuing
-    return false;
+    IF_IMPL_NULL_RETURN_ARG(false);
+    return get()->groupForRedo(cmd);
 }
-
-bool EditCommand::groupForRedo(const EditCommandPtr &) const
+        
+DocumentImpl * const EditCommand::document() const
 {
-    // default is not continuing
-    return false;
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return get()->document();
 }
 
-void EditCommand::moveToStartingSelection()
+KHTMLSelection EditCommand::startingSelection() const
 {
-    ASSERT(m_document);
-    ASSERT(m_document->part());
-    m_document->part()->setSelection(m_startingSelection);
+    IF_IMPL_NULL_RETURN_ARG(KHTMLSelection());
+    return get()->startingSelection();
 }
 
-void EditCommand::moveToEndingSelection()
+KHTMLSelection EditCommand::endingSelection() const
 {
-    ASSERT(m_document);
-    ASSERT(m_document->part());
-    m_document->part()->setSelection(m_endingSelection);
+    IF_IMPL_NULL_RETURN_ARG(KHTMLSelection());
+    return get()->endingSelection();
 }
 
-QString EditCommand::name() const
+KHTMLSelection EditCommand::currentSelection() const
 {
-    switch (commandID()) {
-        case EditCommandID:
-            return "EditCommandID";
-            break;
-        case InputTextCommandID:
-            return "InputTextCommandID";
-            break;
-        case DeleteKeyCommandID:
-            return "DeleteKeyCommandID";
-            break;
-        case MoveSelectionToCommandID:
-            return "MoveSelectionToCommand";
-            break;
-    }
-    
-    ASSERT_NOT_REACHED();
-    return "";
+    IF_IMPL_NULL_RETURN_ARG(KHTMLSelection());
+    return get()->currentSelection();
 }
 
 //------------------------------------------------------------------------------------------
 // CompositeEditCommand
 
-CompositeEditCommand::CompositeEditCommand(DocumentImpl *document) 
-    : EditCommand(document)
-{
-}
-
-CompositeEditCommand::~CompositeEditCommand()
-{
-}
-
-void CompositeEditCommand::unapply()
-{
-    if (m_cmds.count() == 0) {
-        ERROR("Unapplying composite command containing zero steps");
-    }
-    for (int i = m_cmds.count() - 1; i >= 0; --i) {
-        m_cmds[i]->unapply();
-    }
-    moveToStartingSelection();
-    setState(NOT_APPLIED);
-}
-
-void CompositeEditCommand::reapply()
-{
-    if (m_cmds.count() == 0) {
-        ERROR("Reapplying composite command containing zero steps");
-    }
-    for (QValueList<EditCommandPtr>::ConstIterator it = m_cmds.begin(); it != m_cmds.end(); ++it) {
-        (*it)->reapply();
-    }
-    moveToEndingSelection();
-    setState(APPLIED);
-}
-
-//
-// sugary-sweet convenience functions to help create and apply edit commands in composite commands
-//
-void CompositeEditCommand::applyCommand(const EditCommandPtr &step)
-{
-    step->apply();
-    m_cmds.append(step);
-}
-
-void CompositeEditCommand::insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
-{
-    applyCommand(EditCommandPtr(new InsertNodeBeforeCommand(document(), insertChild, refChild)));
-}
-
-void CompositeEditCommand::insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
-{
-    if (refChild->parentNode()->lastChild() == refChild) {
-        appendNode(refChild->parentNode(), insertChild);
-    }
-    else {
-        ASSERT(refChild->nextSibling());
-        insertNodeBefore(insertChild, refChild->nextSibling());
-    }
-}
-
-void CompositeEditCommand::appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild)
-{
-    applyCommand(EditCommandPtr(new AppendNodeCommand(document(), parent, appendChild)));
-}
-
-void CompositeEditCommand::removeNode(DOM::NodeImpl *removeChild)
-{
-    applyCommand(EditCommandPtr(new RemoveNodeCommand(document(), removeChild)));
-}
-
-void CompositeEditCommand::splitTextNode(DOM::TextImpl *text, long offset)
+CompositeEditCommand::CompositeEditCommand() : EditCommand() 
 {
-    applyCommand(EditCommandPtr(new SplitTextNodeCommand(document(), text, offset)));
 }
 
-void CompositeEditCommand::joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2)
+CompositeEditCommand::CompositeEditCommand(CompositeEditCommandImpl *impl) : EditCommand(impl) 
 {
-    applyCommand(EditCommandPtr(new JoinTextNodesCommand(document(), text1, text2)));
 }
 
-void CompositeEditCommand::insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text)
+CompositeEditCommand::CompositeEditCommand(const CompositeEditCommand &o) 
+    : EditCommand(o.impl()) 
 {
-    applyCommand(EditCommandPtr(new InsertTextCommand(document(), node, offset, text)));
 }
 
-void CompositeEditCommand::deleteText(DOM::TextImpl *node, long offset, long count)
+CompositeEditCommand::~CompositeEditCommand()
 {
-    applyCommand(EditCommandPtr(new DeleteTextCommand(document(), node, offset, count)));
 }
 
-void CompositeEditCommand::moveSelectionTo(const KHTMLSelection &selection)
+CompositeEditCommandImpl *CompositeEditCommand::impl() const
 {
-    applyCommand(EditCommandPtr(new MoveSelectionToCommand(document(), selection)));
+    return static_cast<CompositeEditCommandImpl *>(get());
 }
 
-void CompositeEditCommand::moveSelectionTo(DOM::NodeImpl *node, long offset)
-{
-    applyCommand(EditCommandPtr(new MoveSelectionToCommand(document(), node, offset)));
-}
+//------------------------------------------------------------------------------------------
+// InsertNodeBeforeCommand
 
-void CompositeEditCommand::moveSelectionTo(const DOM::DOMPosition &pos)
+InsertNodeBeforeCommand::InsertNodeBeforeCommand() : EditCommand()
 {
-    applyCommand(EditCommandPtr(new MoveSelectionToCommand(document(), pos)));
 }
 
-void CompositeEditCommand::deleteSelection()
+InsertNodeBeforeCommand::InsertNodeBeforeCommand(DocumentImpl *document, NodeImpl *insertChild, NodeImpl *refChild)
+    : EditCommand(new InsertNodeBeforeCommandImpl(document, insertChild, refChild))
 {
-    if (currentSelection().state() == KHTMLSelection::RANGE) {
-        applyCommand(EditCommandPtr(new DeleteSelectionCommand(document())));
-    }
 }
 
-void CompositeEditCommand::deleteSelection(const KHTMLSelection &selection)
+InsertNodeBeforeCommand::InsertNodeBeforeCommand(const InsertNodeBeforeCommand &o)
+    : EditCommand(new InsertNodeBeforeCommandImpl(o.document(), o.insertChild(), o.refChild()))
 {
-    if (selection.state() == KHTMLSelection::RANGE) {
-        applyCommand(EditCommandPtr(new DeleteSelectionCommand(document(), selection)));
-    }
 }
 
-//------------------------------------------------------------------------------------------
-// InsertNodeBeforeCommand
-
-InsertNodeBeforeCommand::InsertNodeBeforeCommand(DocumentImpl *document, NodeImpl *insertChild, NodeImpl *refChild)
-    : EditCommand(document), m_insertChild(insertChild), m_refChild(refChild)
+InsertNodeBeforeCommand::~InsertNodeBeforeCommand()
 {
-    ASSERT(m_insertChild);
-    m_insertChild->ref();
-
-    ASSERT(m_refChild);
-    m_refChild->ref();
 }
 
-InsertNodeBeforeCommand::~InsertNodeBeforeCommand()
+InsertNodeBeforeCommandImpl *InsertNodeBeforeCommand::impl() const
 {
-    if (m_insertChild)
-        m_insertChild->deref();
-    if (m_refChild)
-        m_refChild->deref();
+    return static_cast<InsertNodeBeforeCommandImpl *>(get());
 }
 
-void InsertNodeBeforeCommand::apply()
+NodeImpl *InsertNodeBeforeCommand::insertChild() const
 {
-    beginApply();
-
-    ASSERT(m_insertChild);
-    ASSERT(m_refChild);
-    ASSERT(m_refChild->parent());
-
-    int exceptionCode;
-    m_refChild->parent()->insertBefore(m_insertChild, m_refChild, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    endApply();
+    IF_IMPL_NULL_RETURN_ARG(0);        
+    return impl()->insertChild();
 }
 
-void InsertNodeBeforeCommand::unapply()
+NodeImpl *InsertNodeBeforeCommand::refChild() const
 {
-    beginUnapply();
-
-    ASSERT(m_insertChild);
-    ASSERT(m_refChild);
-    ASSERT(m_refChild->parent());
-
-    int exceptionCode;
-    m_refChild->parent()->removeChild(m_insertChild, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    endUnapply();
+    IF_IMPL_NULL_RETURN_ARG(0);        
+    return impl()->refChild();
 }
 
 //------------------------------------------------------------------------------------------
 // AppendNodeCommand
 
 AppendNodeCommand::AppendNodeCommand(DocumentImpl *document, NodeImpl *parent, NodeImpl *appendChild)
-    : EditCommand(document), m_parent(parent), m_appendChild(appendChild)
+    : EditCommand(new AppendNodeCommandImpl(document, parent, appendChild))
 {
-    ASSERT(m_parent);
-    m_parent->ref();
-
-    ASSERT(m_appendChild);
-    m_appendChild->ref();
 }
 
 AppendNodeCommand::~AppendNodeCommand()
 {
-    if (m_parent)
-        m_parent->deref();
-    if (m_appendChild)
-        m_appendChild->deref();
 }
 
-void AppendNodeCommand::apply()
+AppendNodeCommandImpl *AppendNodeCommand::impl() const
 {
-    beginApply();
-
-    ASSERT(m_parent);
-    ASSERT(m_appendChild);
-
-    int exceptionCode;
-    m_parent->appendChild(m_appendChild, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    endApply();
+    return static_cast<AppendNodeCommandImpl *>(get());
 }
 
-void AppendNodeCommand::unapply()
+NodeImpl *AppendNodeCommand::parent() const
 {
-    beginUnapply();
-
-    ASSERT(m_parent);
-    ASSERT(m_appendChild);
-    ASSERT(state() == APPLIED);
-
-    int exceptionCode;
-    m_parent->removeChild(m_appendChild, exceptionCode);
-    ASSERT(exceptionCode == 0);
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->parent();
+}
 
-    endUnapply();
+NodeImpl *AppendNodeCommand::appendChild() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->appendChild();
 }
 
 //------------------------------------------------------------------------------------------
 // RemoveNodeCommand
 
-RemoveNodeCommand::RemoveNodeCommand(DocumentImpl *document, NodeImpl *removeChild)
-    : EditCommand(document), m_parent(0), m_removeChild(removeChild), m_refChild(0)
+RemoveNodeCommand::RemoveNodeCommand(DocumentImpl *document, NodeImpl *node)
+    : EditCommand(new RemoveNodeCommandImpl(document, node))
 {
-    ASSERT(m_removeChild);
-    m_removeChild->ref();
-
-    m_parent = m_removeChild->parentNode();
-    ASSERT(m_parent);
-    m_parent->ref();
-    
-    NodeListImpl *children = m_parent->childNodes();
-    for (int i = children->length(); i >= 0; i--) {
-        NodeImpl *node = children->item(i);
-        if (node == m_removeChild)
-            break;
-        m_refChild = node;
-    }
-    
-    if (m_refChild)
-        m_refChild->ref();
 }
 
 RemoveNodeCommand::~RemoveNodeCommand()
 {
-    if (m_parent)
-        m_parent->deref();
-    if (m_removeChild)
-        m_removeChild->deref();
-    if (m_refChild)
-        m_refChild->deref();
 }
 
-void RemoveNodeCommand::apply()
+RemoveNodeCommandImpl *RemoveNodeCommand::impl() const
 {
-    beginApply();
-
-    ASSERT(m_parent);
-    ASSERT(m_removeChild);
-
-    int exceptionCode;
-    m_parent->removeChild(m_removeChild, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    endApply();
+    return static_cast<RemoveNodeCommandImpl *>(get());
 }
 
-void RemoveNodeCommand::unapply()
+NodeImpl *RemoveNodeCommand::node() const
 {
-    beginUnapply();
-
-    ASSERT(m_parent);
-    ASSERT(m_removeChild);
-
-    int exceptionCode;
-    if (m_refChild)
-        m_parent->insertBefore(m_removeChild, m_refChild, exceptionCode);
-    else
-        m_parent->appendChild(m_removeChild, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    endUnapply();
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->node();
 }
 
 //------------------------------------------------------------------------------------------
 // ModifyTextNodeCommand
 
-ModifyTextNodeCommand::ModifyTextNodeCommand(DocumentImpl *document, TextImpl *text, long offset)
-    : EditCommand(document), m_text1(0), m_text2(text), m_offset(offset)
-{
-    ASSERT(m_text2);
-    ASSERT(m_text2->length() > 0);
-    ASSERT(m_offset >= 0);
-
-    m_text2->ref();
-}
-
-ModifyTextNodeCommand::ModifyTextNodeCommand(DocumentImpl *document, TextImpl *text1, TextImpl *text2)
-    : EditCommand(document), m_text1(text1), m_text2(text2), m_offset(0)
+ModifyTextNodeCommand::ModifyTextNodeCommand(ModifyTextNodeCommandImpl *impl) : EditCommand(impl) 
 {
-    ASSERT(m_text1);
-    ASSERT(m_text2);
-    ASSERT(m_text1->nextSibling() == m_text2);
-    ASSERT(m_text1->length() > 0);
-    ASSERT(m_text2->length() > 0);
-
-    m_text1->ref();
-    m_text2->ref();
 }
 
 ModifyTextNodeCommand::~ModifyTextNodeCommand()
 {
-    if (m_text2)
-        m_text2->deref();
-    if (m_text1)
-        m_text1->deref();
-}
-
-void ModifyTextNodeCommand::splitTextNode()
-{
-    ASSERT(m_text2);
-    ASSERT(m_text1 == 0);
-    ASSERT(m_offset > 0);
-    ASSERT(state() == splitState());
-
-    ASSERT(m_offset >= m_text2->caretMinOffset() && m_offset <= m_text2->caretMaxOffset());
-
-    int exceptionCode;
-    m_text1 = document()->createTextNode(m_text2->substringData(0, m_offset, exceptionCode));
-    ASSERT(exceptionCode == 0);
-    ASSERT(m_text1);
-    m_text1->ref();
-
-    m_text2->deleteData(0, m_offset, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    m_text2->parentNode()->insertBefore(m_text1, m_text2, exceptionCode);
-    ASSERT(exceptionCode == 0);
-        
-    ASSERT(m_text2->previousSibling()->isTextNode());
-    m_text1 = static_cast<TextImpl *>(m_text2->previousSibling());
-}
-
-void ModifyTextNodeCommand::joinTextNodes()
-{
-    ASSERT(m_text1);
-    ASSERT(m_text2);
-    ASSERT(state() == joinState());
-    
-    ASSERT(m_text1->nextSibling() == m_text2);
-
-    int exceptionCode;
-    m_text2->insertData(0, m_text1->data(), exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    m_text2->parent()->removeChild(m_text1, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    m_offset = m_text1->length();
-    m_text1->deref();
-    m_text1 = 0;
 }
 
 //------------------------------------------------------------------------------------------
 // SplitTextNodeCommand
 
 SplitTextNodeCommand::SplitTextNodeCommand(DocumentImpl *document, TextImpl *text, long offset)
-    : ModifyTextNodeCommand(document, text, offset)
+    : ModifyTextNodeCommand(new SplitTextNodeCommandImpl(document, text, offset))
 {
 }
 
@@ -577,25 +320,28 @@ SplitTextNodeCommand::~SplitTextNodeCommand()
 {
 }
 
-void SplitTextNodeCommand::apply()
+SplitTextNodeCommandImpl *SplitTextNodeCommand::impl() const
 {
-    beginApply();
-    splitTextNode();
-    endApply();
+    return static_cast<SplitTextNodeCommandImpl *>(get());
 }
 
-void SplitTextNodeCommand::unapply()
+TextImpl *SplitTextNodeCommand::node() const
 {
-    beginUnapply();
-    joinTextNodes();
-    endUnapply();
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->node();
+}
+
+long SplitTextNodeCommand::offset() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->offset();
 }
 
 //------------------------------------------------------------------------------------------
-// SplitTextNodeCommand
+// JoinTextNodesCommand
 
 JoinTextNodesCommand::JoinTextNodesCommand(DocumentImpl *document, TextImpl *text1, TextImpl *text2)
-    : ModifyTextNodeCommand(document, text1, text2)
+    : ModifyTextNodeCommand(new JoinTextNodesCommandImpl(document, text1, text2))
 {
 }
 
@@ -603,428 +349,165 @@ JoinTextNodesCommand::~JoinTextNodesCommand()
 {
 }
 
-void JoinTextNodesCommand::apply()
+JoinTextNodesCommandImpl *JoinTextNodesCommand::impl() const
+{
+    return static_cast<JoinTextNodesCommandImpl *>(get());
+}
+
+TextImpl *JoinTextNodesCommand::firstNode() const
 {
-    beginApply();
-    joinTextNodes();
-    endApply();
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->firstNode();
 }
 
-void JoinTextNodesCommand::unapply()
+TextImpl *JoinTextNodesCommand::secondNode() const
 {
-    beginUnapply();
-    splitTextNode();
-    endUnapply();
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->secondNode();
 }
 
 //------------------------------------------------------------------------------------------
 // InsertTextCommand
 
 InsertTextCommand::InsertTextCommand(DocumentImpl *document, TextImpl *node, long offset, const DOMString &text)
-    : EditCommand(document), m_node(node), m_offset(offset)
+    : EditCommand(new InsertTextCommandImpl(document, node, offset, text))
 {
-    ASSERT(m_node);
-    ASSERT(m_offset >= 0);
-    ASSERT(text.length() > 0);
-    
-    m_node->ref();
-    m_text = text.copy(); // make a copy to ensure that the string never changes
 }
 
 InsertTextCommand::~InsertTextCommand()
 {
-    if (m_node)
-        m_node->deref();
 }
 
-void InsertTextCommand::apply()
+InsertTextCommandImpl *InsertTextCommand::impl() const
 {
-    beginApply();
-
-    ASSERT(m_node);
-    ASSERT(!m_text.isEmpty());
-
-    int exceptionCode;
-    m_node->insertData(m_offset, m_text, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    endApply();
+    return static_cast<InsertTextCommandImpl *>(get());
 }
 
-void InsertTextCommand::unapply()
+TextImpl *InsertTextCommand::node() const
 {
-    beginUnapply();
-
-    ASSERT(m_node);
-    ASSERT(!m_text.isEmpty());
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->node();
+}
 
-    int exceptionCode;
-    m_node->deleteData(m_offset, m_text.length(), exceptionCode);
-    ASSERT(exceptionCode == 0);
+long InsertTextCommand::offset() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->offset();
+}
 
-    endUnapply();
+DOMString InsertTextCommand::text() const
+{
+    IF_IMPL_NULL_RETURN_ARG(DOMString());
+    return impl()->text();
 }
 
 //------------------------------------------------------------------------------------------
 // DeleteTextCommand
 
 DeleteTextCommand::DeleteTextCommand(DocumentImpl *document, TextImpl *node, long offset, long count)
-    : EditCommand(document), m_node(node), m_offset(offset), m_count(count)
+    : EditCommand(new DeleteTextCommandImpl(document, node, offset, count))
 {
-    ASSERT(m_node);
-    ASSERT(m_offset >= 0);
-    ASSERT(m_count >= 0);
-    
-    m_node->ref();
 }
 
 DeleteTextCommand::~DeleteTextCommand()
 {
-    if (m_node)
-        m_node->deref();
 }
 
-void DeleteTextCommand::apply()
+DeleteTextCommandImpl *DeleteTextCommand::impl() const
 {
-    beginApply();
-
-    ASSERT(m_node);
-
-    int exceptionCode;
-    m_text = m_node->substringData(m_offset, m_count, exceptionCode);
-    ASSERT(exceptionCode == 0);
-    
-    m_node->deleteData(m_offset, m_count, exceptionCode);
-    ASSERT(exceptionCode == 0);
-
-    endApply();
+    return static_cast<DeleteTextCommandImpl *>(get());
 }
 
-void DeleteTextCommand::unapply()
+TextImpl *DeleteTextCommand::node() const
 {
-    beginUnapply();
-
-    ASSERT(m_node);
-    ASSERT(!m_text.isEmpty());
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->node();
+}
 
-    int exceptionCode;
-    m_node->insertData(m_offset, m_text, exceptionCode);
-    ASSERT(exceptionCode == 0);
+long DeleteTextCommand::offset() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->offset();
+}
 
-    endUnapply();
+long DeleteTextCommand::count() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->count();
 }
 
 //------------------------------------------------------------------------------------------
 // MoveSelectionToCommand
 
 MoveSelectionToCommand::MoveSelectionToCommand(DocumentImpl *document, const KHTMLSelection &selection)
-    : EditCommand(document)
+    : EditCommand(new MoveSelectionToCommandImpl(document, selection))
 {
-    setEndingSelection(selection);
 }
 
-MoveSelectionToCommand::MoveSelectionToCommand(DocumentImpl *document, DOM::NodeImpl *node, long offset)
-    : EditCommand(document)
+MoveSelectionToCommand::MoveSelectionToCommand(DocumentImpl *document, NodeImpl *node, long offset)
+    : EditCommand(new MoveSelectionToCommandImpl(document, node, offset))
 {
-    KHTMLSelection selection(node, offset);
-    setEndingSelection(selection);
 }
 
 MoveSelectionToCommand::MoveSelectionToCommand(DOM::DocumentImpl *document, const DOM::DOMPosition &pos)
-    : EditCommand(document)
+    : EditCommand(new MoveSelectionToCommandImpl(document, pos))
 {
-    KHTMLSelection selection(pos);
-    setEndingSelection(selection);
 }
 
 MoveSelectionToCommand::~MoveSelectionToCommand() 
 {
 }
 
-int MoveSelectionToCommand::commandID() const
-{
-    return MoveSelectionToCommandID;
-}
-
-
-void MoveSelectionToCommand::apply()
+MoveSelectionToCommandImpl *MoveSelectionToCommand::impl() const
 {
-    beginApply();
-    endApply();
-}
-
-void MoveSelectionToCommand::unapply()
-{
-    beginUnapply();
-    endUnapply();
+    return static_cast<MoveSelectionToCommandImpl *>(get());
 }
 
 //------------------------------------------------------------------------------------------
 // DeleteSelectionCommand
 
 DeleteSelectionCommand::DeleteSelectionCommand(DOM::DocumentImpl *document)
-    : CompositeEditCommand(document)
-{
-}
-
-DeleteSelectionCommand::DeleteSelectionCommand(DOM::DocumentImpl *document, const KHTMLSelection &selection)
-    : CompositeEditCommand(document)
+    : CompositeEditCommand(new DeleteSelectionCommandImpl(document))
 {
-    setStartingSelection(selection);
 }
 
 DeleteSelectionCommand::~DeleteSelectionCommand()
 {
 }
 	
-void DeleteSelectionCommand::apply()
-{
-    beginApply();
-
-    if (startingSelection().isEmpty()) {
-        endApply();
-        return;
-    }
-
-    KHTMLSelection selection = startingSelection();
-
-    //
-    // Figure out where to place the caret after doing the delete:
-    //
-    // 1. If the start node is not completely selected, use the start 
-    //    node and start offset for the new position; else
-    // 2. If the start and end nodes are completely selected:
-    //       a. If there is an editable node following the end node, 
-    //          place the caret in the min caret offset of that node; else
-    //       b. If there is an editable node before the start node, 
-    //          place the caret in the max caret offset of that node; else
-    //       c. There is no more editable content in the document.
-    //          EDIT FIXME: We do not handle this case now
-    // 3. If the start node is completely selected and the end node is 
-    //    different than the start node and it is not completely selected,
-    //    use the end node and the end node min caret for the new position; else
-    //
-
-    DOMPosition deleteStart = DOMPosition(selection.startNode(), selection.startOffset());
-    DOMPosition deleteEnd = DOMPosition(selection.endNode(), selection.endOffset());
-
-    bool startIsCompletelySelected = 
-        deleteStart.offset() == deleteStart.node()->caretMinOffset() &&
-        ((deleteStart.node() != deleteEnd.node()) ||
-         (deleteEnd.offset() == deleteEnd.node()->caretMaxOffset()));
-
-    bool endIsCompletelySelected = 
-        deleteEnd.offset() == deleteEnd.node()->caretMaxOffset() &&
-        ((deleteStart.node() != deleteEnd.node()) ||
-         (deleteStart.offset() == deleteStart.node()->caretMinOffset()));
-
-    DOMPosition endingPosition;
-
-    if (!startIsCompletelySelected) {
-        // Case 1
-        endingPosition = DOMPosition(deleteStart.node(), deleteStart.offset());
-    }
-    else if (endIsCompletelySelected) {
-        DOMPosition pos = selection.nextCharacterPosition(deleteEnd);
-        if (pos != deleteEnd) {
-            // Case 2a
-            endingPosition = DOMPosition(pos.node(), pos.node()->caretMinOffset());
-        }
-        else {
-            pos = selection.previousCharacterPosition(deleteStart);
-            if (pos != deleteStart) {
-                // Case 2b
-                endingPosition = DOMPosition(pos.node(), pos.node()->caretMaxOffset());
-            }
-            else {
-                // Case 2c
-                // EDIT FIXME
-                endingPosition = DOMPosition();
-            }
-        }
-    }
-    else {
-        // Case 3
-        endingPosition = DOMPosition(deleteEnd.node(), deleteEnd.node()->caretMinOffset());
-    }
-
-    //
-    // Do the delete
-    //
-    NodeImpl *n = deleteStart.node()->nextLeafNode();
-
-    // work on start node
-    if (startIsCompletelySelected) {
-        removeNode(deleteStart.node());
-    }
-    else if (deleteStart.node()->isTextNode()) {
-        TextImpl *text = static_cast<TextImpl *>(deleteStart.node());
-        int endOffset = text == deleteEnd.node() ? deleteEnd.offset() : text->length();
-        if (endOffset > deleteStart.offset()) {
-            deleteText(text, deleteStart.offset(), endOffset - deleteStart.offset());
-        }
-    }
-    else {
-        ASSERT_NOT_REACHED();
-    }
-
-    if (deleteStart.node() != deleteEnd.node()) {
-        // work on intermediate nodes
-        while (n != deleteEnd.node()) {
-            NodeImpl *d = n;
-            n = n->nextLeafNode();
-            removeNode(d);
-        }
-        
-        // work on end node
-        ASSERT(n == deleteEnd.node());
-        if (endIsCompletelySelected) {
-            removeNode(deleteEnd.node());
-        }
-        else if (deleteEnd.node()->isTextNode()) {
-            if (deleteEnd.offset() > 0) {
-                TextImpl *text = static_cast<TextImpl *>(deleteEnd.node());
-                deleteText(text, 0, deleteEnd.offset());
-            }
-        }
-        else {
-            ASSERT_NOT_REACHED();
-        }
-    }
-
-    //
-    // set the ending selection
-    //
-    selection.moveTo(endingPosition);
-    selection.moveToRenderedContent();
-    setEndingSelection(selection);
-
-    endApply();
+DeleteSelectionCommandImpl *DeleteSelectionCommand::impl() const
+{
+    return static_cast<DeleteSelectionCommandImpl *>(get());
 }
 
 //------------------------------------------------------------------------------------------
 // InputTextCommand
 
 InputTextCommand::InputTextCommand(DocumentImpl *document, const DOMString &text) 
-    : CompositeEditCommand(document)
+    : CompositeEditCommand(new InputTextCommandImpl(document, text))
 {
-    ASSERT(!text.isEmpty());
-    m_text = text; 
 }
 
 InputTextCommand::~InputTextCommand() 
 {
 }
 
-int InputTextCommand::commandID() const
-{
-    return InputTextCommandID;
-}
-
-bool InputTextCommand::isLineBreak(const DOM::DOMString &text) const
-{
-    return text.length() == 1 && (text[0] == '\n' || text[0] == '\r');
-}
-
-bool InputTextCommand::isSpace(const DOM::DOMString &text) const
-{
-    return text.length() == 1 && (text[0] == ' ');
-}
-
-void InputTextCommand::apply()
-{
-    beginApply();
-    execute(m_text);
-    endApply();
-}
-
-bool InputTextCommand::coalesce(const EditCommandPtr &cmd)
-{
-    ASSERT(state() == APPLIED);
-    
-    if (cmd->commandID() == InputTextCommandID && endingSelection() == cmd->startingSelection()) {
-        // InputTextCommands coalesce with each other if they 
-        const InputTextCommand *c = static_cast<const InputTextCommand *>(cmd.get());
-        execute(c->text());
-        m_text += c->text();
-        moveToEndingSelection();
-        return true;
-    }
-
-    return false;
-}
-
-bool InputTextCommand::groupForUndo(const EditCommandPtr &cmd) const
-{
-    if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && startingSelection() == cmd->endingSelection()) {
-        return true;
-    }
-    return false;
-}
-
-bool InputTextCommand::groupForRedo(const EditCommandPtr &cmd) const
+InputTextCommandImpl *InputTextCommand::impl() const
 {
-    if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && endingSelection() == cmd->startingSelection()) {
-        return true;
-    }
-    return false;
+    return static_cast<InputTextCommandImpl *>(get());
 }
 
-void InputTextCommand::execute(const DOM::DOMString &text)
+DOMString InputTextCommand::text() const
 {
-    KHTMLSelection selection = currentSelection();
-
-    if (!selection.startNode()->isTextNode())
-        return;
-
-    // Delete the current selection
-    deleteSelection();
-    
-    TextImpl *textNode = static_cast<TextImpl *>(selection.startNode());
-    
-    if (isLineBreak(text)) {
-        int exceptionCode;
-        ElementImpl *breakNode = document()->createHTMLElement("BR", exceptionCode);
-
-        bool atStart = selection.startOffset() == textNode->renderer()->caretMinOffset();
-        bool atEnd = selection.startOffset() == textNode->renderer()->caretMaxOffset();
-        if (atStart) {
-            // Set the cursor at the beginning of text node now following the new BR.
-            insertNodeBefore(breakNode, textNode);
-            selection = KHTMLSelection(textNode, 0);
-            setEndingSelection(selection);
-        }
-        else if (atEnd) {
-            insertNodeAfter(breakNode, textNode);
-            // Set the cursor at the beginning of the the BR.
-            selection = selection.nextCharacterPosition();
-            setEndingSelection(selection);
-        }
-        else {
-            TextImpl *textBeforeNode = document()->createTextNode(textNode->substringData(0, selection.startOffset(), exceptionCode));
-            deleteText(textNode, 0, selection.startOffset());
-            insertNodeBefore(textBeforeNode, textNode);
-            insertNodeBefore(breakNode, textNode);
-            textBeforeNode->deref();
-            // Set the cursor at the beginning of the node after the BR.
-            selection = KHTMLSelection(textNode, 0);
-            setEndingSelection(selection);
-        }
-        
-        breakNode->deref();
-    }
-    else {
-        insertText(textNode, selection.startOffset(), text);
-        selection = KHTMLSelection(selection.startNode(), selection.startOffset() + text.length());
-        setEndingSelection(selection);
-    }
+    IF_IMPL_NULL_RETURN_ARG(DOMString());
+    return impl()->text();
 }
 
 //------------------------------------------------------------------------------------------
 // DeleteKeyCommand
 
 DeleteKeyCommand::DeleteKeyCommand(DocumentImpl *document) 
-    : CompositeEditCommand(document)
+    : CompositeEditCommand(new DeleteKeyCommandImpl(document))
 {
 }
 
@@ -1032,167 +515,31 @@ DeleteKeyCommand::~DeleteKeyCommand()
 {
 }
 
-int DeleteKeyCommand::commandID() const
+DeleteKeyCommandImpl *DeleteKeyCommand::impl() const
 {
-    return DeleteKeyCommandID;
+    return static_cast<DeleteKeyCommandImpl *>(get());
 }
 
-void DeleteKeyCommand::apply()
-{
-    beginApply();
-
-    KHTMLPart *part = document()->part();
-    ASSERT(part);
-
-    KHTMLSelection selection = part->selection();
-    ASSERT(!selection.isEmpty());
-
-    // Delete the current selection
-    if (selection.state() == KHTMLSelection::RANGE) {
-        deleteSelection();
-        endApply();
-        return;
-    }
-
-    NodeImpl *caretNode = selection.startNode();
+//------------------------------------------------------------------------------------------
+// PasteHTMLCommand
 
-    if (caretNode->isTextNode()) {
-        // Check if we can delete character at cursor
-        int offset = selection.startOffset() - 1;
-        if (offset >= caretNode->caretMinOffset()) {
-            TextImpl *textNode = static_cast<TextImpl *>(caretNode);
-            deleteText(textNode, offset, 1);
-            selection = KHTMLSelection(textNode, offset);
-            setEndingSelection(selection);
-            endApply();
-            return;
-        }
-        
-        // Check if previous sibling is a BR element
-        NodeImpl *previousSibling = caretNode->previousSibling();
-        if (previousSibling->renderer() && previousSibling->renderer()->isBR()) {
-            removeNode(previousSibling);
-            endApply();
-            return;
-        }
-        
-        // Check if previous leaf node is a text node
-        NodeImpl *previousLeafNode = caretNode->previousLeafNode();
-        if (previousLeafNode->isTextNode()) {
-            TextImpl *textNode = static_cast<TextImpl *>(previousLeafNode);
-            offset = previousLeafNode->caretMaxOffset() - 1;
-            deleteText(textNode, offset, 1);
-            selection = KHTMLSelection(textNode, offset);
-            setEndingSelection(selection);
-            endApply();
-            return;
-        }
-    }
+PasteHTMLCommand::PasteHTMLCommand(DocumentImpl *document, const DOMString &HTMLString) 
+    : CompositeEditCommand(new PasteHTMLCommandImpl(document, HTMLString))
+{
 }
 
-bool DeleteKeyCommand::groupForUndo(const EditCommandPtr &cmd) const
+PasteHTMLCommand::~PasteHTMLCommand() 
 {
-    if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && startingSelection() == cmd->endingSelection()) {
-        return true;
-    }
-
-    return false;
 }
 
-bool DeleteKeyCommand::groupForRedo(const EditCommandPtr &cmd) const
+PasteHTMLCommandImpl *PasteHTMLCommand::impl() const
 {
-    if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && endingSelection() == cmd->startingSelection()) {
-        return true;
-    }
-
-    return false;
+    return static_cast<PasteHTMLCommandImpl *>(get());
 }
 
-PasteHTMLCommand::PasteHTMLCommand(DocumentImpl *document, const DOMString &HTMLString) 
-    : CompositeEditCommand(document)
-{
-    ASSERT(!HTMLString.isEmpty());
-    m_HTMLString = HTMLString; 
-}
-
-PasteHTMLCommand::~PasteHTMLCommand()
-{
-}
-
-void PasteHTMLCommand::apply()
-{
-    beginApply();
-    
-    DOM::DocumentFragmentImpl *root = static_cast<HTMLElementImpl *>(document()->documentElement())->createContextualFragment(m_HTMLString);
-    ASSERT(root);
-    
-    DOM::NodeImpl *firstChild = root->firstChild();
-    DOM::NodeImpl *lastChild = root->lastChild();
-    ASSERT(firstChild);
-    ASSERT(lastChild);
-    
-    deleteSelection();
-    
-    KHTMLPart *part = document()->part();
-    ASSERT(part);
-    
-    KHTMLSelection selection = part->selection();
-    ASSERT(!selection.isEmpty());
-    
-    DOM::NodeImpl *startNode = selection.startNode();
-    long startOffset = selection.startOffset();
-    TextImpl *textNode = startNode->isTextNode() ? static_cast<TextImpl *>(startNode) : NULL;
-
-    if (textNode && firstChild == lastChild && firstChild->isTextNode()) {
-        // Simple text paste. Add the text to the text node with the caret.
-        insertText(textNode, startOffset, static_cast<TextImpl *>(firstChild)->data());
-        selection = KHTMLSelection(textNode, startOffset + static_cast<TextImpl *>(firstChild)->length());
-        setEndingSelection(selection);
-    } 
-    else {
-        // HTML tree paste.
-        DOM::NodeImpl *child = firstChild;
-        DOM::NodeImpl *beforeNode = NULL;
-        if (startNode->caretMinOffset() == startOffset) {
-            // Caret is at the beginning of the node. Insert before it.
-            DOM::NodeImpl *nextSibling = child->nextSibling();
-            insertNodeBefore(child, startNode);
-            beforeNode = child;
-            child = nextSibling;
-        } 
-        else if (textNode && textNode->caretMaxOffset() != startOffset) {
-            // Caret is in middle of a text node. Split the text node and insert in between.
-            splitTextNode(textNode, startOffset);
-            beforeNode = textNode->previousSibling();
-        } 
-        else {
-            // Caret is at the end of the node. Insert after it.
-            beforeNode = startNode;
-        }
-        
-        ASSERT(beforeNode);
-		
-        // Insert the nodes from the clipping.
-        while (child) {
-            DOM::NodeImpl *nextSibling = child->nextSibling();
-            insertNodeAfter(child, beforeNode);
-            beforeNode = child;
-            child = nextSibling;
-        }
-		
-		// Find the last leaf and place the caret after it.
-        child = lastChild;
-        while (1) {
-            DOM::NodeImpl *nextChild = child->lastChild();
-            if (!nextChild) {
-                break;
-            }
-            child = nextChild;
-        }
-        selection = KHTMLSelection(child, child->caretMaxOffset());
-        setEndingSelection(selection);
-    }
-
-    endApply();
+DOMString PasteHTMLCommand::HTMLString() const
+{
+    IF_IMPL_NULL_RETURN_ARG(DOMString());
+    return impl()->HTMLString();
 }
 
diff --git a/WebCore/khtml/editing/htmlediting.h b/WebCore/khtml/editing/htmlediting.h
index 8390655..82948a9 100644
--- a/WebCore/khtml/editing/htmlediting.h
+++ b/WebCore/khtml/editing/htmlediting.h
@@ -30,13 +30,11 @@
 #include <dom_position.h>
 #include <dom_string.h>
 
-#include <qvaluelist.h>
 #include <shared.h>
 
 class KHTMLSelection;
 
 namespace DOM {
-    class DocumentFragmentImpl;
     class DocumentImpl;
     class DOMPosition;
     class DOMString;
@@ -46,114 +44,122 @@ namespace DOM {
 
 namespace khtml {
 
+class AppendNodeCommandImpl;
+class CompositeEditCommandImpl;
+class DeleteKeyCommandImpl;
+class DeleteSelectionCommandImpl;
+class DeleteTextCommandImpl;
+class EditCommandImpl;
+class InputTextCommandImpl;
+class InsertNodeBeforeCommandImpl;
+class InsertTextCommandImpl;
+class JoinTextNodesCommandImpl;
+class ModifyTextNodeCommandImpl;
+class RemoveNodeCommandImpl;
+class MoveSelectionToCommandImpl;
+class PasteHTMLCommandImpl;
+class SplitTextNodeCommandImpl;
+
 //------------------------------------------------------------------------------------------
 // EditCommand classes
 
-class EditCommand;
-
-typedef SharedPtr<EditCommand> EditCommandPtr;
-
-enum EditCommandID { 
-    EditCommandID, 
-    InputTextCommandID, 
+enum ECommandID { 
+    EditCommandID, // leave the base class first, others in alpha order
+    AppendNodeCommandID,
+    CompositeEditCommandID,
     DeleteKeyCommandID,
-    MoveSelectionToCommandID, 
+    DeleteSelectionCommandID,
+    DeleteTextCommandID,
+    InputTextCommandID,
+    InsertNodeBeforeCommandID,
+    InsertTextCommandID,
+    JoinTextNodesCommandID,
+    ModifyTextNodeCommandID,
+    RemoveNodeCommandID,
+    MoveSelectionToCommandID,
+    PasteHTMLCommandID,
+    SplitTextNodeCommandID,
 };
 
-class EditCommand : public Shared<EditCommand>
+class EditCommand;
+
+class SharedCommandImpl : public Shared<SharedCommandImpl>
 {
 public:
-	EditCommand(DOM::DocumentImpl *);
-	virtual ~EditCommand();
+	SharedCommandImpl() {}
+	virtual ~SharedCommandImpl() {}
 
-    virtual int commandID() const;
-	QString name() const;
+    virtual int commandID() const = 0;
+	virtual QString name() const = 0;
 
-    enum EditCommandState { NOT_APPLIED, APPLIED };
-    
 	virtual void apply() = 0;	
 	virtual void unapply() = 0;
-	virtual void reapply();  // calls apply()
+	virtual void reapply() = 0;
 
-    virtual bool coalesce(const EditCommandPtr &);
+    virtual bool coalesce(const EditCommand &) = 0;
 
-    virtual bool groupForUndo(const EditCommandPtr &) const;
-    virtual bool groupForRedo(const EditCommandPtr &) const;
+    virtual bool groupForUndo(const EditCommand &) const = 0;
+    virtual bool groupForRedo(const EditCommand &) const = 0;
             
-    DOM::DocumentImpl * const document() const { return m_document; }
-
-    const KHTMLSelection &startingSelection() const { return m_startingSelection; }
-    const KHTMLSelection &endingSelection() const { return m_endingSelection; }
-    const KHTMLSelection &currentSelection() const;
-        
-protected:
-    void beginApply();
-    void endApply();
-    void beginUnapply();
-    void endUnapply();
-    void beginReapply();
-    void endReapply();
-    
-    EditCommandState state() const { return m_state; }
-    void setState(EditCommandState state) { m_state = state; }
+    virtual DOM::DocumentImpl * const document() const = 0;
+
+    virtual KHTMLSelection startingSelection() const = 0;
+    virtual KHTMLSelection endingSelection() const = 0;
+    virtual KHTMLSelection currentSelection() const = 0;
+};
+
+class EditCommand : public SharedPtr<SharedCommandImpl>
+{
+public:
+	EditCommand();
+	EditCommand(EditCommandImpl *);
+	EditCommand(const EditCommand &);
+	virtual ~EditCommand();
 
-    void setStartingSelection(const KHTMLSelection &s) { m_startingSelection = s; }
-    void setEndingSelection(const KHTMLSelection &s) { m_endingSelection = s; }
+    int commandID() const;
+	QString name() const;
 
-    void moveToStartingSelection();
-    void moveToEndingSelection();
+	void apply();	
+	void unapply();
+	void reapply();
 
-private:
-    DOM::DocumentImpl *m_document;
-    EditCommandState m_state;
-    KHTMLSelection m_startingSelection;
-    KHTMLSelection m_endingSelection;
+    bool coalesce(const EditCommand &);
+
+    bool groupForUndo(const EditCommand &) const;
+    bool groupForRedo(const EditCommand &) const;
+            
+    DOM::DocumentImpl * const document() const;
+
+    KHTMLSelection startingSelection() const;
+    KHTMLSelection endingSelection() const;
+    KHTMLSelection currentSelection() const;
 };
 
 class CompositeEditCommand : public EditCommand
 {
 public:
-	CompositeEditCommand(DOM::DocumentImpl *);
+	CompositeEditCommand();
+	CompositeEditCommand(CompositeEditCommandImpl *);
+	CompositeEditCommand(const CompositeEditCommand &);
 	virtual ~CompositeEditCommand();
-	
-	virtual void apply() = 0;	
-	virtual void unapply();
-	virtual void reapply();
-    
-protected:
-    //
-    // sugary-sweet convenience functions to help create and apply edit commands in composite commands
-    //
-    void applyCommand(const EditCommandPtr &step);
-    void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
-    void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
-    void appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
-    void removeNode(DOM::NodeImpl *removeChild);
-    void splitTextNode(DOM::TextImpl *text, long offset);
-    void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
-    void insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
-    void deleteText(DOM::TextImpl *node, long offset, long count);
-    void moveSelectionTo(const KHTMLSelection &selection);
-	void moveSelectionTo(DOM::NodeImpl *, long);
-	void moveSelectionTo(const DOM::DOMPosition &);
-    void deleteSelection();
-    void deleteSelection(const KHTMLSelection &selection);
-
-    QValueList<EditCommandPtr> m_cmds;
+
+private:
+    inline CompositeEditCommandImpl *impl() const;
 };
 
 class InsertNodeBeforeCommand : public EditCommand
 {
 public:
+    InsertNodeBeforeCommand();
     InsertNodeBeforeCommand(DOM::DocumentImpl *, DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
-	virtual ~InsertNodeBeforeCommand();
-
-	virtual void apply();
-	virtual void unapply();
+    InsertNodeBeforeCommand(const InsertNodeBeforeCommand &);
+    virtual ~InsertNodeBeforeCommand();
 
+    DOM::NodeImpl *insertChild() const;
+    DOM::NodeImpl *refChild() const;
+    
 private:
-    DOM::NodeImpl *m_insertChild;
-    DOM::NodeImpl *m_refChild;    
+    inline InsertNodeBeforeCommandImpl *impl() const;
 };
 
 class AppendNodeCommand : public EditCommand
@@ -162,48 +168,30 @@ public:
     AppendNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
 	virtual ~AppendNodeCommand();
 
-	virtual void apply();
-	virtual void unapply();
-
+    DOM::NodeImpl *parent() const;
+    DOM::NodeImpl *appendChild() const;
+    
 private:
-    DOM::NodeImpl *m_parent;    
-    DOM::NodeImpl *m_appendChild;
+    inline AppendNodeCommandImpl *impl() const;
 };
 
 class RemoveNodeCommand : public EditCommand
 {
 public:
-	RemoveNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *);
+	RemoveNodeCommand(DOM::DocumentImpl *, DOM::NodeImpl *node);
 	virtual ~RemoveNodeCommand();
-	
-	virtual void apply();
-	virtual void unapply();
 
+    DOM::NodeImpl *node() const;
+    
 private:
-    DOM::NodeImpl *m_parent;    
-    DOM::NodeImpl *m_removeChild;
-    DOM::NodeImpl *m_refChild;    
+    inline RemoveNodeCommandImpl *impl() const;
 };
 
 class ModifyTextNodeCommand : public EditCommand
 {
 public:
-    // used by SplitTextNodeCommand derived class
-	ModifyTextNodeCommand(DOM::DocumentImpl *, DOM::TextImpl *, long); 
-    // used by JoinTextNodesCommand derived class
-    ModifyTextNodeCommand(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
+    ModifyTextNodeCommand(ModifyTextNodeCommandImpl *);
 	virtual ~ModifyTextNodeCommand();
-	
-protected:
-    void splitTextNode();
-    void joinTextNodes();
-
-    virtual EditCommandState joinState() = 0;
-    virtual EditCommandState splitState() = 0;
-
-    DOM::TextImpl *m_text1;
-    DOM::TextImpl *m_text2;
-    long m_offset;
 };
 
 class SplitTextNodeCommand : public ModifyTextNodeCommand
@@ -211,12 +199,12 @@ class SplitTextNodeCommand : public ModifyTextNodeCommand
 public:
 	SplitTextNodeCommand(DOM::DocumentImpl *, DOM::TextImpl *, long);
 	virtual ~SplitTextNodeCommand();
-	
-	virtual void apply();
-	virtual void unapply();
 
-    virtual EditCommandState joinState() { return APPLIED; }
-    virtual EditCommandState splitState() { return NOT_APPLIED; }
+    DOM::TextImpl *node() const;
+    long offset() const;
+    
+private:
+    inline SplitTextNodeCommandImpl *impl() const;
 };
 
 class JoinTextNodesCommand : public ModifyTextNodeCommand
@@ -224,12 +212,12 @@ class JoinTextNodesCommand : public ModifyTextNodeCommand
 public:
 	JoinTextNodesCommand(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
 	virtual ~JoinTextNodesCommand();
-	
-	virtual void apply();
-	virtual void unapply();
 
-    virtual EditCommandState joinState() { return NOT_APPLIED; }
-    virtual EditCommandState splitState() { return APPLIED; }
+    DOM::TextImpl *firstNode() const;
+    DOM::TextImpl *secondNode() const;
+    
+private:
+    inline JoinTextNodesCommandImpl *impl() const;
 };
 
 class InsertTextCommand : public EditCommand
@@ -237,14 +225,13 @@ class InsertTextCommand : public EditCommand
 public:
 	InsertTextCommand(DOM::DocumentImpl *document, DOM::TextImpl *, long, const DOM::DOMString &);
 	virtual ~InsertTextCommand();
-	
-	virtual void apply();
-	virtual void unapply();
+
+    DOM::TextImpl *node() const;
+    long offset() const;
+    DOM::DOMString text() const;
 
 private:
-    DOM::TextImpl *m_node;
-    long m_offset;
-    DOM::DOMString m_text;
+    inline InsertTextCommandImpl *impl() const;
 };
 
 class DeleteTextCommand : public EditCommand
@@ -252,15 +239,13 @@ class DeleteTextCommand : public EditCommand
 public:
 	DeleteTextCommand(DOM::DocumentImpl *document, DOM::TextImpl *, long offset, long count);
 	virtual ~DeleteTextCommand();
-	
-	virtual void apply();
-	virtual void unapply();
+
+    DOM::TextImpl *node() const;
+    long offset() const;
+    long count() const;
 
 private:
-    DOM::TextImpl *m_node;
-    long m_offset;
-    long m_count;
-    DOM::DOMString m_text;
+    inline DeleteTextCommandImpl *impl() const;
 };
 
 class MoveSelectionToCommand : public EditCommand
@@ -271,20 +256,18 @@ public:
 	MoveSelectionToCommand(DOM::DocumentImpl *document, const DOM::DOMPosition &);
 	virtual ~MoveSelectionToCommand();
 
-    virtual int commandID() const;
-	
-	virtual void apply();
-	virtual void unapply();
+private:
+    inline MoveSelectionToCommandImpl *impl() const;
 };
 
 class DeleteSelectionCommand : public CompositeEditCommand
 {
 public:
 	DeleteSelectionCommand(DOM::DocumentImpl *document);
-	DeleteSelectionCommand(DOM::DocumentImpl *document, const KHTMLSelection &);
 	virtual ~DeleteSelectionCommand();
-	
-	virtual void apply();
+
+private:
+    inline DeleteSelectionCommandImpl *impl() const;
 };
 
 class InputTextCommand : public CompositeEditCommand
@@ -293,23 +276,10 @@ public:
     InputTextCommand(DOM::DocumentImpl *document, const DOM::DOMString &text);
     virtual ~InputTextCommand();
 
-    virtual int commandID() const;
-
-    virtual void apply();
+    DOM::DOMString text() const;
 
-    virtual bool coalesce(const EditCommandPtr &);
-
-    virtual bool groupForUndo(const EditCommandPtr &) const;
-    virtual bool groupForRedo(const EditCommandPtr &) const;
-
-    DOM::DOMString text() const { return m_text; }
-    bool isLineBreak(const DOM::DOMString &text) const;
-    bool isSpace(const DOM::DOMString &text) const;
-    
 private:
-    void execute(const DOM::DOMString &text);
-
-    DOM::DOMString m_text;
+    inline InputTextCommandImpl *impl() const;
 };
 
 class DeleteKeyCommand : public CompositeEditCommand
@@ -317,13 +287,9 @@ class DeleteKeyCommand : public CompositeEditCommand
 public:
     DeleteKeyCommand(DOM::DocumentImpl *document);
     virtual ~DeleteKeyCommand();
-    
-    virtual int commandID() const;
-
-    virtual void apply();
 
-    virtual bool groupForUndo(const EditCommandPtr &) const;
-    virtual bool groupForRedo(const EditCommandPtr &) const;
+private:
+    inline DeleteKeyCommandImpl *impl() const;
 };
 
 class PasteHTMLCommand : public CompositeEditCommand
@@ -331,11 +297,11 @@ class PasteHTMLCommand : public CompositeEditCommand
 public:
     PasteHTMLCommand(DOM::DocumentImpl *document, const DOM::DOMString &HTMLString);
     virtual ~PasteHTMLCommand();
-    
-    virtual void apply();
+
+    DOM::DOMString HTMLString() const;
 
 private:
-    DOM::DOMString m_HTMLString;
+    inline PasteHTMLCommandImpl *impl() const;
 };
 
 }; // end namespace khtml
diff --git a/WebCore/khtml/editing/htmlediting.cpp b/WebCore/khtml/editing/htmlediting_impl.cpp
similarity index 69%
copy from WebCore/khtml/editing/htmlediting.cpp
copy to WebCore/khtml/editing/htmlediting_impl.cpp
index ea5fd19..0aaf73c 100644
--- a/WebCore/khtml/editing/htmlediting.cpp
+++ b/WebCore/khtml/editing/htmlediting_impl.cpp
@@ -23,7 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include "htmlediting.h"
+#include "htmlediting_impl.h"
 
 #if APPLE_CHANGES
 #include "KWQAssertions.h"
@@ -56,20 +56,35 @@ using DOM::RangeImpl;
 using DOM::TextImpl;
 
 using khtml::AppendNodeCommand;
+using khtml::AppendNodeCommandImpl;
 using khtml::CompositeEditCommand;
+using khtml::CompositeEditCommandImpl;
 using khtml::DeleteKeyCommand;
+using khtml::DeleteKeyCommandImpl;
 using khtml::DeleteSelectionCommand;
+using khtml::DeleteSelectionCommandImpl;
 using khtml::DeleteTextCommand;
+using khtml::DeleteTextCommandImpl;
 using khtml::EditCommand;
+using khtml::EditCommandImpl;
 using khtml::InputTextCommand;
+using khtml::InputTextCommandImpl;
 using khtml::InsertNodeBeforeCommand;
+using khtml::InsertNodeBeforeCommandImpl;
 using khtml::InsertTextCommand;
+using khtml::InsertTextCommandImpl;
 using khtml::JoinTextNodesCommand;
+using khtml::JoinTextNodesCommandImpl;
 using khtml::ModifyTextNodeCommand;
+using khtml::ModifyTextNodeCommandImpl;
 using khtml::RemoveNodeCommand;
+using khtml::RemoveNodeCommandImpl;
 using khtml::MoveSelectionToCommand;
+using khtml::MoveSelectionToCommandImpl;
 using khtml::PasteHTMLCommand;
+using khtml::PasteHTMLCommandImpl;
 using khtml::SplitTextNodeCommand;
+using khtml::SplitTextNodeCommandImpl;
 
 #if !APPLE_CHANGES
 #define ASSERT(assertion) ((void)0)
@@ -80,9 +95,10 @@ using khtml::SplitTextNodeCommand;
 #endif
 
 //------------------------------------------------------------------------------------------
-// EditCommand
+// EditCommandImpl
 
-EditCommand::EditCommand(DocumentImpl *document) : m_document(document), m_state(NOT_APPLIED)
+EditCommandImpl::EditCommandImpl(DocumentImpl *document) 
+    : SharedCommandImpl(), m_document(document), m_state(NotApplied)
 {
     ASSERT(m_document);
     ASSERT(m_document->part());
@@ -91,107 +107,141 @@ EditCommand::EditCommand(DocumentImpl *document) : m_document(document), m_state
     m_endingSelection = m_startingSelection;
 }
 
-EditCommand::~EditCommand()
+EditCommandImpl::~EditCommandImpl()
 {
     ASSERT(m_document);
     m_document->deref();
+    fprintf(stderr, "~EditCommandImpl\n");
 }
 
-int EditCommand::commandID() const
+int EditCommandImpl::commandID() const
 {
     return EditCommandID;
 }
 
-void EditCommand::reapply()
+void EditCommandImpl::reapply()
 {
     apply();
 }
 
-inline void EditCommand::beginApply()
+inline void EditCommandImpl::beginApply()
 {
-    ASSERT(state() == NOT_APPLIED);
+    ASSERT(state() == NotApplied);
 }
 
-inline void EditCommand::endApply()
+inline void EditCommandImpl::endApply()
 {
-    m_state = APPLIED;
+    m_state = Applied;
     moveToEndingSelection();
 }
 
-inline void EditCommand::beginUnapply()
+inline void EditCommandImpl::beginUnapply()
 {
-    ASSERT(state() == APPLIED);
+    ASSERT(state() == Applied);
 }
 
-inline void EditCommand::endUnapply()
+inline void EditCommandImpl::endUnapply()
 {
-    m_state = NOT_APPLIED;
+    m_state = NotApplied;
     moveToStartingSelection();
 }
 
-inline void EditCommand::beginReapply()
+inline void EditCommandImpl::beginReapply()
 {
     beginApply();
 }
 
-inline void EditCommand::endReapply()
+inline void EditCommandImpl::endReapply()
 {
     endApply();
 }
 
-const KHTMLSelection &EditCommand::currentSelection() const
+KHTMLSelection EditCommandImpl::currentSelection() const
 {
     ASSERT(m_document);
     ASSERT(m_document->part());
     return m_document->part()->selection();
 }
 
-bool EditCommand::coalesce(const EditCommandPtr &cmd)
+bool EditCommandImpl::coalesce(const EditCommand &cmd)
 {
     // default is no coalescing
     return false;
 }
 
-bool EditCommand::groupForUndo(const EditCommandPtr &) const
+bool EditCommandImpl::groupForUndo(const EditCommand &) const
 {
     // default is not continuing
     return false;
 }
 
-bool EditCommand::groupForRedo(const EditCommandPtr &) const
+bool EditCommandImpl::groupForRedo(const EditCommand &) const
 {
     // default is not continuing
     return false;
 }
 
-void EditCommand::moveToStartingSelection()
+void EditCommandImpl::moveToStartingSelection()
 {
     ASSERT(m_document);
     ASSERT(m_document->part());
     m_document->part()->setSelection(m_startingSelection);
 }
 
-void EditCommand::moveToEndingSelection()
+void EditCommandImpl::moveToEndingSelection()
 {
     ASSERT(m_document);
     ASSERT(m_document->part());
     m_document->part()->setSelection(m_endingSelection);
 }
 
-QString EditCommand::name() const
+QString EditCommandImpl::name() const
 {
     switch (commandID()) {
         case EditCommandID:
-            return "EditCommandID";
+            return "EditCommandImpl";
             break;
-        case InputTextCommandID:
-            return "InputTextCommandID";
+        case AppendNodeCommandID:
+            return "AppendNodeCommandImpl";
+            break;
+        case CompositeEditCommandID:
+            return "CompositeEditCommandImpl";
             break;
         case DeleteKeyCommandID:
-            return "DeleteKeyCommandID";
+            return "DeleteKeyCommandImpl";
+            break;
+        case DeleteSelectionCommandID:
+            return "DeleteSelectionCommandImpl";
+            break;
+        case DeleteTextCommandID:
+            return "DeleteTextCommandImpl";
+            break;
+        case InputTextCommandID:
+            return "InputTextCommandImpl";
+            break;
+        case InsertNodeBeforeCommandID:
+            return "InsertNodeBeforeCommandImpl";
+            break;
+        case InsertTextCommandID:
+            return "InsertTextCommandImpl";
+            break;
+        case JoinTextNodesCommandID:
+            return "JoinTextNodesCommandImpl";
+            break;
+        case ModifyTextNodeCommandID:
+            return "ModifyTextNodeCommandImpl";
+            break;
+        case RemoveNodeCommandID:
+            return "RemoveNodeCommandImpl";
             break;
         case MoveSelectionToCommandID:
-            return "MoveSelectionToCommand";
+            return "MoveSelectionToCommandImpl";
+            break;
+        case PasteHTMLCommandID:
+            return "PasteHTMLCommandImpl";
+            break;
+        case SplitTextNodeCommandID:
+            return "SplitTextNodeCommandImpl";
             break;
     }
     
@@ -200,56 +250,61 @@ QString EditCommand::name() const
 }
 
 //------------------------------------------------------------------------------------------
-// CompositeEditCommand
+// CompositeEditCommandImpl
 
-CompositeEditCommand::CompositeEditCommand(DocumentImpl *document) 
-    : EditCommand(document)
+CompositeEditCommandImpl::CompositeEditCommandImpl(DocumentImpl *document) 
+    : EditCommandImpl(document)
 {
 }
 
-CompositeEditCommand::~CompositeEditCommand()
+CompositeEditCommandImpl::~CompositeEditCommandImpl()
 {
 }
 
-void CompositeEditCommand::unapply()
+void CompositeEditCommandImpl::unapply()
 {
     if (m_cmds.count() == 0) {
         ERROR("Unapplying composite command containing zero steps");
+        return;
     }
-    for (int i = m_cmds.count() - 1; i >= 0; --i) {
+    
+    for (int i = m_cmds.count() - 1; i >= 0; --i)
         m_cmds[i]->unapply();
-    }
+
     moveToStartingSelection();
-    setState(NOT_APPLIED);
+    setState(NotApplied);
 }
 
-void CompositeEditCommand::reapply()
+void CompositeEditCommandImpl::reapply()
 {
     if (m_cmds.count() == 0) {
         ERROR("Reapplying composite command containing zero steps");
+        return;
     }
-    for (QValueList<EditCommandPtr>::ConstIterator it = m_cmds.begin(); it != m_cmds.end(); ++it) {
+
+    for (QValueList<EditCommand>::ConstIterator it = m_cmds.begin(); it != m_cmds.end(); ++it)
         (*it)->reapply();
-    }
+
     moveToEndingSelection();
-    setState(APPLIED);
+    setState(Applied);
 }
 
 //
 // sugary-sweet convenience functions to help create and apply edit commands in composite commands
 //
-void CompositeEditCommand::applyCommand(const EditCommandPtr &step)
+void CompositeEditCommandImpl::applyCommand(EditCommand &cmd)
 {
-    step->apply();
-    m_cmds.append(step);
+    cmd.apply();
+    m_cmds.append(cmd);
 }
 
-void CompositeEditCommand::insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
+void CompositeEditCommandImpl::insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
 {
-    applyCommand(EditCommandPtr(new InsertNodeBeforeCommand(document(), insertChild, refChild)));
+    InsertNodeBeforeCommand cmd(document(), insertChild, refChild);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
+void CompositeEditCommandImpl::insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
 {
     if (refChild->parentNode()->lastChild() == refChild) {
         appendNode(refChild->parentNode(), insertChild);
@@ -260,70 +315,73 @@ void CompositeEditCommand::insertNodeAfter(DOM::NodeImpl *insertChild, DOM::Node
     }
 }
 
-void CompositeEditCommand::appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild)
+void CompositeEditCommandImpl::appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild)
 {
-    applyCommand(EditCommandPtr(new AppendNodeCommand(document(), parent, appendChild)));
+    AppendNodeCommand cmd(document(), parent, appendChild);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::removeNode(DOM::NodeImpl *removeChild)
+void CompositeEditCommandImpl::removeNode(DOM::NodeImpl *removeChild)
 {
-    applyCommand(EditCommandPtr(new RemoveNodeCommand(document(), removeChild)));
+    RemoveNodeCommand cmd(document(), removeChild);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::splitTextNode(DOM::TextImpl *text, long offset)
+void CompositeEditCommandImpl::splitTextNode(DOM::TextImpl *text, long offset)
 {
-    applyCommand(EditCommandPtr(new SplitTextNodeCommand(document(), text, offset)));
+    SplitTextNodeCommand cmd(document(), text, offset);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2)
+void CompositeEditCommandImpl::joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2)
 {
-    applyCommand(EditCommandPtr(new JoinTextNodesCommand(document(), text1, text2)));
+    JoinTextNodesCommand cmd(document(), text1, text2);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text)
+void CompositeEditCommandImpl::insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text)
 {
-    applyCommand(EditCommandPtr(new InsertTextCommand(document(), node, offset, text)));
+    InsertTextCommand cmd(document(), node, offset, text);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::deleteText(DOM::TextImpl *node, long offset, long count)
+void CompositeEditCommandImpl::deleteText(DOM::TextImpl *node, long offset, long count)
 {
-    applyCommand(EditCommandPtr(new DeleteTextCommand(document(), node, offset, count)));
+    DeleteTextCommand cmd(document(), node, offset, count);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::moveSelectionTo(const KHTMLSelection &selection)
+void CompositeEditCommandImpl::moveSelectionTo(const KHTMLSelection &selection)
 {
-    applyCommand(EditCommandPtr(new MoveSelectionToCommand(document(), selection)));
+    MoveSelectionToCommand cmd(document(), selection);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::moveSelectionTo(DOM::NodeImpl *node, long offset)
+void CompositeEditCommandImpl::moveSelectionTo(DOM::NodeImpl *node, long offset)
 {
-    applyCommand(EditCommandPtr(new MoveSelectionToCommand(document(), node, offset)));
+    MoveSelectionToCommand cmd(document(), node, offset);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::moveSelectionTo(const DOM::DOMPosition &pos)
+void CompositeEditCommandImpl::moveSelectionTo(const DOM::DOMPosition &pos)
 {
-    applyCommand(EditCommandPtr(new MoveSelectionToCommand(document(), pos)));
+    MoveSelectionToCommand cmd(document(), pos);
+    applyCommand(cmd);
 }
 
-void CompositeEditCommand::deleteSelection()
+void CompositeEditCommandImpl::deleteSelection()
 {
     if (currentSelection().state() == KHTMLSelection::RANGE) {
-        applyCommand(EditCommandPtr(new DeleteSelectionCommand(document())));
-    }
-}
-
-void CompositeEditCommand::deleteSelection(const KHTMLSelection &selection)
-{
-    if (selection.state() == KHTMLSelection::RANGE) {
-        applyCommand(EditCommandPtr(new DeleteSelectionCommand(document(), selection)));
+        DeleteSelectionCommand cmd(document());
+        applyCommand(cmd);
     }
 }
 
 //------------------------------------------------------------------------------------------
-// InsertNodeBeforeCommand
+// InsertNodeBeforeCommandImpl
 
-InsertNodeBeforeCommand::InsertNodeBeforeCommand(DocumentImpl *document, NodeImpl *insertChild, NodeImpl *refChild)
-    : EditCommand(document), m_insertChild(insertChild), m_refChild(refChild)
+InsertNodeBeforeCommandImpl::InsertNodeBeforeCommandImpl(DocumentImpl *document, NodeImpl *insertChild, NodeImpl *refChild)
+    : EditCommandImpl(document), m_insertChild(insertChild), m_refChild(refChild)
 {
     ASSERT(m_insertChild);
     m_insertChild->ref();
@@ -332,7 +390,7 @@ InsertNodeBeforeCommand::InsertNodeBeforeCommand(DocumentImpl *document, NodeImp
     m_refChild->ref();
 }
 
-InsertNodeBeforeCommand::~InsertNodeBeforeCommand()
+InsertNodeBeforeCommandImpl::~InsertNodeBeforeCommandImpl()
 {
     if (m_insertChild)
         m_insertChild->deref();
@@ -340,7 +398,7 @@ InsertNodeBeforeCommand::~InsertNodeBeforeCommand()
         m_refChild->deref();
 }
 
-void InsertNodeBeforeCommand::apply()
+void InsertNodeBeforeCommandImpl::apply()
 {
     beginApply();
 
@@ -355,7 +413,7 @@ void InsertNodeBeforeCommand::apply()
     endApply();
 }
 
-void InsertNodeBeforeCommand::unapply()
+void InsertNodeBeforeCommandImpl::unapply()
 {
     beginUnapply();
 
@@ -371,10 +429,10 @@ void InsertNodeBeforeCommand::unapply()
 }
 
 //------------------------------------------------------------------------------------------
-// AppendNodeCommand
+// AppendNodeCommandImpl
 
-AppendNodeCommand::AppendNodeCommand(DocumentImpl *document, NodeImpl *parent, NodeImpl *appendChild)
-    : EditCommand(document), m_parent(parent), m_appendChild(appendChild)
+AppendNodeCommandImpl::AppendNodeCommandImpl(DocumentImpl *document, NodeImpl *parent, NodeImpl *appendChild)
+    : EditCommandImpl(document), m_parent(parent), m_appendChild(appendChild)
 {
     ASSERT(m_parent);
     m_parent->ref();
@@ -383,7 +441,7 @@ AppendNodeCommand::AppendNodeCommand(DocumentImpl *document, NodeImpl *parent, N
     m_appendChild->ref();
 }
 
-AppendNodeCommand::~AppendNodeCommand()
+AppendNodeCommandImpl::~AppendNodeCommandImpl()
 {
     if (m_parent)
         m_parent->deref();
@@ -391,7 +449,7 @@ AppendNodeCommand::~AppendNodeCommand()
         m_appendChild->deref();
 }
 
-void AppendNodeCommand::apply()
+void AppendNodeCommandImpl::apply()
 {
     beginApply();
 
@@ -405,13 +463,13 @@ void AppendNodeCommand::apply()
     endApply();
 }
 
-void AppendNodeCommand::unapply()
+void AppendNodeCommandImpl::unapply()
 {
     beginUnapply();
 
     ASSERT(m_parent);
     ASSERT(m_appendChild);
-    ASSERT(state() == APPLIED);
+    ASSERT(state() == Applied);
 
     int exceptionCode;
     m_parent->removeChild(m_appendChild, exceptionCode);
@@ -421,10 +479,10 @@ void AppendNodeCommand::unapply()
 }
 
 //------------------------------------------------------------------------------------------
-// RemoveNodeCommand
+// RemoveNodeCommandImpl
 
-RemoveNodeCommand::RemoveNodeCommand(DocumentImpl *document, NodeImpl *removeChild)
-    : EditCommand(document), m_parent(0), m_removeChild(removeChild), m_refChild(0)
+RemoveNodeCommandImpl::RemoveNodeCommandImpl(DocumentImpl *document, NodeImpl *removeChild)
+    : EditCommandImpl(document), m_parent(0), m_removeChild(removeChild), m_refChild(0)
 {
     ASSERT(m_removeChild);
     m_removeChild->ref();
@@ -445,7 +503,7 @@ RemoveNodeCommand::RemoveNodeCommand(DocumentImpl *document, NodeImpl *removeChi
         m_refChild->ref();
 }
 
-RemoveNodeCommand::~RemoveNodeCommand()
+RemoveNodeCommandImpl::~RemoveNodeCommandImpl()
 {
     if (m_parent)
         m_parent->deref();
@@ -455,7 +513,7 @@ RemoveNodeCommand::~RemoveNodeCommand()
         m_refChild->deref();
 }
 
-void RemoveNodeCommand::apply()
+void RemoveNodeCommandImpl::apply()
 {
     beginApply();
 
@@ -469,7 +527,7 @@ void RemoveNodeCommand::apply()
     endApply();
 }
 
-void RemoveNodeCommand::unapply()
+void RemoveNodeCommandImpl::unapply()
 {
     beginUnapply();
 
@@ -487,10 +545,10 @@ void RemoveNodeCommand::unapply()
 }
 
 //------------------------------------------------------------------------------------------
-// ModifyTextNodeCommand
+// ModifyTextNodeCommandImpl
 
-ModifyTextNodeCommand::ModifyTextNodeCommand(DocumentImpl *document, TextImpl *text, long offset)
-    : EditCommand(document), m_text1(0), m_text2(text), m_offset(offset)
+ModifyTextNodeCommandImpl::ModifyTextNodeCommandImpl(DocumentImpl *document, TextImpl *text, long offset)
+    : EditCommandImpl(document), m_text1(0), m_text2(text), m_offset(offset)
 {
     ASSERT(m_text2);
     ASSERT(m_text2->length() > 0);
@@ -499,8 +557,8 @@ ModifyTextNodeCommand::ModifyTextNodeCommand(DocumentImpl *document, TextImpl *t
     m_text2->ref();
 }
 
-ModifyTextNodeCommand::ModifyTextNodeCommand(DocumentImpl *document, TextImpl *text1, TextImpl *text2)
-    : EditCommand(document), m_text1(text1), m_text2(text2), m_offset(0)
+ModifyTextNodeCommandImpl::ModifyTextNodeCommandImpl(DocumentImpl *document, TextImpl *text1, TextImpl *text2)
+    : EditCommandImpl(document), m_text1(text1), m_text2(text2), m_offset(0)
 {
     ASSERT(m_text1);
     ASSERT(m_text2);
@@ -512,7 +570,7 @@ ModifyTextNodeCommand::ModifyTextNodeCommand(DocumentImpl *document, TextImpl *t
     m_text2->ref();
 }
 
-ModifyTextNodeCommand::~ModifyTextNodeCommand()
+ModifyTextNodeCommandImpl::~ModifyTextNodeCommandImpl()
 {
     if (m_text2)
         m_text2->deref();
@@ -520,7 +578,7 @@ ModifyTextNodeCommand::~ModifyTextNodeCommand()
         m_text1->deref();
 }
 
-void ModifyTextNodeCommand::splitTextNode()
+void ModifyTextNodeCommandImpl::splitTextNode()
 {
     ASSERT(m_text2);
     ASSERT(m_text1 == 0);
@@ -545,7 +603,7 @@ void ModifyTextNodeCommand::splitTextNode()
     m_text1 = static_cast<TextImpl *>(m_text2->previousSibling());
 }
 
-void ModifyTextNodeCommand::joinTextNodes()
+void ModifyTextNodeCommandImpl::joinTextNodes()
 {
     ASSERT(m_text1);
     ASSERT(m_text2);
@@ -566,25 +624,25 @@ void ModifyTextNodeCommand::joinTextNodes()
 }
 
 //------------------------------------------------------------------------------------------
-// SplitTextNodeCommand
+// SplitTextNodeCommandImpl
 
-SplitTextNodeCommand::SplitTextNodeCommand(DocumentImpl *document, TextImpl *text, long offset)
-    : ModifyTextNodeCommand(document, text, offset)
+SplitTextNodeCommandImpl::SplitTextNodeCommandImpl(DocumentImpl *document, TextImpl *text, long offset)
+    : ModifyTextNodeCommandImpl(document, text, offset)
 {
 }
 
-SplitTextNodeCommand::~SplitTextNodeCommand()
+SplitTextNodeCommandImpl::~SplitTextNodeCommandImpl()
 {
 }
 
-void SplitTextNodeCommand::apply()
+void SplitTextNodeCommandImpl::apply()
 {
     beginApply();
     splitTextNode();
     endApply();
 }
 
-void SplitTextNodeCommand::unapply()
+void SplitTextNodeCommandImpl::unapply()
 {
     beginUnapply();
     joinTextNodes();
@@ -592,25 +650,25 @@ void SplitTextNodeCommand::unapply()
 }
 
 //------------------------------------------------------------------------------------------
-// SplitTextNodeCommand
+// SplitTextNodeCommandImpl
 
-JoinTextNodesCommand::JoinTextNodesCommand(DocumentImpl *document, TextImpl *text1, TextImpl *text2)
-    : ModifyTextNodeCommand(document, text1, text2)
+JoinTextNodesCommandImpl::JoinTextNodesCommandImpl(DocumentImpl *document, TextImpl *text1, TextImpl *text2)
+    : ModifyTextNodeCommandImpl(document, text1, text2)
 {
 }
 
-JoinTextNodesCommand::~JoinTextNodesCommand()
+JoinTextNodesCommandImpl::~JoinTextNodesCommandImpl()
 {
 }
 
-void JoinTextNodesCommand::apply()
+void JoinTextNodesCommandImpl::apply()
 {
     beginApply();
     joinTextNodes();
     endApply();
 }
 
-void JoinTextNodesCommand::unapply()
+void JoinTextNodesCommandImpl::unapply()
 {
     beginUnapply();
     splitTextNode();
@@ -618,10 +676,10 @@ void JoinTextNodesCommand::unapply()
 }
 
 //------------------------------------------------------------------------------------------
-// InsertTextCommand
+// InsertTextCommandImpl
 
-InsertTextCommand::InsertTextCommand(DocumentImpl *document, TextImpl *node, long offset, const DOMString &text)
-    : EditCommand(document), m_node(node), m_offset(offset)
+InsertTextCommandImpl::InsertTextCommandImpl(DocumentImpl *document, TextImpl *node, long offset, const DOMString &text)
+    : EditCommandImpl(document), m_node(node), m_offset(offset)
 {
     ASSERT(m_node);
     ASSERT(m_offset >= 0);
@@ -631,13 +689,13 @@ InsertTextCommand::InsertTextCommand(DocumentImpl *document, TextImpl *node, lon
     m_text = text.copy(); // make a copy to ensure that the string never changes
 }
 
-InsertTextCommand::~InsertTextCommand()
+InsertTextCommandImpl::~InsertTextCommandImpl()
 {
     if (m_node)
         m_node->deref();
 }
 
-void InsertTextCommand::apply()
+void InsertTextCommandImpl::apply()
 {
     beginApply();
 
@@ -651,7 +709,7 @@ void InsertTextCommand::apply()
     endApply();
 }
 
-void InsertTextCommand::unapply()
+void InsertTextCommandImpl::unapply()
 {
     beginUnapply();
 
@@ -666,10 +724,10 @@ void InsertTextCommand::unapply()
 }
 
 //------------------------------------------------------------------------------------------
-// DeleteTextCommand
+// DeleteTextCommandImpl
 
-DeleteTextCommand::DeleteTextCommand(DocumentImpl *document, TextImpl *node, long offset, long count)
-    : EditCommand(document), m_node(node), m_offset(offset), m_count(count)
+DeleteTextCommandImpl::DeleteTextCommandImpl(DocumentImpl *document, TextImpl *node, long offset, long count)
+    : EditCommandImpl(document), m_node(node), m_offset(offset), m_count(count)
 {
     ASSERT(m_node);
     ASSERT(m_offset >= 0);
@@ -678,13 +736,13 @@ DeleteTextCommand::DeleteTextCommand(DocumentImpl *document, TextImpl *node, lon
     m_node->ref();
 }
 
-DeleteTextCommand::~DeleteTextCommand()
+DeleteTextCommandImpl::~DeleteTextCommandImpl()
 {
     if (m_node)
         m_node->deref();
 }
 
-void DeleteTextCommand::apply()
+void DeleteTextCommandImpl::apply()
 {
     beginApply();
 
@@ -700,7 +758,7 @@ void DeleteTextCommand::apply()
     endApply();
 }
 
-void DeleteTextCommand::unapply()
+void DeleteTextCommandImpl::unapply()
 {
     beginUnapply();
 
@@ -715,69 +773,57 @@ void DeleteTextCommand::unapply()
 }
 
 //------------------------------------------------------------------------------------------
-// MoveSelectionToCommand
+// MoveSelectionToCommandImpl
 
-MoveSelectionToCommand::MoveSelectionToCommand(DocumentImpl *document, const KHTMLSelection &selection)
-    : EditCommand(document)
+MoveSelectionToCommandImpl::MoveSelectionToCommandImpl(DocumentImpl *document, const KHTMLSelection &selection)
+    : EditCommandImpl(document)
 {
     setEndingSelection(selection);
 }
 
-MoveSelectionToCommand::MoveSelectionToCommand(DocumentImpl *document, DOM::NodeImpl *node, long offset)
-    : EditCommand(document)
+MoveSelectionToCommandImpl::MoveSelectionToCommandImpl(DocumentImpl *document, DOM::NodeImpl *node, long offset)
+    : EditCommandImpl(document)
 {
     KHTMLSelection selection(node, offset);
     setEndingSelection(selection);
 }
 
-MoveSelectionToCommand::MoveSelectionToCommand(DOM::DocumentImpl *document, const DOM::DOMPosition &pos)
-    : EditCommand(document)
+MoveSelectionToCommandImpl::MoveSelectionToCommandImpl(DOM::DocumentImpl *document, const DOM::DOMPosition &pos)
+    : EditCommandImpl(document)
 {
     KHTMLSelection selection(pos);
     setEndingSelection(selection);
 }
 
-MoveSelectionToCommand::~MoveSelectionToCommand() 
+MoveSelectionToCommandImpl::~MoveSelectionToCommandImpl() 
 {
 }
 
-int MoveSelectionToCommand::commandID() const
-{
-    return MoveSelectionToCommandID;
-}
-
-
-void MoveSelectionToCommand::apply()
+void MoveSelectionToCommandImpl::apply()
 {
     beginApply();
     endApply();
 }
 
-void MoveSelectionToCommand::unapply()
+void MoveSelectionToCommandImpl::unapply()
 {
     beginUnapply();
     endUnapply();
 }
 
 //------------------------------------------------------------------------------------------
-// DeleteSelectionCommand
+// DeleteSelectionCommandImpl
 
-DeleteSelectionCommand::DeleteSelectionCommand(DOM::DocumentImpl *document)
-    : CompositeEditCommand(document)
+DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DOM::DocumentImpl *document)
+    : CompositeEditCommandImpl(document)
 {
 }
 
-DeleteSelectionCommand::DeleteSelectionCommand(DOM::DocumentImpl *document, const KHTMLSelection &selection)
-    : CompositeEditCommand(document)
-{
-    setStartingSelection(selection);
-}
-
-DeleteSelectionCommand::~DeleteSelectionCommand()
+DeleteSelectionCommandImpl::~DeleteSelectionCommandImpl()
 {
 }
 	
-void DeleteSelectionCommand::apply()
+void DeleteSelectionCommandImpl::apply()
 {
     beginApply();
 
@@ -903,48 +949,48 @@ void DeleteSelectionCommand::apply()
 }
 
 //------------------------------------------------------------------------------------------
-// InputTextCommand
+// InputTextCommandImpl
 
-InputTextCommand::InputTextCommand(DocumentImpl *document, const DOMString &text) 
-    : CompositeEditCommand(document)
+InputTextCommandImpl::InputTextCommandImpl(DocumentImpl *document, const DOMString &text) 
+    : CompositeEditCommandImpl(document)
 {
     ASSERT(!text.isEmpty());
     m_text = text; 
 }
 
-InputTextCommand::~InputTextCommand() 
+InputTextCommandImpl::~InputTextCommandImpl() 
 {
 }
 
-int InputTextCommand::commandID() const
+int InputTextCommandImpl::commandID() const
 {
     return InputTextCommandID;
 }
 
-bool InputTextCommand::isLineBreak(const DOM::DOMString &text) const
+bool InputTextCommandImpl::isLineBreak(const DOM::DOMString &text) const
 {
     return text.length() == 1 && (text[0] == '\n' || text[0] == '\r');
 }
 
-bool InputTextCommand::isSpace(const DOM::DOMString &text) const
+bool InputTextCommandImpl::isSpace(const DOM::DOMString &text) const
 {
     return text.length() == 1 && (text[0] == ' ');
 }
 
-void InputTextCommand::apply()
+void InputTextCommandImpl::apply()
 {
     beginApply();
     execute(m_text);
     endApply();
 }
 
-bool InputTextCommand::coalesce(const EditCommandPtr &cmd)
+bool InputTextCommandImpl::coalesce(const EditCommand &cmd)
 {
-    ASSERT(state() == APPLIED);
+    ASSERT(state() == Applied);
     
     if (cmd->commandID() == InputTextCommandID && endingSelection() == cmd->startingSelection()) {
         // InputTextCommands coalesce with each other if they 
-        const InputTextCommand *c = static_cast<const InputTextCommand *>(cmd.get());
+        const InputTextCommandImpl *c = static_cast<const InputTextCommandImpl *>(cmd.get());
         execute(c->text());
         m_text += c->text();
         moveToEndingSelection();
@@ -954,7 +1000,7 @@ bool InputTextCommand::coalesce(const EditCommandPtr &cmd)
     return false;
 }
 
-bool InputTextCommand::groupForUndo(const EditCommandPtr &cmd) const
+bool InputTextCommandImpl::groupForUndo(const EditCommand &cmd) const
 {
     if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && startingSelection() == cmd->endingSelection()) {
         return true;
@@ -962,7 +1008,7 @@ bool InputTextCommand::groupForUndo(const EditCommandPtr &cmd) const
     return false;
 }
 
-bool InputTextCommand::groupForRedo(const EditCommandPtr &cmd) const
+bool InputTextCommandImpl::groupForRedo(const EditCommand &cmd) const
 {
     if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && endingSelection() == cmd->startingSelection()) {
         return true;
@@ -970,7 +1016,7 @@ bool InputTextCommand::groupForRedo(const EditCommandPtr &cmd) const
     return false;
 }
 
-void InputTextCommand::execute(const DOM::DOMString &text)
+void InputTextCommandImpl::execute(const DOM::DOMString &text)
 {
     KHTMLSelection selection = currentSelection();
 
@@ -1021,23 +1067,23 @@ void InputTextCommand::execute(const DOM::DOMString &text)
 }
 
 //------------------------------------------------------------------------------------------
-// DeleteKeyCommand
+// DeleteKeyCommandImpl
 
-DeleteKeyCommand::DeleteKeyCommand(DocumentImpl *document) 
-    : CompositeEditCommand(document)
+DeleteKeyCommandImpl::DeleteKeyCommandImpl(DocumentImpl *document) 
+    : CompositeEditCommandImpl(document)
 {
 }
 
-DeleteKeyCommand::~DeleteKeyCommand() 
+DeleteKeyCommandImpl::~DeleteKeyCommandImpl() 
 {
 }
 
-int DeleteKeyCommand::commandID() const
+int DeleteKeyCommandImpl::commandID() const
 {
     return DeleteKeyCommandID;
 }
 
-void DeleteKeyCommand::apply()
+void DeleteKeyCommandImpl::apply()
 {
     beginApply();
 
@@ -1050,6 +1096,7 @@ void DeleteKeyCommand::apply()
     // Delete the current selection
     if (selection.state() == KHTMLSelection::RANGE) {
         deleteSelection();
+        setEndingSelection(currentSelection());
         endApply();
         return;
     }
@@ -1090,7 +1137,7 @@ void DeleteKeyCommand::apply()
     }
 }
 
-bool DeleteKeyCommand::groupForUndo(const EditCommandPtr &cmd) const
+bool DeleteKeyCommandImpl::groupForUndo(const EditCommand &cmd) const
 {
     if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && startingSelection() == cmd->endingSelection()) {
         return true;
@@ -1099,7 +1146,7 @@ bool DeleteKeyCommand::groupForUndo(const EditCommandPtr &cmd) const
     return false;
 }
 
-bool DeleteKeyCommand::groupForRedo(const EditCommandPtr &cmd) const
+bool DeleteKeyCommandImpl::groupForRedo(const EditCommand &cmd) const
 {
     if ((cmd->commandID() == InputTextCommandID || cmd->commandID() == DeleteKeyCommandID) && endingSelection() == cmd->startingSelection()) {
         return true;
@@ -1108,18 +1155,18 @@ bool DeleteKeyCommand::groupForRedo(const EditCommandPtr &cmd) const
     return false;
 }
 
-PasteHTMLCommand::PasteHTMLCommand(DocumentImpl *document, const DOMString &HTMLString) 
-    : CompositeEditCommand(document)
+PasteHTMLCommandImpl::PasteHTMLCommandImpl(DocumentImpl *document, const DOMString &HTMLString) 
+    : CompositeEditCommandImpl(document)
 {
     ASSERT(!HTMLString.isEmpty());
     m_HTMLString = HTMLString; 
 }
 
-PasteHTMLCommand::~PasteHTMLCommand()
+PasteHTMLCommandImpl::~PasteHTMLCommandImpl()
 {
 }
 
-void PasteHTMLCommand::apply()
+void PasteHTMLCommandImpl::apply()
 {
     beginApply();
     
@@ -1195,4 +1242,3 @@ void PasteHTMLCommand::apply()
 
     endApply();
 }
-
diff --git a/WebCore/khtml/editing/htmlediting_impl.h b/WebCore/khtml/editing/htmlediting_impl.h
new file mode 100644
index 0000000..67f3322
--- /dev/null
+++ b/WebCore/khtml/editing/htmlediting_impl.h
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef __htmleditingimpl_h__
+#define __htmleditingimpl_h__
+
+#include "htmlediting.h"
+
+#include <khtml_selection.h>
+#include <dom_position.h>
+#include <dom_string.h>
+
+#include <qvaluelist.h>
+#include <shared.h>
+
+class KHTMLSelection;
+
+namespace DOM {
+    class DocumentImpl;
+    class DOMPosition;
+    class DOMString;
+    class NodeImpl;
+    class TextImpl;
+};
+
+namespace khtml {
+
+//------------------------------------------------------------------------------------------
+// EditCommandImpl classes
+
+class EditCommandImpl : public SharedCommandImpl
+{
+public:
+	EditCommandImpl(DOM::DocumentImpl *);
+	virtual ~EditCommandImpl();
+
+    virtual int commandID() const;
+	virtual QString name() const;
+
+    enum ECommandState { NotApplied, Applied };
+    
+	virtual void apply() = 0;	
+	virtual void unapply() = 0;
+	virtual void reapply();  // calls apply()
+
+    virtual bool coalesce(const EditCommand &);
+
+    virtual bool groupForUndo(const EditCommand &) const;
+    virtual bool groupForRedo(const EditCommand &) const;
+            
+    virtual DOM::DocumentImpl * const document() const { return m_document; }
+
+    virtual KHTMLSelection startingSelection() const { return m_startingSelection; }
+    virtual KHTMLSelection endingSelection() const { return m_endingSelection; }
+    virtual KHTMLSelection currentSelection() const;
+        
+protected:
+    void beginApply();
+    void endApply();
+    void beginUnapply();
+    void endUnapply();
+    void beginReapply();
+    void endReapply();
+    
+    ECommandState state() const { return m_state; }
+    void setState(ECommandState state) { m_state = state; }
+
+    void setStartingSelection(const KHTMLSelection &s) { m_startingSelection = s; }
+    void setEndingSelection(const KHTMLSelection &s) { m_endingSelection = s; }
+
+    void moveToStartingSelection();
+    void moveToEndingSelection();
+
+private:
+    DOM::DocumentImpl *m_document;
+    ECommandState m_state;
+    KHTMLSelection m_startingSelection;
+    KHTMLSelection m_endingSelection;
+};
+
+class CompositeEditCommandImpl : public EditCommandImpl
+{
+public:
+	CompositeEditCommandImpl(DOM::DocumentImpl *);
+	virtual ~CompositeEditCommandImpl();
+	
+	virtual void apply() = 0;	
+	virtual void unapply();
+	virtual void reapply();
+    
+protected:
+    //
+    // sugary-sweet convenience functions to help create and apply edit commands in composite commands
+    //
+    void applyCommand(EditCommand &);
+    void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
+    void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
+    void appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
+    void removeNode(DOM::NodeImpl *removeChild);
+    void splitTextNode(DOM::TextImpl *text, long offset);
+    void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
+    void insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
+    void deleteText(DOM::TextImpl *node, long offset, long count);
+    void moveSelectionTo(const KHTMLSelection &selection);
+	void moveSelectionTo(DOM::NodeImpl *, long);
+	void moveSelectionTo(const DOM::DOMPosition &);
+    void deleteSelection();
+
+    QValueList<EditCommand> m_cmds;
+};
+
+class InsertNodeBeforeCommandImpl : public EditCommandImpl
+{
+public:
+    InsertNodeBeforeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
+	virtual ~InsertNodeBeforeCommandImpl();
+
+	virtual void apply();
+	virtual void unapply();
+
+    DOM::NodeImpl *insertChild() const { return m_insertChild; }
+    DOM::NodeImpl *refChild() const { return m_refChild; }
+
+private:
+    DOM::NodeImpl *m_insertChild;
+    DOM::NodeImpl *m_refChild; 
+};
+
+class AppendNodeCommandImpl : public EditCommandImpl
+{
+public:
+    AppendNodeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
+	virtual ~AppendNodeCommandImpl();
+
+	virtual void apply();
+	virtual void unapply();
+
+    DOM::NodeImpl *parent() const { return m_parent; }
+    DOM::NodeImpl *appendChild() const { return m_appendChild; }
+
+private:
+    DOM::NodeImpl *m_parent;    
+    DOM::NodeImpl *m_appendChild;
+};
+
+class RemoveNodeCommandImpl : public EditCommandImpl
+{
+public:
+	RemoveNodeCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *);
+	virtual ~RemoveNodeCommandImpl();
+	
+	virtual void apply();
+	virtual void unapply();
+
+    DOM::NodeImpl *node() const { return m_removeChild; }
+
+private:
+    DOM::NodeImpl *m_parent;    
+    DOM::NodeImpl *m_removeChild;
+    DOM::NodeImpl *m_refChild;    
+};
+
+class ModifyTextNodeCommandImpl : public EditCommandImpl
+{
+public:
+    // used by SplitTextNodeCommandImpl derived class
+	ModifyTextNodeCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, long); 
+    // used by JoinTextNodesCommandImpl derived class
+    ModifyTextNodeCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
+	virtual ~ModifyTextNodeCommandImpl();
+	
+protected:
+    void splitTextNode();
+    void joinTextNodes();
+
+    virtual ECommandState joinState() = 0;
+    virtual ECommandState splitState() = 0;
+
+    DOM::TextImpl *m_text1;
+    DOM::TextImpl *m_text2;
+    long m_offset;
+};
+
+class SplitTextNodeCommandImpl : public ModifyTextNodeCommandImpl
+{
+public:
+	SplitTextNodeCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, long);
+	virtual ~SplitTextNodeCommandImpl();
+	
+	virtual void apply();
+	virtual void unapply();
+
+    virtual ECommandState joinState() { return Applied; }
+    virtual ECommandState splitState() { return NotApplied; }
+
+    DOM::TextImpl *node() const { return m_text2; }
+    long offset() const { return m_offset; }
+};
+
+class JoinTextNodesCommandImpl : public ModifyTextNodeCommandImpl
+{
+public:
+	JoinTextNodesCommandImpl(DOM::DocumentImpl *, DOM::TextImpl *, DOM::TextImpl *);
+	virtual ~JoinTextNodesCommandImpl();
+	
+	virtual void apply();
+	virtual void unapply();
+
+    virtual ECommandState joinState() { return NotApplied; }
+    virtual ECommandState splitState() { return Applied; }
+
+    DOM::TextImpl *firstNode() const { return m_text1; }
+    DOM::TextImpl *secondNode() const { return m_text2; }
+};
+
+class InsertTextCommandImpl : public EditCommandImpl
+{
+public:
+	InsertTextCommandImpl(DOM::DocumentImpl *document, DOM::TextImpl *, long, const DOM::DOMString &);
+	virtual ~InsertTextCommandImpl();
+	
+	virtual void apply();
+	virtual void unapply();
+
+    DOM::TextImpl *node() const { return m_node; }
+    long offset() const { return m_offset; }
+    DOM::DOMString text() const { return m_text; }
+
+private:
+    DOM::TextImpl *m_node;
+    long m_offset;
+    DOM::DOMString m_text;
+};
+
+class DeleteTextCommandImpl : public EditCommandImpl
+{
+public:
+	DeleteTextCommandImpl(DOM::DocumentImpl *document, DOM::TextImpl *node, long offset, long count);
+	virtual ~DeleteTextCommandImpl();
+	
+	virtual void apply();
+	virtual void unapply();
+
+    DOM::TextImpl *node() const { return m_node; }
+    long offset() const { return m_offset; }
+    long count() const { return m_count; }
+
+private:
+    DOM::TextImpl *m_node;
+    long m_offset;
+    long m_count;
+    DOM::DOMString m_text;
+};
+
+class MoveSelectionToCommandImpl : public EditCommandImpl
+{
+public:
+	MoveSelectionToCommandImpl(DOM::DocumentImpl *document, const KHTMLSelection &selection);
+	MoveSelectionToCommandImpl(DOM::DocumentImpl *document, DOM::NodeImpl *, long);
+	MoveSelectionToCommandImpl(DOM::DocumentImpl *document, const DOM::DOMPosition &);
+	virtual ~MoveSelectionToCommandImpl();
+
+	virtual void apply();
+	virtual void unapply();
+};
+
+class DeleteSelectionCommandImpl : public CompositeEditCommandImpl
+{
+public:
+	DeleteSelectionCommandImpl(DOM::DocumentImpl *document);
+	virtual ~DeleteSelectionCommandImpl();
+	
+	virtual void apply();
+};
+
+class InputTextCommandImpl : public CompositeEditCommandImpl
+{
+public:
+    InputTextCommandImpl(DOM::DocumentImpl *document, const DOM::DOMString &text);
+    virtual ~InputTextCommandImpl();
+
+    virtual int commandID() const;
+
+    virtual void apply();
+
+    virtual bool coalesce(const EditCommand &);
+
+    virtual bool groupForUndo(const EditCommand &) const;
+    virtual bool groupForRedo(const EditCommand &) const;
+
+    DOM::DOMString text() const { return m_text; }
+    bool isLineBreak(const DOM::DOMString &text) const;
+    bool isSpace(const DOM::DOMString &text) const;
+    
+private:
+    void execute(const DOM::DOMString &text);
+
+    DOM::DOMString m_text;
+};
+
+class DeleteKeyCommandImpl : public CompositeEditCommandImpl
+{
+public:
+    DeleteKeyCommandImpl(DOM::DocumentImpl *document);
+    virtual ~DeleteKeyCommandImpl();
+    
+    virtual int commandID() const;
+
+    virtual void apply();
+
+    virtual bool groupForUndo(const EditCommand &) const;
+    virtual bool groupForRedo(const EditCommand &) const;
+};
+
+class PasteHTMLCommandImpl : public CompositeEditCommandImpl
+{
+public:
+    PasteHTMLCommandImpl(DOM::DocumentImpl *document, const DOM::DOMString &HTMLString);
+    virtual ~PasteHTMLCommandImpl();
+    
+    virtual void apply();
+
+    DOM::DOMString HTMLString() const { return m_HTMLString; }
+
+private:
+    DOM::DOMString m_HTMLString;
+};
+
+}; // end namespace khtml
+
+#endif
+
diff --git a/WebCore/khtml/khtml_part.cpp b/WebCore/khtml/khtml_part.cpp
index fa53c24..57a181a 100644
--- a/WebCore/khtml/khtml_part.cpp
+++ b/WebCore/khtml/khtml_part.cpp
@@ -102,7 +102,7 @@ using khtml::Decoder;
 using khtml::DeleteKeyCommand;
 using khtml::DeleteSelectionCommand;
 using khtml::EditCommand;
-using khtml::EditCommandPtr;
+using khtml::EditCommand;
 using khtml::InlineTextBox;
 using khtml::PasteHTMLCommand;
 using khtml::RenderObject;
@@ -394,7 +394,7 @@ bool KHTMLPart::openURL( const KURL &url )
   // clear edit commands
   d->m_undoEditCommands.clear();
   d->m_redoEditCommands.clear();
-  d->m_lastEditCommand = EditCommandPtr(0);
+  d->m_lastEditCommand = EditCommand();
 #if APPLE_CHANGES
   KWQ(this)->clearUndoRedoOperations();
 #endif
@@ -2484,7 +2484,7 @@ void KHTMLPart::clearSelection()
 
 void KHTMLPart::deleteSelection()
 {
-    EditCommandPtr cmd(new DeleteSelectionCommand(d->m_doc));
+    EditCommand cmd(DeleteSelectionCommand(d->m_doc));
     applyCommand(cmd);
 }
 
@@ -5068,46 +5068,50 @@ bool KHTMLPart::isEditingAtCaret() const
     return false;
 }
 
-void KHTMLPart::applyCommand(const khtml::EditCommandPtr &cmd)
+void KHTMLPart::applyCommand(khtml::EditCommand &cmd)
 {
-    if (d->m_lastEditCommand.isEmpty() || !d->m_lastEditCommand->coalesce(cmd)) {
-        cmd->apply();
+    assert(cmd.notNull());
+
+    if (d->m_lastEditCommand.isNull() || !d->m_lastEditCommand.coalesce(cmd)) {
+        cmd.apply();
 
         // add to undo commands
         d->m_undoEditCommands.append(cmd);
 
+        if (d->m_lastEditCommand.isNull() || !cmd.groupForUndo(d->m_lastEditCommand)) {
+            // clear redo commands
+            d->m_redoEditCommands.clear();
 #if APPLE_CHANGES
-        if (d->m_lastEditCommand.isEmpty() || !cmd->groupForUndo(d->m_lastEditCommand))
             KWQ(this)->registerCommandForUndo();
 #endif
+        }
 
         d->m_lastEditCommand = cmd;
     }
-
-    // always clear redo commands
-    d->m_redoEditCommands.clear();
 }
 
 void KHTMLPart::undoEditing()
 {
-    EditCommandPtr cmd;
-    EditCommandPtr next;
+    assert(d->m_undoEditCommands.count() > 0);
     
+    EditCommand cmd;
+    EditCommand next;
+
     do {
-        assert(d->m_undoEditCommands.count() > 0);
         cmd = d->m_undoEditCommands.last();
+        assert(cmd.notNull());
         
-        cmd->unapply();
+        cmd.unapply();
 
         // EDIT FIXME: Removal is O(N). Improve QValueList to implement 0(1) removal of last element. 
         d->m_undoEditCommands.remove(cmd); 
         d->m_redoEditCommands.append(cmd);
     
-        next = d->m_undoEditCommands.count() > 0 ? d->m_undoEditCommands.last() : EditCommandPtr(0);
+        next = d->m_undoEditCommands.count() > 0 ? d->m_undoEditCommands.last() : EditCommand();
     } 
-    while (!next.isEmpty() && cmd->groupForUndo(next));
+    while (next.notNull() && cmd.groupForUndo(next));
     
-    d->m_lastEditCommand = EditCommandPtr(0);
+    d->m_lastEditCommand = EditCommand();
     
 #if APPLE_CHANGES
     KWQ(this)->registerCommandForRedo();
@@ -5116,24 +5120,26 @@ void KHTMLPart::undoEditing()
 
 void KHTMLPart::redoEditing()
 {
-    EditCommandPtr cmd;
-    EditCommandPtr next;
+    assert(d->m_redoEditCommands.count() > 0);
 
+    EditCommand cmd;
+    EditCommand next;
+    
     do {
-        assert(d->m_redoEditCommands.count() > 0);
         cmd = d->m_redoEditCommands.last();
+        assert(cmd.notNull());
     
-        cmd->reapply();
+        cmd.reapply();
 
         // EDIT FIXME: Removal is O(N). Improve QValueList to implement 0(1) removal of last element. 
         d->m_redoEditCommands.remove(cmd); 
         d->m_undoEditCommands.append(cmd);
 
-        next = d->m_redoEditCommands.count() > 0 ? d->m_redoEditCommands.last() : EditCommandPtr(0);
+        next = d->m_redoEditCommands.count() > 0 ? d->m_redoEditCommands.last() : EditCommand();
     }
-    while (!next.isEmpty() && cmd->groupForRedo(next));
+    while (next.notNull() && cmd.groupForRedo(next));
 
-    d->m_lastEditCommand = EditCommandPtr(0);
+    d->m_lastEditCommand = EditCommand();
     
 #if APPLE_CHANGES
     KWQ(this)->registerCommandForUndo();
@@ -5142,7 +5148,7 @@ void KHTMLPart::redoEditing()
 
 void KHTMLPart::pasteHTMLString(const QString &HTMLString)
 {
-    EditCommandPtr cmd(new PasteHTMLCommand(d->m_doc, DOMString(HTMLString)));
+    EditCommand cmd(PasteHTMLCommand(d->m_doc, DOMString(HTMLString)));
     applyCommand(cmd);
 }
 
diff --git a/WebCore/khtml/khtml_part.h b/WebCore/khtml/khtml_part.h
index 096887a..1d13d9e 100644
--- a/WebCore/khtml/khtml_part.h
+++ b/WebCore/khtml/khtml_part.h
@@ -65,7 +65,6 @@ namespace DOM
 }
 
 using DOM::TristateFlag;
-using khtml::EditCommandPtr;
 
 namespace khtml
 {
@@ -629,7 +628,7 @@ public:
   /**
    * Applies the given edit command.
    */
-  void applyCommand(const khtml::EditCommandPtr &);
+  void applyCommand(khtml::EditCommand &);
 
   /**
    * Performs an undo of the edit.
diff --git a/WebCore/khtml/khtmlpart_p.h b/WebCore/khtml/khtmlpart_p.h
index b204312..50131cf 100644
--- a/WebCore/khtml/khtmlpart_p.h
+++ b/WebCore/khtml/khtmlpart_p.h
@@ -365,9 +365,9 @@ public:
   bool m_focusNodeRestored:1;
 
   TristateFlag m_inEditMode;
-  QValueList<khtml::EditCommandPtr> m_undoEditCommands;
-  QValueList<khtml::EditCommandPtr> m_redoEditCommands;
-  khtml::EditCommandPtr m_lastEditCommand;
+  QValueList<khtml::EditCommand> m_undoEditCommands;
+  QValueList<khtml::EditCommand> m_redoEditCommands;
+  khtml::EditCommand m_lastEditCommand;
 
   int m_focusNodeNumber;
 
diff --git a/WebCore/khtml/misc/shared.h b/WebCore/khtml/misc/shared.h
index 8f6b858..190265d 100644
--- a/WebCore/khtml/misc/shared.h
+++ b/WebCore/khtml/misc/shared.h
@@ -60,7 +60,10 @@ public:
 	SharedPtr(const SharedPtr &o) : m_ptr(o.m_ptr) { if (m_ptr) m_ptr->ref(); }
     ~SharedPtr() { if (m_ptr) m_ptr->deref(); }
 	
-    bool isEmpty() const { return m_ptr == 0; }
+    bool isNull() const { return m_ptr == 0; }
+    bool notNull() const { return m_ptr != 0; }
+
+    void reset() { if (m_ptr) m_ptr->deref(); m_ptr = 0; }
     
     T * get() const { return m_ptr; }
 	T &operator*() const { return *m_ptr; }
diff --git a/WebCore/khtml/xml/dom_elementimpl.cpp b/WebCore/khtml/xml/dom_elementimpl.cpp
index ac93325..650b1d5 100644
--- a/WebCore/khtml/xml/dom_elementimpl.cpp
+++ b/WebCore/khtml/xml/dom_elementimpl.cpp
@@ -366,11 +366,11 @@ void ElementImpl::defaultEventHandler(EventImpl *evt)
 {
     if (evt->id() == EventImpl::KEYPRESS_EVENT && isContentEditable()) {
         KeyboardEventImpl *k = static_cast<KeyboardEventImpl *>(evt);
-        EditCommandPtr cmd;
+        EditCommand cmd;
         if (k->keyIdentifier() == "U+00007F" || 
             k->keyIdentifier() == "U+000008" || 
             k->keyIdentifier() == "ForwardDelete") {
-            cmd = EditCommandPtr(new DeleteKeyCommand(getDocument()));
+            cmd = DeleteKeyCommand(getDocument());
         }
         else if (k->keyIdentifier() == "Right") {
             KHTMLPart *part = getDocument()->part();
@@ -398,9 +398,9 @@ void ElementImpl::defaultEventHandler(EventImpl *evt)
         }
         else {
             QString text(k->qKeyEvent()->text());
-            cmd = EditCommandPtr(new InputTextCommand(getDocument(), text));
+            cmd = InputTextCommand(getDocument(), text);
         }
-        if (!cmd.isEmpty()) {
+        if (cmd.notNull()) {
             KHTMLPart *part = getDocument()->part();
             if (part) {
                 part->applyCommand(cmd);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list