[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:39:20 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit 1cfab7a6e66ab5686a06a64b7c0faf2f403c7465
Author: kocienda <kocienda at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu May 13 16:41:20 2004 +0000

    WebCore:
    
            Reviewed by Hyatt
    
            Implemented first cut at text style change code.
    
            * khtml/editing/htmlediting.cpp:
            (khtml::ApplyStyleCommand::ApplyStyleCommand):
            (khtml::ApplyStyleCommand::~ApplyStyleCommand):
            (khtml::ApplyStyleCommand::impl):
            (khtml::RemoveCSSPropertyCommand::RemoveCSSPropertyCommand):
            (khtml::RemoveCSSPropertyCommand::~RemoveCSSPropertyCommand):
            (khtml::RemoveCSSPropertyCommand::impl):
            (khtml::RemoveCSSPropertyCommand::styleDeclaration):
            (khtml::RemoveCSSPropertyCommand::property):
            (khtml::RemoveNodeAttributeCommand::RemoveNodeAttributeCommand):
            (khtml::RemoveNodeAttributeCommand::~RemoveNodeAttributeCommand):
            (khtml::RemoveNodeAttributeCommand::impl):
            (khtml::RemoveNodeAttributeCommand::element):
            (khtml::RemoveNodeAttributeCommand::attribute):
            (khtml::RemoveNodePreservingChildrenCommand::RemoveNodePreservingChildrenCommand):
            (khtml::RemoveNodePreservingChildrenCommand::~RemoveNodePreservingChildrenCommand):
            (khtml::RemoveNodePreservingChildrenCommand::impl):
            (khtml::RemoveNodePreservingChildrenCommand::node):
            (khtml::SetNodeAttributeCommand::SetNodeAttributeCommand):
            (khtml::SetNodeAttributeCommand::~SetNodeAttributeCommand):
            (khtml::SetNodeAttributeCommand::impl):
            (khtml::SetNodeAttributeCommand::element):
            (khtml::SetNodeAttributeCommand::attribute):
            (khtml::SetNodeAttributeCommand::value):
            * khtml/editing/htmlediting.h:
            (khtml::):
            (khtml::ApplyStyleCommand::):
    
            Removed a bunch of unnecessary DOM namespace qualifiers.
            Fixed calls to parent(), which relied on the TreeShared interface to get a parent,
            and changed to the parentNode() DOM Node call, which is more suitable given the
            intention.
    
            * khtml/editing/htmlediting_impl.cpp:
            (khtml::CompositeEditCommandImpl::insertNodeBefore):
            (khtml::CompositeEditCommandImpl::insertNodeAfter):
            (khtml::CompositeEditCommandImpl::appendNode):
            (khtml::CompositeEditCommandImpl::removeNode):
            (khtml::CompositeEditCommandImpl::removeNodeAndPrune):
            (khtml::CompositeEditCommandImpl::removeNodePreservingChildren):
            (khtml::CompositeEditCommandImpl::splitTextNode):
            (khtml::CompositeEditCommandImpl::joinTextNodes):
            (khtml::CompositeEditCommandImpl::insertText):
            (khtml::CompositeEditCommandImpl::deleteText):
            (khtml::CompositeEditCommandImpl::replaceText):
            (khtml::CompositeEditCommandImpl::removeCSSProperty):
            (khtml::CompositeEditCommandImpl::removeNodeAttribute):
            (khtml::CompositeEditCommandImpl::setNodeAttribute):
    
    
            Text style change command implementations.
            There are a couple more parent() -> parentNode() changes in here as well.
    
            (khtml::ApplyStyleCommandImpl::ApplyStyleCommandImpl):
            (khtml::ApplyStyleCommandImpl::~ApplyStyleCommandImpl):
            (khtml::ApplyStyleCommandImpl::commandID):
            (khtml::ApplyStyleCommandImpl::doApply):
            (khtml::ApplyStyleCommandImpl::isHTMLStyleNode):
            (khtml::ApplyStyleCommandImpl::removeHTMLStyleNode):
            (khtml::ApplyStyleCommandImpl::removeCSSStyle):
            (khtml::ApplyStyleCommandImpl::removeCSSProperty):
            (khtml::ApplyStyleCommandImpl::setNodeAttribute):
            (khtml::ApplyStyleCommandImpl::removeNodeAttribute):
            (khtml::ApplyStyleCommandImpl::removeNodePreservingChildren):
            (khtml::ApplyStyleCommandImpl::mustExlicitlyApplyStyle):
            (khtml::ApplyStyleCommandImpl::createExplicitApplyStyleNode):
            (khtml::ApplyStyleCommandImpl::currentlyHasStyle):
            (khtml::ApplyStyleCommandImpl::cssProperty):
            (khtml::ApplyStyleCommandImpl::matchesTargetStyle):
            (khtml::ApplyStyleCommandImpl::positionInsertionPoint):
            (khtml::ApplyStyleCommandImpl::splitTextAtStartIfNeeded):
            (khtml::ApplyStyleCommandImpl::splitTextAtEndIfNeeded):
            (khtml::ApplyStyleCommandImpl::applyStyleIfNeeded):
            (khtml::ApplyStyleCommandImpl::removeStyle):
            (khtml::ApplyStyleCommandImpl::cloneSelection):
            (khtml::ApplyStyleCommandImpl::insertFragment):
            (khtml::ApplyStyleCommandImpl::applyInPlace):
            (khtml::ApplyStyleCommandImpl::applyUsingFragment):
            (khtml::DeleteSelectionCommandImpl::DeleteSelectionCommandImpl):
            (khtml::InsertNodeBeforeCommandImpl::doApply):
            (khtml::InsertNodeBeforeCommandImpl::doUnapply):
            (khtml::JoinTextNodesCommandImpl::doApply):
            (khtml::PasteMarkupCommandImpl::PasteMarkupCommandImpl):
            (khtml::RemoveCSSPropertyCommandImpl::RemoveCSSPropertyCommandImpl):
            (khtml::RemoveCSSPropertyCommandImpl::~RemoveCSSPropertyCommandImpl):
            (khtml::RemoveCSSPropertyCommandImpl::commandID):
            (khtml::RemoveCSSPropertyCommandImpl::doApply):
            (khtml::RemoveCSSPropertyCommandImpl::doUnapply):
            (khtml::RemoveNodeAttributeCommandImpl::RemoveNodeAttributeCommandImpl):
            (khtml::RemoveNodeAttributeCommandImpl::~RemoveNodeAttributeCommandImpl):
            (khtml::RemoveNodeAttributeCommandImpl::commandID):
            (khtml::RemoveNodeAttributeCommandImpl::doApply):
            (khtml::RemoveNodeAttributeCommandImpl::doUnapply):
            (khtml::RemoveNodePreservingChildrenCommandImpl::RemoveNodePreservingChildrenCommandImpl):
            (khtml::RemoveNodePreservingChildrenCommandImpl::~RemoveNodePreservingChildrenCommandImpl):
            (khtml::RemoveNodePreservingChildrenCommandImpl::commandID):
            (khtml::RemoveNodePreservingChildrenCommandImpl::doApply):
            (khtml::SetNodeAttributeCommandImpl::SetNodeAttributeCommandImpl):
            (khtml::SetNodeAttributeCommandImpl::~SetNodeAttributeCommandImpl):
            (khtml::SetNodeAttributeCommandImpl::commandID):
            (khtml::SetNodeAttributeCommandImpl::doApply):
            (khtml::SetNodeAttributeCommandImpl::doUnapply):
            (khtml::SplitTextNodeCommandImpl::doUnapply):
            (khtml::TypingCommandImpl::insertText):
    
    
            Text style change command implementations.
    
            * khtml/editing/htmlediting_impl.h:
            (khtml::ApplyStyleCommandImpl::):
            (khtml::ApplyStyleCommandImpl::removingStyle):
            (khtml::RemoveCSSPropertyCommandImpl::styleDeclaration):
            (khtml::RemoveCSSPropertyCommandImpl::property):
            (khtml::RemoveNodeAttributeCommandImpl::element):
            (khtml::RemoveNodeAttributeCommandImpl::attribute):
            (khtml::RemoveNodePreservingChildrenCommandImpl::node):
            (khtml::SetNodeAttributeCommandImpl::element):
            (khtml::SetNodeAttributeCommandImpl::attribute):
            (khtml::SetNodeAttributeCommandImpl::value):
    
    
            Fixed a bug where the TreeWalker returned the current node instead
            of null when an attempt was made to use the iterator to go to a
            non-existent location.
    
            * khtml/xml/dom2_traversalimpl.cpp:
            (DOM::TreeWalkerImpl::parentNode):
            (DOM::TreeWalkerImpl::firstChild):
            (DOM::TreeWalkerImpl::lastChild):
            (DOM::TreeWalkerImpl::previousSibling):
            (DOM::TreeWalkerImpl::nextSibling):
            (DOM::TreeWalkerImpl::previousNode):
            (DOM::TreeWalkerImpl::nextNode):
    
    
            A convenience.
    
            * khtml/xml/dom_elementimpl.cpp:
            (ElementImpl::hasAttributes):
            * khtml/xml/dom_elementimpl.h:
    
    
            New helpers to begin moving us to using DOM Range-compliant positions in our code.
    
            * khtml/xml/dom_position.cpp:
            (DOM::Position::equivalentRangeCompliantPosition):
            (DOM::Position::equivalentShallowPosition):
            (DOM::Position::inLastEditableInContainingEditableBlock):
    
    
            (DOM::Position::debugPosition): Debugging aid.
            * khtml/xml/dom_position.h:
    
            * kwq/WebCoreBridge.mm:
            (-[WebCoreBridge applyStyle:]): First bit of wiring up. Some hard-coded temporary code
            in here will need to be improved soon.
    
    WebKit:
    
    	Fixed:
    	<rdar://problem/3633296>: (Japanese input is not working properly in Carbon Web Kit applications (including CarbonWeb))
    	<rdar://problem/3631390>: (can't toggle between Input Methods (IMEs) using cmd-space in Carbon Web Kit applications)
    
            Reviewed by rjw.
    
    	* Carbon.subproj/CarbonWindowAdapter.m:
            (-[CarbonWindowAdapter sendSuperEvent:]): call [NSInputContext processInputKeyBindings:inEvent] just as NSApp does
            * Carbon.subproj/HIWebView.m:
            (HIWebViewEventHandler): [NSApp setWindowsNeedUpdate:YES] must be called before events so that ActivateTSMDocument is called to set an active document. Without an active document, TSM will use a default document which uses a bottom-line input window which we don't want.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6585 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 6c33d97..7f417e7 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,166 @@
+2004-05-13  Ken Kocienda  <kocienda at apple.com>
+
+        Reviewed by Hyatt
+
+        Implemented first cut at text style change code.
+
+        * khtml/editing/htmlediting.cpp:
+        (khtml::ApplyStyleCommand::ApplyStyleCommand):
+        (khtml::ApplyStyleCommand::~ApplyStyleCommand):
+        (khtml::ApplyStyleCommand::impl):
+        (khtml::RemoveCSSPropertyCommand::RemoveCSSPropertyCommand):
+        (khtml::RemoveCSSPropertyCommand::~RemoveCSSPropertyCommand):
+        (khtml::RemoveCSSPropertyCommand::impl):
+        (khtml::RemoveCSSPropertyCommand::styleDeclaration):
+        (khtml::RemoveCSSPropertyCommand::property):
+        (khtml::RemoveNodeAttributeCommand::RemoveNodeAttributeCommand):
+        (khtml::RemoveNodeAttributeCommand::~RemoveNodeAttributeCommand):
+        (khtml::RemoveNodeAttributeCommand::impl):
+        (khtml::RemoveNodeAttributeCommand::element):
+        (khtml::RemoveNodeAttributeCommand::attribute):
+        (khtml::RemoveNodePreservingChildrenCommand::RemoveNodePreservingChildrenCommand):
+        (khtml::RemoveNodePreservingChildrenCommand::~RemoveNodePreservingChildrenCommand):
+        (khtml::RemoveNodePreservingChildrenCommand::impl):
+        (khtml::RemoveNodePreservingChildrenCommand::node):
+        (khtml::SetNodeAttributeCommand::SetNodeAttributeCommand):
+        (khtml::SetNodeAttributeCommand::~SetNodeAttributeCommand):
+        (khtml::SetNodeAttributeCommand::impl):
+        (khtml::SetNodeAttributeCommand::element):
+        (khtml::SetNodeAttributeCommand::attribute):
+        (khtml::SetNodeAttributeCommand::value):
+        * khtml/editing/htmlediting.h:
+        (khtml::):
+        (khtml::ApplyStyleCommand::):
+        
+        Removed a bunch of unnecessary DOM namespace qualifiers.
+        Fixed calls to parent(), which relied on the TreeShared interface to get a parent,
+        and changed to the parentNode() DOM Node call, which is more suitable given the
+        intention.
+        
+        * khtml/editing/htmlediting_impl.cpp:
+        (khtml::CompositeEditCommandImpl::insertNodeBefore):
+        (khtml::CompositeEditCommandImpl::insertNodeAfter):
+        (khtml::CompositeEditCommandImpl::appendNode):
+        (khtml::CompositeEditCommandImpl::removeNode):
+        (khtml::CompositeEditCommandImpl::removeNodeAndPrune):
+        (khtml::CompositeEditCommandImpl::removeNodePreservingChildren):
+        (khtml::CompositeEditCommandImpl::splitTextNode):
+        (khtml::CompositeEditCommandImpl::joinTextNodes):
+        (khtml::CompositeEditCommandImpl::insertText):
+        (khtml::CompositeEditCommandImpl::deleteText):
+        (khtml::CompositeEditCommandImpl::replaceText):
+        (khtml::CompositeEditCommandImpl::removeCSSProperty):
+        (khtml::CompositeEditCommandImpl::removeNodeAttribute):
+        (khtml::CompositeEditCommandImpl::setNodeAttribute):
+        
+        
+        Text style change command implementations.
+        There are a couple more parent() -> parentNode() changes in here as well.
+        
+        (khtml::ApplyStyleCommandImpl::ApplyStyleCommandImpl):
+        (khtml::ApplyStyleCommandImpl::~ApplyStyleCommandImpl):
+        (khtml::ApplyStyleCommandImpl::commandID):
+        (khtml::ApplyStyleCommandImpl::doApply):
+        (khtml::ApplyStyleCommandImpl::isHTMLStyleNode):
+        (khtml::ApplyStyleCommandImpl::removeHTMLStyleNode):
+        (khtml::ApplyStyleCommandImpl::removeCSSStyle):
+        (khtml::ApplyStyleCommandImpl::removeCSSProperty):
+        (khtml::ApplyStyleCommandImpl::setNodeAttribute):
+        (khtml::ApplyStyleCommandImpl::removeNodeAttribute):
+        (khtml::ApplyStyleCommandImpl::removeNodePreservingChildren):
+        (khtml::ApplyStyleCommandImpl::mustExlicitlyApplyStyle):
+        (khtml::ApplyStyleCommandImpl::createExplicitApplyStyleNode):
+        (khtml::ApplyStyleCommandImpl::currentlyHasStyle):
+        (khtml::ApplyStyleCommandImpl::cssProperty):
+        (khtml::ApplyStyleCommandImpl::matchesTargetStyle):
+        (khtml::ApplyStyleCommandImpl::positionInsertionPoint):
+        (khtml::ApplyStyleCommandImpl::splitTextAtStartIfNeeded):
+        (khtml::ApplyStyleCommandImpl::splitTextAtEndIfNeeded):
+        (khtml::ApplyStyleCommandImpl::applyStyleIfNeeded):
+        (khtml::ApplyStyleCommandImpl::removeStyle):
+        (khtml::ApplyStyleCommandImpl::cloneSelection):
+        (khtml::ApplyStyleCommandImpl::insertFragment):
+        (khtml::ApplyStyleCommandImpl::applyInPlace):
+        (khtml::ApplyStyleCommandImpl::applyUsingFragment):
+        (khtml::DeleteSelectionCommandImpl::DeleteSelectionCommandImpl):
+        (khtml::InsertNodeBeforeCommandImpl::doApply):
+        (khtml::InsertNodeBeforeCommandImpl::doUnapply):
+        (khtml::JoinTextNodesCommandImpl::doApply):
+        (khtml::PasteMarkupCommandImpl::PasteMarkupCommandImpl):
+        (khtml::RemoveCSSPropertyCommandImpl::RemoveCSSPropertyCommandImpl):
+        (khtml::RemoveCSSPropertyCommandImpl::~RemoveCSSPropertyCommandImpl):
+        (khtml::RemoveCSSPropertyCommandImpl::commandID):
+        (khtml::RemoveCSSPropertyCommandImpl::doApply):
+        (khtml::RemoveCSSPropertyCommandImpl::doUnapply):
+        (khtml::RemoveNodeAttributeCommandImpl::RemoveNodeAttributeCommandImpl):
+        (khtml::RemoveNodeAttributeCommandImpl::~RemoveNodeAttributeCommandImpl):
+        (khtml::RemoveNodeAttributeCommandImpl::commandID):
+        (khtml::RemoveNodeAttributeCommandImpl::doApply):
+        (khtml::RemoveNodeAttributeCommandImpl::doUnapply):
+        (khtml::RemoveNodePreservingChildrenCommandImpl::RemoveNodePreservingChildrenCommandImpl):
+        (khtml::RemoveNodePreservingChildrenCommandImpl::~RemoveNodePreservingChildrenCommandImpl):
+        (khtml::RemoveNodePreservingChildrenCommandImpl::commandID):
+        (khtml::RemoveNodePreservingChildrenCommandImpl::doApply):
+        (khtml::SetNodeAttributeCommandImpl::SetNodeAttributeCommandImpl):
+        (khtml::SetNodeAttributeCommandImpl::~SetNodeAttributeCommandImpl):
+        (khtml::SetNodeAttributeCommandImpl::commandID):
+        (khtml::SetNodeAttributeCommandImpl::doApply):
+        (khtml::SetNodeAttributeCommandImpl::doUnapply):
+        (khtml::SplitTextNodeCommandImpl::doUnapply):
+        (khtml::TypingCommandImpl::insertText):
+
+
+        Text style change command implementations.
+
+        * khtml/editing/htmlediting_impl.h:
+        (khtml::ApplyStyleCommandImpl::):
+        (khtml::ApplyStyleCommandImpl::removingStyle):
+        (khtml::RemoveCSSPropertyCommandImpl::styleDeclaration):
+        (khtml::RemoveCSSPropertyCommandImpl::property):
+        (khtml::RemoveNodeAttributeCommandImpl::element):
+        (khtml::RemoveNodeAttributeCommandImpl::attribute):
+        (khtml::RemoveNodePreservingChildrenCommandImpl::node):
+        (khtml::SetNodeAttributeCommandImpl::element):
+        (khtml::SetNodeAttributeCommandImpl::attribute):
+        (khtml::SetNodeAttributeCommandImpl::value):
+        
+        
+        Fixed a bug where the TreeWalker returned the current node instead
+        of null when an attempt was made to use the iterator to go to a
+        non-existent location.
+        
+        * khtml/xml/dom2_traversalimpl.cpp:
+        (DOM::TreeWalkerImpl::parentNode):
+        (DOM::TreeWalkerImpl::firstChild):
+        (DOM::TreeWalkerImpl::lastChild):
+        (DOM::TreeWalkerImpl::previousSibling):
+        (DOM::TreeWalkerImpl::nextSibling):
+        (DOM::TreeWalkerImpl::previousNode):
+        (DOM::TreeWalkerImpl::nextNode):
+        
+        
+        A convenience.
+        
+        * khtml/xml/dom_elementimpl.cpp:
+        (ElementImpl::hasAttributes):
+        * khtml/xml/dom_elementimpl.h:
+        
+        
+        New helpers to begin moving us to using DOM Range-compliant positions in our code.
+        
+        * khtml/xml/dom_position.cpp:
+        (DOM::Position::equivalentRangeCompliantPosition):
+        (DOM::Position::equivalentShallowPosition):
+        (DOM::Position::inLastEditableInContainingEditableBlock):
+        
+        
+        (DOM::Position::debugPosition): Debugging aid.
+        * khtml/xml/dom_position.h:
+       
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge applyStyle:]): First bit of wiring up. Some hard-coded temporary code 
+        in here will need to be improved soon.
+
 2004-05-12  David Hyatt  <hyatt at apple.com>
 
 	Improve layout scheduling.  Make sure no layouts can be scheduled until over a minimum delay threshold.
diff --git a/WebCore/khtml/editing/SelectionController.cpp b/WebCore/khtml/editing/SelectionController.cpp
index 086487a..04217f4 100644
--- a/WebCore/khtml/editing/SelectionController.cpp
+++ b/WebCore/khtml/editing/SelectionController.cpp
@@ -397,7 +397,9 @@ Range Selection::toRange() const
     if (isEmpty())
         return Range();
 
-    return Range(Node(start().node()), start().offset(), Node(end().node()), end().offset());
+    Position s(start().equivalentRangeCompliantPosition());
+    Position e(end().equivalentRangeCompliantPosition());
+    return Range(Node(s.node()), s.offset(), Node(e.node()), e.offset());
 }
 
 void Selection::layoutCaret()
diff --git a/WebCore/khtml/editing/htmlediting.cpp b/WebCore/khtml/editing/htmlediting.cpp
index 77d1051..ef263f5 100644
--- a/WebCore/khtml/editing/htmlediting.cpp
+++ b/WebCore/khtml/editing/htmlediting.cpp
@@ -27,6 +27,7 @@
 #include "htmlediting_impl.h"
 
 #include "khtml_part.h"
+#include "dom/dom_doc.h"
 #include "dom/dom_position.h"
 #include "xml/dom_docimpl.h"
 #include "xml/dom_nodeimpl.h"
@@ -38,46 +39,16 @@
 #include "KWQLogging.h"
 #endif
 
+using DOM::CSSStyleDeclarationImpl;
 using DOM::DocumentImpl;
+using DOM::ElementImpl;
 using DOM::Position;
 using DOM::DOMString;
 using DOM::NodeImpl;
+using DOM::NodeListImpl;
 using DOM::Selection;
 using DOM::TextImpl;
 
-using khtml::AppendNodeCommand;
-using khtml::AppendNodeCommandImpl;
-using khtml::CompositeEditCommand;
-using khtml::CompositeEditCommandImpl;
-using khtml::DeleteCollapsibleWhitespaceCommand;
-using khtml::DeleteCollapsibleWhitespaceCommandImpl;
-using khtml::DeleteSelectionCommand;
-using khtml::DeleteSelectionCommandImpl;
-using khtml::DeleteTextCommand;
-using khtml::DeleteTextCommandImpl;
-using khtml::EditCommand;
-using khtml::EditCommandImpl;
-using khtml::InputNewlineCommand;
-using khtml::InputNewlineCommandImpl;
-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::RemoveNodeCommand;
-using khtml::RemoveNodeCommandImpl;
-using khtml::RemoveNodeAndPruneCommand;
-using khtml::RemoveNodeAndPruneCommandImpl;
-using khtml::PasteMarkupCommand;
-using khtml::PasteMarkupCommandImpl;
-using khtml::SplitTextNodeCommand;
-using khtml::SplitTextNodeCommandImpl;
-using khtml::TypingCommand;
-using khtml::TypingCommandImpl;
-
 #if !APPLE_CHANGES
 #define ASSERT(assertion) ((void)0)
 #define ASSERT_WITH_MESSAGE(assertion, formatAndArgs...) ((void)0)
@@ -93,7 +64,10 @@ using khtml::TypingCommandImpl;
 #define IF_IMPL_NULL_RETURN do { \
         if (isNull()) { return; } \
     } while (0)
-        
+
+
+namespace khtml {
+
 //------------------------------------------------------------------------------------------
 // EditCommand
 
@@ -275,6 +249,23 @@ NodeImpl *AppendNodeCommand::appendChild() const
 }
 
 //------------------------------------------------------------------------------------------
+// ApplyStyleCommand
+
+ApplyStyleCommand::ApplyStyleCommand(DocumentImpl *document, EStyle style)
+    : CompositeEditCommand(new ApplyStyleCommandImpl(document, style))
+{
+}
+
+ApplyStyleCommand::~ApplyStyleCommand()
+{
+}
+
+ApplyStyleCommandImpl *ApplyStyleCommand::impl() const
+{
+    return static_cast<ApplyStyleCommandImpl *>(get());
+}
+
+//------------------------------------------------------------------------------------------
 // DeleteCollapsibleWhitespaceCommand
 
 DeleteCollapsibleWhitespaceCommand::DeleteCollapsibleWhitespaceCommand(DocumentImpl *document)
@@ -536,6 +527,64 @@ DOMString PasteMarkupCommand::markupString() const
 }
 
 //------------------------------------------------------------------------------------------
+// RemoveCSSPropertyCommand
+
+RemoveCSSPropertyCommand::RemoveCSSPropertyCommand(DocumentImpl *document, CSSStyleDeclarationImpl *decl, int property)
+    : EditCommand(new RemoveCSSPropertyCommandImpl(document, decl, property))
+{
+}
+
+RemoveCSSPropertyCommand::~RemoveCSSPropertyCommand()
+{
+}
+
+RemoveCSSPropertyCommandImpl *RemoveCSSPropertyCommand::impl() const
+{
+    return static_cast<RemoveCSSPropertyCommandImpl *>(get());
+}
+
+CSSStyleDeclarationImpl *RemoveCSSPropertyCommand::styleDeclaration() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->styleDeclaration();
+}
+
+int RemoveCSSPropertyCommand::property() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->property();
+}
+
+//------------------------------------------------------------------------------------------
+// RemoveNodeAttributeCommand
+
+RemoveNodeAttributeCommand::RemoveNodeAttributeCommand(DocumentImpl *document, ElementImpl *element, NodeImpl::Id attribute)
+    : EditCommand(new RemoveNodeAttributeCommandImpl(document, element, attribute))
+{
+}
+
+RemoveNodeAttributeCommand::~RemoveNodeAttributeCommand()
+{
+}
+
+RemoveNodeAttributeCommandImpl *RemoveNodeAttributeCommand::impl() const
+{
+    return static_cast<RemoveNodeAttributeCommandImpl *>(get());
+}
+
+ElementImpl *RemoveNodeAttributeCommand::element() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->element();
+}
+
+NodeImpl::Id RemoveNodeAttributeCommand::attribute() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->attribute();
+}
+
+//------------------------------------------------------------------------------------------
 // RemoveNodeCommand
 
 RemoveNodeCommand::RemoveNodeCommand(DocumentImpl *document, NodeImpl *node)
@@ -582,6 +631,64 @@ NodeImpl *RemoveNodeAndPruneCommand::node() const
 }
 
 //------------------------------------------------------------------------------------------
+// RemoveNodePreservingChildrenCommand
+
+RemoveNodePreservingChildrenCommand::RemoveNodePreservingChildrenCommand(DocumentImpl *document, NodeImpl *node)
+    : CompositeEditCommand(new RemoveNodePreservingChildrenCommandImpl(document, node))
+{
+}
+
+RemoveNodePreservingChildrenCommand::~RemoveNodePreservingChildrenCommand()
+{
+}
+
+RemoveNodePreservingChildrenCommandImpl *RemoveNodePreservingChildrenCommand::impl() const
+{
+    return static_cast<RemoveNodePreservingChildrenCommandImpl *>(get());
+}
+
+NodeImpl *RemoveNodePreservingChildrenCommand::node() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->node();
+}
+
+//------------------------------------------------------------------------------------------
+// SetNodeAttributeCommand
+
+SetNodeAttributeCommand::SetNodeAttributeCommand(DocumentImpl *document, ElementImpl *element, NodeImpl::Id attribute, const DOM::DOMString &value)
+    : EditCommand(new SetNodeAttributeCommandImpl(document, element, attribute, value))
+{
+}
+
+SetNodeAttributeCommand::~SetNodeAttributeCommand()
+{
+}
+
+SetNodeAttributeCommandImpl *SetNodeAttributeCommand::impl() const
+{
+    return static_cast<SetNodeAttributeCommandImpl *>(get());
+}
+
+ElementImpl *SetNodeAttributeCommand::element() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->element();
+}
+
+NodeImpl::Id SetNodeAttributeCommand::attribute() const
+{
+    IF_IMPL_NULL_RETURN_ARG(0);
+    return impl()->attribute();
+}
+
+DOMString SetNodeAttributeCommand::value() const
+{
+    IF_IMPL_NULL_RETURN_ARG("");
+    return impl()->value();
+}
+
+//------------------------------------------------------------------------------------------
 // SplitTextNodeCommand
 
 SplitTextNodeCommand::SplitTextNodeCommand(DocumentImpl *document, TextImpl *text, long offset)
@@ -723,3 +830,4 @@ void TypingCommand::deleteKeyPressed()
     return impl()->deleteKeyPressed();
 }
 
+} // namespace khtml
diff --git a/WebCore/khtml/editing/htmlediting.h b/WebCore/khtml/editing/htmlediting.h
index 25ad852..389dc3c 100644
--- a/WebCore/khtml/editing/htmlediting.h
+++ b/WebCore/khtml/editing/htmlediting.h
@@ -30,10 +30,13 @@
 #include "dom_selection.h"
 #include "dom_string.h"
 #include "shared.h"
+#include "xml/dom_nodeimpl.h"
 
 namespace DOM {
+    class CSSStyleDeclarationImpl;
     class DocumentImpl;
     class DOMString;
+    class ElementImpl;
     class NodeImpl;
     class Position;
     class Selection;
@@ -43,6 +46,7 @@ namespace DOM {
 namespace khtml {
 
 class AppendNodeCommandImpl;
+class ApplyStyleCommandImpl;
 class CompositeEditCommandImpl;
 class DeleteCollapsibleWhitespaceCommandImpl;
 class DeleteSelectionCommandImpl;
@@ -55,8 +59,12 @@ class InsertNodeBeforeCommandImpl;
 class InsertTextCommandImpl;
 class JoinTextNodesCommandImpl;
 class PasteMarkupCommandImpl;
+class RemoveCSSPropertyCommandImpl;
+class RemoveNodeAttributeCommandImpl;
 class RemoveNodeCommandImpl;
 class RemoveNodeAndPruneCommandImpl;
+class RemoveNodePreservingChildrenCommandImpl;
+class SetNodeAttributeCommandImpl;
 class SplitTextNodeCommandImpl;
 class TypingCommandImpl;
 
@@ -66,6 +74,7 @@ class TypingCommandImpl;
 enum ECommandID { 
     EditCommandID, // leave the base class first, others in alpha order
     AppendNodeCommandID,
+    ApplyStyleCommandID,
     CompositeEditCommandID,
     DeleteCollapsibleWhitespaceCommandID,
     DeleteSelectionCommandID,
@@ -76,8 +85,12 @@ enum ECommandID {
     InsertTextCommandID,
     JoinTextNodesCommandID,
     PasteMarkupCommandID,
+    RemoveCSSPropertyCommandID,
+    RemoveNodeAttributeCommandID,
     RemoveNodeCommandID,
     RemoveNodeAndPruneCommandID,
+    RemoveNodePreservingChildrenCommandID,
+    SetNodeAttributeCommandID,
     SplitTextNodeCommandID,
     TypingCommandID,
 };
@@ -186,6 +199,22 @@ private:
 };
 
 //------------------------------------------------------------------------------------------
+// ApplyStyleCommand
+
+class ApplyStyleCommand : public CompositeEditCommand
+{
+public:
+    
+    enum EStyle { NONE, BOLD };
+
+	ApplyStyleCommand(DOM::DocumentImpl *, EStyle);
+	virtual ~ApplyStyleCommand();
+
+private:
+    inline ApplyStyleCommandImpl *impl() const;
+};
+
+//------------------------------------------------------------------------------------------
 // DeleteCollapsibleWhitespaceCommand
 
 class DeleteCollapsibleWhitespaceCommand : public CompositeEditCommand
@@ -330,6 +359,38 @@ private:
 };
 
 //------------------------------------------------------------------------------------------
+// RemoveCSSPropertyCommand
+
+class RemoveCSSPropertyCommand : public EditCommand
+{
+public:
+	RemoveCSSPropertyCommand(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *, int property);
+	virtual ~RemoveCSSPropertyCommand();
+
+    DOM::CSSStyleDeclarationImpl *styleDeclaration() const;
+    int property() const;
+    
+private:
+    inline RemoveCSSPropertyCommandImpl *impl() const;
+};
+
+//------------------------------------------------------------------------------------------
+// RemoveNodeAttributeCommand
+
+class RemoveNodeAttributeCommand : public EditCommand
+{
+public:
+	RemoveNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute);
+	virtual ~RemoveNodeAttributeCommand();
+
+    DOM::ElementImpl *element() const;
+    DOM::NodeImpl::Id attribute() const;
+    
+private:
+    inline RemoveNodeAttributeCommandImpl *impl() const;
+};
+
+//------------------------------------------------------------------------------------------
 // RemoveNodeCommand
 
 class RemoveNodeCommand : public EditCommand
@@ -360,6 +421,38 @@ private:
 };
 
 //------------------------------------------------------------------------------------------
+// RemoveNodePreservingChildrenCommand
+
+class RemoveNodePreservingChildrenCommand : public CompositeEditCommand
+{
+public:
+    RemoveNodePreservingChildrenCommand(DOM::DocumentImpl *document, DOM::NodeImpl *node);
+    virtual ~RemoveNodePreservingChildrenCommand();
+
+    DOM::NodeImpl *node() const;
+
+private:
+    inline RemoveNodePreservingChildrenCommandImpl *impl() const;
+};
+
+//------------------------------------------------------------------------------------------
+// SetNodeAttributeCommand
+
+class SetNodeAttributeCommand : public EditCommand
+{
+public:
+	SetNodeAttributeCommand(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute, const DOM::DOMString &value);
+	virtual ~SetNodeAttributeCommand();
+
+    DOM::ElementImpl *element() const;
+    DOM::NodeImpl::Id attribute() const;
+    DOM::DOMString value() const;
+    
+private:
+    inline SetNodeAttributeCommandImpl *impl() const;
+};
+
+//------------------------------------------------------------------------------------------
 // SplitTextNodeCommand
 
 class SplitTextNodeCommand : public EditCommand
diff --git a/WebCore/khtml/editing/htmlediting_impl.cpp b/WebCore/khtml/editing/htmlediting_impl.cpp
index 47449e2..52d0a28 100644
--- a/WebCore/khtml/editing/htmlediting_impl.cpp
+++ b/WebCore/khtml/editing/htmlediting_impl.cpp
@@ -25,6 +25,9 @@
 
 #include "htmlediting_impl.h"
 
+#include "cssproperties.h"
+#include "css/css_valueimpl.h"
+#include "dom/css_value.h"
 #include "dom/dom_position.h"
 #include "html/html_elementimpl.h"
 #include "html/html_imageimpl.h"
@@ -43,12 +46,18 @@
 #include "xml/dom_stringimpl.h"
 #include "xml/dom_textimpl.h"
 #include "xml/dom2_rangeimpl.h"
+#include "xml/dom2_viewsimpl.h"
 
 #if APPLE_CHANGES
 #include "KWQAssertions.h"
 #include "KWQLogging.h"
 #endif
 
+using DOM::AttrImpl;
+using DOM::CSSPrimitiveValue;
+using DOM::CSSPrimitiveValueImpl;
+using DOM::CSSProperty;
+using DOM::CSSStyleDeclarationImpl;
 using DOM::DocumentFragmentImpl;
 using DOM::DocumentImpl;
 using DOM::DOMString;
@@ -66,43 +75,7 @@ using DOM::Range;
 using DOM::RangeImpl;
 using DOM::Selection;
 using DOM::TextImpl;
-
-using khtml::AppendNodeCommand;
-using khtml::AppendNodeCommandImpl;
-using khtml::CompositeEditCommand;
-using khtml::CompositeEditCommandImpl;
-using khtml::DeleteCollapsibleWhitespaceCommand;
-using khtml::DeleteCollapsibleWhitespaceCommandImpl;
-using khtml::DeleteSelectionCommand;
-using khtml::DeleteSelectionCommandImpl;
-using khtml::DeleteTextCommand;
-using khtml::DeleteTextCommandImpl;
-using khtml::EditCommand;
-using khtml::EditCommandImpl;
-using khtml::InlineTextBox;
-using khtml::InputNewlineCommand;
-using khtml::InputNewlineCommandImpl;
-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::RemoveNodeCommand;
-using khtml::RemoveNodeCommandImpl;
-using khtml::RemoveNodeAndPruneCommand;
-using khtml::RemoveNodeAndPruneCommandImpl;
-using khtml::RenderObject;
-using khtml::RenderStyle;
-using khtml::RenderText;
-using khtml::PasteMarkupCommand;
-using khtml::PasteMarkupCommandImpl;
-using khtml::SplitTextNodeCommand;
-using khtml::SplitTextNodeCommandImpl;
-using khtml::TypingCommand;
-using khtml::TypingCommandImpl;
+using DOM::TreeWalkerImpl;
 
 #if !APPLE_CHANGES
 #define ASSERT(assertion) ((void)0)
@@ -115,6 +88,9 @@ using khtml::TypingCommandImpl;
 #endif
 #endif
 
+namespace khtml {
+
+
 static inline bool isNBSP(const QChar &c)
 {
     return c == QChar(0xa0);
@@ -415,13 +391,13 @@ void CompositeEditCommandImpl::applyCommandToComposite(EditCommand &cmd)
     m_cmds.append(cmd);
 }
 
-void CompositeEditCommandImpl::insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
+void CompositeEditCommandImpl::insertNodeBefore(NodeImpl *insertChild, NodeImpl *refChild)
 {
     InsertNodeBeforeCommand cmd(document(), insertChild, refChild);
     applyCommandToComposite(cmd);
 }
 
-void CompositeEditCommandImpl::insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild)
+void CompositeEditCommandImpl::insertNodeAfter(NodeImpl *insertChild, NodeImpl *refChild)
 {
     if (refChild->parentNode()->lastChild() == refChild) {
         appendNode(refChild->parentNode(), insertChild);
@@ -455,31 +431,37 @@ void CompositeEditCommandImpl::insertNodeAt(NodeImpl *insertChild, NodeImpl *ref
     }
 }
 
-void CompositeEditCommandImpl::appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild)
+void CompositeEditCommandImpl::appendNode(NodeImpl *parent, NodeImpl *appendChild)
 {
     AppendNodeCommand cmd(document(), parent, appendChild);
     applyCommandToComposite(cmd);
 }
 
-void CompositeEditCommandImpl::removeNode(DOM::NodeImpl *removeChild)
+void CompositeEditCommandImpl::removeNode(NodeImpl *removeChild)
 {
     RemoveNodeCommand cmd(document(), removeChild);
     applyCommandToComposite(cmd);
 }
 
-void CompositeEditCommandImpl::removeNodeAndPrune(DOM::NodeImpl *removeChild)
+void CompositeEditCommandImpl::removeNodeAndPrune(NodeImpl *removeChild)
 {
     RemoveNodeAndPruneCommand cmd(document(), removeChild);
     applyCommandToComposite(cmd);
 }
 
-void CompositeEditCommandImpl::splitTextNode(DOM::TextImpl *text, long offset)
+void CompositeEditCommandImpl::removeNodePreservingChildren(NodeImpl *removeChild)
+{
+    RemoveNodePreservingChildrenCommand cmd(document(), removeChild);
+    applyCommandToComposite(cmd);
+}
+
+void CompositeEditCommandImpl::splitTextNode(TextImpl *text, long offset)
 {
     SplitTextNodeCommand cmd(document(), text, offset);
     applyCommandToComposite(cmd);
 }
 
-void CompositeEditCommandImpl::joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2)
+void CompositeEditCommandImpl::joinTextNodes(TextImpl *text1, TextImpl *text2)
 {
     JoinTextNodesCommand cmd(document(), text1, text2);
     applyCommandToComposite(cmd);
@@ -492,19 +474,19 @@ void CompositeEditCommandImpl::inputText(const DOMString &text)
     cmd.input(text);
 }
 
-void CompositeEditCommandImpl::insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text)
+void CompositeEditCommandImpl::insertText(TextImpl *node, long offset, const DOMString &text)
 {
     InsertTextCommand cmd(document(), node, offset, text);
     applyCommandToComposite(cmd);
 }
 
-void CompositeEditCommandImpl::deleteText(DOM::TextImpl *node, long offset, long count)
+void CompositeEditCommandImpl::deleteText(TextImpl *node, long offset, long count)
 {
     DeleteTextCommand cmd(document(), node, offset, count);
     applyCommandToComposite(cmd);
 }
 
-void CompositeEditCommandImpl::replaceText(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText)
+void CompositeEditCommandImpl::replaceText(TextImpl *node, long offset, long count, const DOMString &replacementText)
 {
     DeleteTextCommand deleteCommand(document(), node, offset, count);
     applyCommandToComposite(deleteCommand);
@@ -540,6 +522,24 @@ void CompositeEditCommandImpl::deleteCollapsibleWhitespace(const Selection &sele
     applyCommandToComposite(cmd);
 }
 
+void CompositeEditCommandImpl::removeCSSProperty(CSSStyleDeclarationImpl *decl, int property)
+{
+    RemoveCSSPropertyCommand cmd(document(), decl, property);
+    applyCommandToComposite(cmd);
+}
+
+void CompositeEditCommandImpl::removeNodeAttribute(ElementImpl *element, int attribute)
+{
+    RemoveNodeAttributeCommand cmd(document(), element, attribute);
+    applyCommandToComposite(cmd);
+}
+
+void CompositeEditCommandImpl::setNodeAttribute(ElementImpl *element, int attribute, const DOMString &value)
+{
+    SetNodeAttributeCommand cmd(document(), element, attribute, value);
+    applyCommandToComposite(cmd);
+}
+
 //==========================================================================================
 // Concrete commands
 //------------------------------------------------------------------------------------------
@@ -590,6 +590,480 @@ void AppendNodeCommandImpl::doUnapply()
 }
 
 //------------------------------------------------------------------------------------------
+// ApplyStyleCommandImpl
+
+ApplyStyleCommandImpl::ApplyStyleCommandImpl(DocumentImpl *document, ApplyStyleCommand::EStyle style)
+    : CompositeEditCommandImpl(document), m_styleConstant(style)
+{   
+}
+
+ApplyStyleCommandImpl::~ApplyStyleCommandImpl()
+{
+}
+
+int ApplyStyleCommandImpl::commandID() const
+{
+    return ApplyStyleCommandID;
+}
+
+void ApplyStyleCommandImpl::doApply()
+{
+    if (endingSelection().state() != Selection::RANGE)
+        return;
+
+    m_removingStyle = currentlyHasStyle();
+    
+    // Right now, we only apply in place if the start and end are in the same
+    // node. This could be improved in the future to handle more cases that
+    // are only a bit more complex than this case.
+    Position start(endingSelection().start().equivalentDownstreamPosition());
+    Position end(endingSelection().end().equivalentUpstreamPosition());
+    if (start.node() == end.node())
+        applyInPlace(start, end);
+    else
+        applyUsingFragment();
+}
+
+//------------------------------------------------------------------------------------------
+// ApplyStyleCommandImpl: style-removal helpers
+
+bool ApplyStyleCommandImpl::isHTMLStyleNode(HTMLElementImpl *elem)
+{
+    switch (m_styleConstant) {
+        case ApplyStyleCommand::BOLD:
+            return elem->id() == ID_B;
+        default:
+        case ApplyStyleCommand::NONE:
+            return false;
+    }
+}
+
+void ApplyStyleCommandImpl::removeHTMLStyleNode(HTMLElementImpl *elem, EUndoable undoable)
+{
+    // This node can be removed.
+    // EDIT FIXME: This does not handle the case where the node
+    // has attributes. But how often do people add attributes to <B> tags? 
+    // Not so often I think.
+    ASSERT(elem);
+    removeNodePreservingChildren(elem, undoable);
+}
+
+void ApplyStyleCommandImpl::removeCSSStyle(HTMLElementImpl *elem, EUndoable undoable)
+{
+    ASSERT(elem);
+
+    CSSStyleDeclarationImpl *decl = elem->inlineStyleDecl();
+    int property = cssProperty(); 
+    if (!decl || !decl->getPropertyCSSValue(property))
+        return;
+        
+    removeCSSProperty(decl, property, undoable);
+
+    // EDIT FIXME: These four lines of code should not be necessary.
+    // The DOM should update without having to do this extra work.
+    if (decl->values()->count() > 0)
+        setNodeAttribute(elem, ATTR_STYLE, decl->cssText(), undoable);
+    else
+        removeNodeAttribute(elem, ATTR_STYLE, undoable);
+}
+
+void ApplyStyleCommandImpl::removeCSSProperty(CSSStyleDeclarationImpl *decl, int property, EUndoable undoable)
+{
+    if (undoable == UNDOABLE)
+        CompositeEditCommandImpl::removeCSSProperty(decl, property);
+    else
+        decl->removeProperty(property);
+}
+
+void ApplyStyleCommandImpl::setNodeAttribute(ElementImpl *elem, int attribute, const DOMString &value, EUndoable undoable)
+{
+    if (undoable == UNDOABLE) {
+        CompositeEditCommandImpl::setNodeAttribute(elem, attribute, value);
+    }
+    else {
+        int exceptionCode = 0;
+        elem->setAttribute(attribute, value.implementation(), exceptionCode);
+        ASSERT(exceptionCode == 0);
+    }
+}
+
+void ApplyStyleCommandImpl::removeNodeAttribute(ElementImpl *elem, int attribute, EUndoable undoable)
+{
+    if (undoable == UNDOABLE) {
+        CompositeEditCommandImpl::removeNodeAttribute(elem, attribute);
+    }
+    else {
+        int exceptionCode = 0;
+        elem->removeAttribute(attribute, exceptionCode);
+        ASSERT(exceptionCode == 0);
+    }
+}
+
+void ApplyStyleCommandImpl::removeNodePreservingChildren(NodeImpl *parent, EUndoable undoable)
+{
+    if (undoable == UNDOABLE) {
+        CompositeEditCommandImpl::removeNodePreservingChildren(parent);
+    }
+    else {
+        NodeImpl *grandparent = parent->parentNode();
+        ASSERT(grandparent);
+        int exceptionCode = 0;
+        while (parent->firstChild()) {
+            NodeImpl *child = parent->firstChild();
+            child->ref();
+            parent->removeChild(child, exceptionCode);
+            ASSERT(exceptionCode == 0);
+            grandparent->insertBefore(child, parent, exceptionCode);
+            ASSERT(exceptionCode == 0);
+            child->deref();
+        }
+        parent->parentNode()->removeChild(parent, exceptionCode);
+        ASSERT(exceptionCode == 0);
+    }
+}
+
+//------------------------------------------------------------------------------------------
+// ApplyStyleCommandImpl: shared helpers
+
+bool ApplyStyleCommandImpl::mustExlicitlyApplyStyle(const Position &pos) const
+{
+    bool hasStyle = currentlyHasStyle(pos);
+    return (removingStyle() && hasStyle) || (!removingStyle() && !hasStyle);
+} 
+
+NodeImpl *ApplyStyleCommandImpl::createExplicitApplyStyleNode() const
+{
+    int exceptionCode = 0;
+    
+    switch (m_styleConstant) {
+        case ApplyStyleCommand::BOLD:
+            if (removingStyle()) {
+                ElementImpl *elem = document()->createHTMLElement("SPAN", exceptionCode);
+                ASSERT(exceptionCode == 0);
+                elem->setAttribute(ATTR_STYLE, "font-weight: normal");
+                return elem;
+            }
+            else {
+                ElementImpl *elem = document()->createHTMLElement("B", exceptionCode);
+                ASSERT(exceptionCode == 0);
+                return elem;
+            }
+        default:
+        case ApplyStyleCommand::NONE:
+            ASSERT_NOT_REACHED();
+    }
+    
+    return 0;
+}
+
+bool ApplyStyleCommandImpl::currentlyHasStyle() const
+{
+    return currentlyHasStyle(endingSelection().start().equivalentDownstreamPosition());
+}
+
+bool ApplyStyleCommandImpl::currentlyHasStyle(const Position &pos) const
+{
+    ASSERT(pos.notEmpty());
+    
+    NodeImpl *node = pos.node();
+    while (node && !node->isElementNode())
+         node = node->parentNode();
+    ASSERT(node);
+
+    CSSStyleDeclarationImpl *decl = document()->defaultView()->getComputedStyle(static_cast<ElementImpl *>(node), 0);
+    ASSERT(decl);
+    
+    switch (m_styleConstant) {
+        case ApplyStyleCommand::BOLD: {
+            CSSPrimitiveValueImpl *value = static_cast<CSSPrimitiveValueImpl *>(decl->getPropertyCSSValue(CSS_PROP_FONT_WEIGHT));
+            return !strcasecmp(value->getStringValue(), "bold");
+        }
+        case ApplyStyleCommand::NONE:
+            ASSERT(0);
+            break;
+    }
+    
+    return false;
+}
+
+int ApplyStyleCommandImpl::cssProperty() const
+{
+    switch (m_styleConstant) {
+        case ApplyStyleCommand::BOLD:
+            return CSS_PROP_FONT_WEIGHT;
+        default:
+        case ApplyStyleCommand::NONE:
+            ASSERT_NOT_REACHED();
+    }
+    
+    return 0;
+}
+
+//------------------------------------------------------------------------------------------
+// ApplyStyleCommandImpl: apply-in-place helpers
+
+bool ApplyStyleCommandImpl::matchesTargetStyle(bool hasStyle) const
+{
+    return (removingStyle() && !hasStyle) || (!removingStyle() && hasStyle);
+}
+
+Position ApplyStyleCommandImpl::positionInsertionPoint(Position pos)
+{
+    if (pos.node()->isTextNode() && (pos.offset() > 0 && pos.offset() < pos.node()->maxOffset())) {
+        SplitTextNodeCommand split(document(), static_cast<TextImpl *>(pos.node()), pos.offset());
+        split.apply();
+        pos = Position(split.node(), 0);
+    }
+
+    if (matchesTargetStyle(currentlyHasStyle(pos)))
+        return pos;
+        
+    // try next node
+    if (pos.offset() >= pos.node()->caretMaxOffset()) {
+        NodeImpl *nextNode = pos.node()->traverseNextNode();
+        if (nextNode) {
+            Position next = Position(nextNode, 0);
+            if (matchesTargetStyle(currentlyHasStyle(next)))
+                return next;
+        }
+    }
+
+    // try previous node
+    if (pos.offset() <= pos.node()->caretMinOffset()) {
+        NodeImpl *prevNode = pos.node()->traversePreviousNode();
+        if (prevNode) {
+            Position prev = Position(prevNode, prevNode->maxOffset());
+            if (matchesTargetStyle(currentlyHasStyle(prev)))
+                return prev;
+        }
+    }
+    
+    return pos;
+}
+
+bool ApplyStyleCommandImpl::splitTextAtStartIfNeeded(const Position &start, const Position &end)
+{
+    if (start.node()->isTextNode() && start.offset() > start.node()->caretMinOffset() && start.offset() < start.node()->caretMaxOffset()) {
+        long endOffsetAdjustment = start.node() == end.node() ? start.offset() : 0;
+        TextImpl *text = static_cast<TextImpl *>(start.node());
+        SplitTextNodeCommand cmd(document(), text, start.offset());
+        applyCommandToComposite(cmd);
+        setEndingSelection(Selection(Position(start.node(), 0), Position(end.node(), end.offset() - endOffsetAdjustment)));
+        return true;
+    }
+    return false;
+}
+
+bool ApplyStyleCommandImpl::splitTextAtEndIfNeeded(const Position &start, const Position &end)
+{
+    if (end.node()->isTextNode() && end.offset() > end.node()->caretMinOffset() && end.offset() < end.node()->caretMaxOffset()) {
+        TextImpl *text = static_cast<TextImpl *>(end.node());
+        SplitTextNodeCommand cmd(document(), text, end.offset());
+        applyCommandToComposite(cmd);
+        NodeImpl *startNode = start.node() == end.node() ? cmd.node()->previousSibling() : start.node();
+        ASSERT(startNode);
+        ASSERT(startNode->isTextNode());
+        setEndingSelection(Selection(Position(startNode, start.offset()), Position(cmd.node()->previousSibling(), cmd.node()->previousSibling()->caretMaxOffset())));
+        return true;
+    }
+    return false;
+}
+
+void ApplyStyleCommandImpl::applyStyleIfNeeded(const Position &insertionPoint)
+{
+    ASSERT(insertionPoint.notEmpty());
+    if (mustExlicitlyApplyStyle(insertionPoint)) {
+        NodeImpl *styleNode = createExplicitApplyStyleNode();
+        ASSERT(styleNode);
+        int exceptionCode = 0;
+        NodeImpl *contentNode = insertionPoint.node();
+        insertNodeBefore(styleNode, contentNode);
+        removeNode(contentNode);
+        appendNode(styleNode, contentNode);
+        ASSERT(exceptionCode == 0);
+    }
+}
+
+void ApplyStyleCommandImpl::removeStyle(const Position &s, const Position &e)
+{
+    Position start(s.equivalentDownstreamPosition().equivalentShallowPosition().equivalentRangeCompliantPosition());
+    Position end(e.equivalentUpstreamPosition());
+    NodeImpl *node = start.node();
+    while (node != end.node()) {
+        NodeImpl *next = node->traverseNextNode();
+        if (node->isHTMLElement()) {
+            HTMLElementImpl *elem = static_cast<HTMLElementImpl *>(node);
+            if (isHTMLStyleNode(elem))
+                removeHTMLStyleNode(elem, UNDOABLE);
+            else
+                removeCSSStyle(elem, UNDOABLE);
+        }
+        node = next;
+    }
+}
+
+//------------------------------------------------------------------------------------------
+// ApplyStyleCommandImpl: apply using fragment helpers
+
+DocumentFragmentImpl *ApplyStyleCommandImpl::cloneSelection() const
+{
+    RangeImpl *range = document()->createRange();
+    range->ref();
+    
+    int exceptionCode = 0;
+    Position pos = endingSelection().start();
+    
+    pos = endingSelection().start().equivalentShallowPosition().equivalentRangeCompliantPosition();
+    range->setStart(pos.node(), pos.offset(), exceptionCode);
+    ASSERT(exceptionCode == 0);
+    
+    pos = endingSelection().end().equivalentUpstreamPosition().equivalentRangeCompliantPosition();
+    range->setEnd(pos.node(), pos.offset(), exceptionCode);
+    ASSERT(exceptionCode == 0);
+
+    DocumentFragmentImpl *fragment = range->cloneContents(exceptionCode);
+    ASSERT(exceptionCode == 0);
+
+    range->detach(exceptionCode);
+    ASSERT(exceptionCode == 0);
+
+    range->deref();
+
+    return fragment;
+}
+
+void ApplyStyleCommandImpl::removeStyle(DocumentFragmentImpl *fragment)
+{
+    ASSERT(fragment);
+    
+    NodeImpl *node = fragment->firstChild();
+    while (node) {
+        NodeImpl *next = node->traverseNextNode();
+        if (node->isHTMLElement()) {
+            HTMLElementImpl *elem = static_cast<HTMLElementImpl *>(node);
+            if (isHTMLStyleNode(elem))
+                removeHTMLStyleNode(elem, NOTUNDOABLE);
+            else
+                removeCSSStyle(elem, NOTUNDOABLE);
+        }
+        node = next;
+    }
+}
+
+void ApplyStyleCommandImpl::applyStyleIfNeeded(DocumentFragmentImpl *fragment, const Position &insertionPoint)
+{
+    ASSERT(fragment);
+    ASSERT(insertionPoint.notEmpty());
+
+    if (mustExlicitlyApplyStyle(insertionPoint)) {
+        NodeImpl *styleNode = createExplicitApplyStyleNode();
+        ASSERT(styleNode);
+        int exceptionCode = 0;
+        NodeImpl *node = fragment->firstChild();
+        while (node) {
+            NodeImpl *next = node->nextSibling();
+            node->ref();
+            fragment->removeChild(node, exceptionCode);
+            ASSERT(exceptionCode == 0);
+            styleNode->appendChild(node, exceptionCode);
+            ASSERT(exceptionCode == 0);
+            node->deref();
+            node = next;
+        }
+        fragment->appendChild(styleNode, exceptionCode);
+        ASSERT(exceptionCode == 0);
+    }
+}
+
+void ApplyStyleCommandImpl::insertFragment(DocumentFragmentImpl *fragment, const Position &pos)
+{
+    ASSERT(fragment);
+    ASSERT(pos.notEmpty());
+
+    NodeImpl *node = fragment->lastChild();
+    while (node) {
+        int exceptionCode = 0;
+        NodeImpl *prev = node->previousSibling();
+        node->ref();
+        fragment->removeChild(node, exceptionCode);
+        ASSERT(exceptionCode == 0);
+        insertNodeAfter(node, pos.node());
+        node->deref();
+        node = prev;
+    }
+}
+
+//------------------------------------------------------------------------------------------
+// ApplyStyleCommandImpl: different cases we recognize and treat differently
+
+void ApplyStyleCommandImpl::applyInPlace(const Position &s, const Position &e)
+{
+    // Style-change request is being done on a sufficiently simple portion of the tree
+    // such that the style change can be done in place.
+
+    // If the start position of the selection is in the middle of a text node, split it.
+    Position start(s);
+    Position end(e);
+    bool splitStart = splitTextAtStartIfNeeded(start, end);
+
+    // If the end position of the selection is in the middle of a text node, split it.
+    if (splitStart) {
+        start = endingSelection().start();
+        end = endingSelection().end();
+    }
+    bool splitEnd = splitTextAtEndIfNeeded(start, end);
+    
+    // If neither start nor end is in the middle of a text node, have a look
+    // to see if any style can be removed from the current selection.
+    if (!splitStart && !splitEnd)
+        removeStyle(start, end);
+    
+    // Apply style if needed (it might not be needed in cases 
+    // where removing style, as done above, makes this content take on the needed style).
+    applyStyleIfNeeded(positionInsertionPoint(endingSelection().start()));
+}
+
+void ApplyStyleCommandImpl::applyUsingFragment()
+{
+    // Style-change request is being done on a sufficiently complex portion of the tree
+    // such that we use a cloned copy of the content in the selection to perform
+    // the style change. 
+    // FIXME: This is more heavy-weight than we might like for some cases,
+    // but it is a start.
+
+    // Start off by creating a cloned document fragment for the selected content
+    // and then delete the selection using the undoable delete. This is an
+    // important part of what makes this operation undoable.
+    DocumentFragmentImpl *fragment = cloneSelection();
+    ASSERT(fragment);
+    fragment->ref();
+    deleteSelection();
+
+    // Move the selection to the edges of the current insertion point left
+    // by the delete selection step. This makes it easy to shift the selection
+    // to the edges of the fragment content once it is reinserted.
+    Position start(endingSelection().start().equivalentUpstreamPosition());
+    Position end(endingSelection().end().equivalentDownstreamPosition());
+
+    // Now process the fragment:
+    // 1. Remove all traces of style we are applying or removing
+    // 2. Apply style if needed (it might not be needed in cases 
+    //    where removing style, as done above, makes this content take on 
+    //    the needed style).
+    // 3. Reinsert fragment into document.
+    // 4. Deref the fragment
+    removeStyle(fragment);
+    applyStyleIfNeeded(fragment, start);
+    insertFragment(fragment, start);
+    fragment->deref();
+
+    // Shift the selection to the edges of the re-inserted fragment content.
+    start = start.equivalentDownstreamPosition();
+    end = end.equivalentUpstreamPosition();
+    setEndingSelection(Selection(start, end));
+}
+
+//------------------------------------------------------------------------------------------
 // DeleteCollapsibleWhitespaceCommandImpl
 
 DeleteCollapsibleWhitespaceCommandImpl::DeleteCollapsibleWhitespaceCommandImpl(DocumentImpl *document)
@@ -747,13 +1221,13 @@ void DeleteCollapsibleWhitespaceCommandImpl::doApply()
 //------------------------------------------------------------------------------------------
 // DeleteSelectionCommandImpl
 
-DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DOM::DocumentImpl *document)
+DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DocumentImpl *document)
     : CompositeEditCommandImpl(document)
 {
     m_selectionToDelete = endingSelection();
 }
 
-DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DOM::DocumentImpl *document, const Selection &selection)
+DeleteSelectionCommandImpl::DeleteSelectionCommandImpl(DocumentImpl *document, const Selection &selection)
     : CompositeEditCommandImpl(document)
 {
     m_selectionToDelete = selection;
@@ -1338,10 +1812,10 @@ void InsertNodeBeforeCommandImpl::doApply()
 {
     ASSERT(m_insertChild);
     ASSERT(m_refChild);
-    ASSERT(m_refChild->parent());
+    ASSERT(m_refChild->parentNode());
 
     int exceptionCode = 0;
-    m_refChild->parent()->insertBefore(m_insertChild, m_refChild, exceptionCode);
+    m_refChild->parentNode()->insertBefore(m_insertChild, m_refChild, exceptionCode);
     ASSERT(exceptionCode == 0);
 }
 
@@ -1349,10 +1823,10 @@ void InsertNodeBeforeCommandImpl::doUnapply()
 {
     ASSERT(m_insertChild);
     ASSERT(m_refChild);
-    ASSERT(m_refChild->parent());
+    ASSERT(m_refChild->parentNode());
 
     int exceptionCode = 0;
-    m_refChild->parent()->removeChild(m_insertChild, exceptionCode);
+    m_refChild->parentNode()->removeChild(m_insertChild, exceptionCode);
     ASSERT(exceptionCode == 0);
 }
 
@@ -1440,7 +1914,7 @@ void JoinTextNodesCommandImpl::doApply()
     m_text2->insertData(0, m_text1->data(), exceptionCode);
     ASSERT(exceptionCode == 0);
 
-    m_text2->parent()->removeChild(m_text1, exceptionCode);
+    m_text2->parentNode()->removeChild(m_text1, exceptionCode);
     ASSERT(exceptionCode == 0);
 
     m_offset = m_text1->length();
@@ -1466,7 +1940,7 @@ void JoinTextNodesCommandImpl::doUnapply()
 //------------------------------------------------------------------------------------------
 // PasteMarkupCommandImpl
 
-PasteMarkupCommandImpl::PasteMarkupCommandImpl(DocumentImpl *document, const DOMString &markupString, const DOM::DOMString &baseURL) 
+PasteMarkupCommandImpl::PasteMarkupCommandImpl(DocumentImpl *document, const DOMString &markupString, const DOMString &baseURL) 
     : CompositeEditCommandImpl(document), m_markupString(markupString), m_baseURL(baseURL)
 {
     ASSERT(!m_markupString.isEmpty());
@@ -1540,6 +2014,85 @@ void PasteMarkupCommandImpl::doApply()
 }
 
 //------------------------------------------------------------------------------------------
+// RemoveCSSPropertyCommandImpl
+
+RemoveCSSPropertyCommandImpl::RemoveCSSPropertyCommandImpl(DocumentImpl *document, CSSStyleDeclarationImpl *decl, int property)
+    : EditCommandImpl(document), m_decl(decl), m_property(property), m_important(false)
+{
+    ASSERT(m_decl);
+    m_decl->ref();
+}
+
+RemoveCSSPropertyCommandImpl::~RemoveCSSPropertyCommandImpl()
+{
+    if (m_decl)
+        m_decl->deref();
+}
+
+int RemoveCSSPropertyCommandImpl::commandID() const
+{
+    return RemoveCSSPropertyCommandID;
+}
+
+void RemoveCSSPropertyCommandImpl::doApply()
+{
+    ASSERT(m_decl);
+
+    m_oldValue = m_decl->getPropertyValue(m_property);
+    m_important = m_decl->getPropertyPriority(m_property);
+    m_decl->removeProperty(m_property);
+}
+
+void RemoveCSSPropertyCommandImpl::doUnapply()
+{
+    ASSERT(m_decl);
+    ASSERT(!m_oldValue.isNull());
+
+    m_decl->setProperty(m_property, m_oldValue, m_important);
+}
+
+//------------------------------------------------------------------------------------------
+// RemoveNodeAttributeCommandImpl
+
+RemoveNodeAttributeCommandImpl::RemoveNodeAttributeCommandImpl(DocumentImpl *document, ElementImpl *element, NodeImpl::Id attribute)
+    : EditCommandImpl(document), m_element(element), m_attribute(attribute)
+{
+    ASSERT(m_element);
+    m_element->ref();
+}
+
+RemoveNodeAttributeCommandImpl::~RemoveNodeAttributeCommandImpl()
+{
+    if (m_element)
+        m_element->deref();
+}
+
+int RemoveNodeAttributeCommandImpl::commandID() const
+{
+    return RemoveNodeAttributeCommandID;
+}
+
+void RemoveNodeAttributeCommandImpl::doApply()
+{
+    ASSERT(m_element);
+
+    int exceptionCode = 0;
+    m_oldValue = m_element->getAttribute(m_attribute);
+    m_element->removeAttribute(m_attribute, exceptionCode);
+    ASSERT(exceptionCode == 0);
+}
+
+void RemoveNodeAttributeCommandImpl::doUnapply()
+{
+    ASSERT(m_element);
+    ASSERT(!m_oldValue.isNull());
+
+    int exceptionCode = 0;
+    m_element->setAttribute(m_attribute, m_oldValue.implementation(), exceptionCode);
+    ASSERT(exceptionCode == 0);
+}
+
+//------------------------------------------------------------------------------------------
 // RemoveNodeCommandImpl
 
 RemoveNodeCommandImpl::RemoveNodeCommandImpl(DocumentImpl *document, NodeImpl *removeChild)
@@ -1639,6 +2192,82 @@ void RemoveNodeAndPruneCommandImpl::doApply()
 }
 
 //------------------------------------------------------------------------------------------
+// RemoveNodePreservingChildrenCommandImpl
+
+RemoveNodePreservingChildrenCommandImpl::RemoveNodePreservingChildrenCommandImpl(DocumentImpl *document, NodeImpl *node)
+    : CompositeEditCommandImpl(document), m_node(node)
+{
+    ASSERT(m_node);
+    m_node->ref();
+}
+
+RemoveNodePreservingChildrenCommandImpl::~RemoveNodePreservingChildrenCommandImpl()
+{
+    if (m_node)
+        m_node->deref();
+}
+
+int RemoveNodePreservingChildrenCommandImpl::commandID() const
+{
+    return RemoveNodePreservingChildrenCommandID;
+}
+
+void RemoveNodePreservingChildrenCommandImpl::doApply()
+{
+    NodeListImpl *children = node()->childNodes();
+    int length = children->length();
+    for (int i = 0; i < length; i++) {
+        NodeImpl *child = children->item(0);
+        removeNode(child);
+        insertNodeBefore(child, node());
+    }
+    removeNode(node());
+}
+
+//------------------------------------------------------------------------------------------
+// SetNodeAttributeCommandImpl
+
+SetNodeAttributeCommandImpl::SetNodeAttributeCommandImpl(DocumentImpl *document, ElementImpl *element, NodeImpl::Id attribute, const DOMString &value)
+    : EditCommandImpl(document), m_element(element), m_attribute(attribute), m_value(value)
+{
+    ASSERT(m_element);
+    m_element->ref();
+    ASSERT(!m_value.isNull());
+}
+
+SetNodeAttributeCommandImpl::~SetNodeAttributeCommandImpl()
+{
+    if (m_element)
+        m_element->deref();
+}
+
+int SetNodeAttributeCommandImpl::commandID() const
+{
+    return SetNodeAttributeCommandID;
+}
+
+void SetNodeAttributeCommandImpl::doApply()
+{
+    ASSERT(m_element);
+    ASSERT(!m_value.isNull());
+
+    int exceptionCode = 0;
+    m_oldValue = m_element->getAttribute(m_attribute);
+    m_element->setAttribute(m_attribute, m_value.implementation(), exceptionCode);
+    ASSERT(exceptionCode == 0);
+}
+
+void SetNodeAttributeCommandImpl::doUnapply()
+{
+    ASSERT(m_element);
+    ASSERT(!m_oldValue.isNull());
+
+    int exceptionCode = 0;
+    m_element->setAttribute(m_attribute, m_oldValue.implementation(), exceptionCode);
+    ASSERT(exceptionCode == 0);
+}
+
+//------------------------------------------------------------------------------------------
 // SplitTextNodeCommandImpl
 
 SplitTextNodeCommandImpl::SplitTextNodeCommandImpl(DocumentImpl *document, TextImpl *text, long offset)
@@ -1704,7 +2333,7 @@ void SplitTextNodeCommandImpl::doUnapply()
     m_text2->insertData(0, m_text1->data(), exceptionCode);
     ASSERT(exceptionCode == 0);
 
-    m_text2->parent()->removeChild(m_text1, exceptionCode);
+    m_text2->parentNode()->removeChild(m_text1, exceptionCode);
     ASSERT(exceptionCode == 0);
 
     m_offset = m_text1->length();
@@ -1731,7 +2360,7 @@ void TypingCommandImpl::doApply()
 {
 }
 
-void TypingCommandImpl::insertText(const DOM::DOMString &text)
+void TypingCommandImpl::insertText(const DOMString &text)
 {
     if (m_cmds.count() == 0) {
         InputTextCommand cmd(document());
@@ -1824,3 +2453,4 @@ void TypingCommandImpl::removeCommand(const EditCommand &cmd)
 
 //------------------------------------------------------------------------------------------
 
+} // namespace khtml
diff --git a/WebCore/khtml/editing/htmlediting_impl.h b/WebCore/khtml/editing/htmlediting_impl.h
index ca22c31..3a12d71 100644
--- a/WebCore/khtml/editing/htmlediting_impl.h
+++ b/WebCore/khtml/editing/htmlediting_impl.h
@@ -31,17 +31,24 @@
 #include "dom_position.h"
 #include "dom_selection.h"
 #include "dom_string.h"
+#include "dom2_range.h"
 #include "qvaluelist.h"
 #include "shared.h"
 
 namespace DOM {
+    class AtomicString;
+    class CSSStyleDeclarationImpl;
     class DocumentImpl;
     class DOMString;
     class ElementImpl;
+    class HTMLElementImpl;
     class NodeImpl;
+    class NodeListImpl;
     class Position;
+    class Range;
     class Selection;
     class TextImpl;
+    class TreeWalkerImpl;
 };
 
 namespace khtml {
@@ -111,24 +118,28 @@ protected:
     //
     // sugary-sweet convenience functions to help create and apply edit commands in composite commands
     //
+    void appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
     void applyCommandToComposite(EditCommand &);
-    void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
+    void deleteCollapsibleWhitespace();
+    void deleteCollapsibleWhitespace(const DOM::Selection &selection);
+    void deleteKeyPressed();
+    void deleteSelection();
+    void deleteSelection(const DOM::Selection &selection);
+    void deleteText(DOM::TextImpl *node, long offset, long count);
+    void inputText(const DOM::DOMString &text);
     void insertNodeAfter(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
     void insertNodeAt(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild, long offset);
-    void appendNode(DOM::NodeImpl *parent, DOM::NodeImpl *appendChild);
+    void insertNodeBefore(DOM::NodeImpl *insertChild, DOM::NodeImpl *refChild);
+    void insertText(DOM::TextImpl *node, long offset, const DOM::DOMString &text);
+    void joinTextNodes(DOM::TextImpl *text1, DOM::TextImpl *text2);
+    void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property);
+    void removeNodeAttribute(DOM::ElementImpl *, int attribute);
     void removeNode(DOM::NodeImpl *removeChild);
     void removeNodeAndPrune(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 inputText(const DOM::DOMString &text);
-    void deleteText(DOM::TextImpl *node, long offset, long count);
+    void removeNodePreservingChildren(DOM::NodeImpl *node);
     void replaceText(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText);
-    void deleteSelection();
-    void deleteSelection(const DOM::Selection &selection);
-    void deleteKeyPressed();
-    void deleteCollapsibleWhitespace();
-    void deleteCollapsibleWhitespace(const DOM::Selection &selection);
+    void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &);
+    void splitTextNode(DOM::TextImpl *text, long offset);
 
     QValueList<EditCommand> m_cmds;
 };
@@ -158,6 +169,60 @@ private:
 };
 
 //------------------------------------------------------------------------------------------
+// ApplyStyleCommandImpl
+
+class ApplyStyleCommandImpl : public CompositeEditCommandImpl
+{
+public:
+	ApplyStyleCommandImpl(DOM::DocumentImpl *, ApplyStyleCommand::EStyle);
+	virtual ~ApplyStyleCommandImpl();
+	
+    virtual int commandID() const;
+
+	virtual void doApply();
+
+private:
+    // style-removal helpers
+    enum EUndoable { UNDOABLE, NOTUNDOABLE };
+    bool isHTMLStyleNode(DOM::HTMLElementImpl *);
+    void removeHTMLStyleNode(DOM::HTMLElementImpl *, EUndoable undoable);
+    void removeCSSStyle(DOM::HTMLElementImpl *, EUndoable undoable);
+    void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property, EUndoable undoable);
+    void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &, EUndoable undoable);
+    void removeNodeAttribute(DOM::ElementImpl *, int attribute, EUndoable undoable);
+    void removeNodePreservingChildren(DOM::NodeImpl *, EUndoable undoable);
+
+    // shared helpers
+    bool mustExlicitlyApplyStyle(const DOM::Position &) const;
+    DOM::NodeImpl *createExplicitApplyStyleNode() const;
+    bool removingStyle() const { return m_removingStyle; }
+    bool currentlyHasStyle() const;
+    bool currentlyHasStyle(const DOM::Position &) const;
+    int cssProperty() const;
+     
+    // apply-in-place helpers
+    bool matchesTargetStyle(bool hasStyle) const;
+    DOM::Position positionInsertionPoint(DOM::Position);
+    bool splitTextAtStartIfNeeded(const DOM::Position &start, const DOM::Position &end);
+    bool splitTextAtEndIfNeeded(const DOM::Position &start, const DOM::Position &end);
+    void removeStyle(const DOM::Position &start, const DOM::Position &end);
+    void applyStyleIfNeeded(const DOM::Position &);
+
+    // apply using fragment helpers
+    DOM::DocumentFragmentImpl *cloneSelection() const;
+    void removeStyle(DOM::DocumentFragmentImpl *);
+    void applyStyleIfNeeded(DOM::DocumentFragmentImpl *, const DOM::Position &);
+    void insertFragment(DOM::DocumentFragmentImpl *, const DOM::Position &);
+
+    // different cases we recognize and treat differently
+    void applyInPlace(const DOM::Position &s, const DOM::Position &e);
+    void applyUsingFragment();
+    
+    ApplyStyleCommand::EStyle m_styleConstant;
+    bool m_removingStyle;
+};
+
+//------------------------------------------------------------------------------------------
 // DeleteCollapsibleWhitespaceCommandImpl
 
 class DeleteCollapsibleWhitespaceCommandImpl : public CompositeEditCommandImpl
@@ -358,6 +423,53 @@ private:
 };
 
 //------------------------------------------------------------------------------------------
+// RemoveCSSPropertyCommand
+
+class RemoveCSSPropertyCommandImpl : public EditCommandImpl
+{
+public:
+	RemoveCSSPropertyCommandImpl(DOM::DocumentImpl *, DOM::CSSStyleDeclarationImpl *, int property);
+	virtual ~RemoveCSSPropertyCommandImpl();
+
+    virtual int commandID() const;
+
+	virtual void doApply();
+	virtual void doUnapply();
+
+    DOM::CSSStyleDeclarationImpl *styleDeclaration() const { return m_decl; }
+    int property() const { return m_property; }
+    
+private:
+    DOM::CSSStyleDeclarationImpl *m_decl;
+    int m_property;
+    DOM::DOMString m_oldValue;
+    bool m_important;
+};
+
+//------------------------------------------------------------------------------------------
+// RemoveNodeAttributeCommandImpl
+
+class RemoveNodeAttributeCommandImpl : public EditCommandImpl
+{
+public:
+	RemoveNodeAttributeCommandImpl(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute);
+	virtual ~RemoveNodeAttributeCommandImpl();
+
+    virtual int commandID() const;
+
+	virtual void doApply();
+	virtual void doUnapply();
+
+    DOM::ElementImpl *element() const { return m_element; }
+    DOM::NodeImpl::Id attribute() const { return m_attribute; }
+    
+private:
+    DOM::ElementImpl *m_element;
+    DOM::NodeImpl::Id m_attribute;
+    DOM::DOMString m_oldValue;
+};
+
+//------------------------------------------------------------------------------------------
 // RemoveNodeCommandImpl
 
 class RemoveNodeCommandImpl : public EditCommandImpl
@@ -399,6 +511,50 @@ private:
 };
 
 //------------------------------------------------------------------------------------------
+// RemoveNodePreservingChildrenCommandImpl
+
+class RemoveNodePreservingChildrenCommandImpl : public CompositeEditCommandImpl
+{
+public:
+	RemoveNodePreservingChildrenCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *);
+	virtual ~RemoveNodePreservingChildrenCommandImpl();
+	
+    virtual int commandID() const;
+
+	virtual void doApply();
+
+    DOM::NodeImpl *node() const { return m_node; }
+
+private:
+    DOM::NodeImpl *m_node;
+};
+
+//------------------------------------------------------------------------------------------
+// SetNodeAttributeCommandImpl
+
+class SetNodeAttributeCommandImpl : public EditCommandImpl
+{
+public:
+	SetNodeAttributeCommandImpl(DOM::DocumentImpl *, DOM::ElementImpl *, DOM::NodeImpl::Id attribute, const DOM::DOMString &value);
+	virtual ~SetNodeAttributeCommandImpl();
+
+    virtual int commandID() const;
+
+	virtual void doApply();
+	virtual void doUnapply();
+
+    DOM::ElementImpl *element() const { return m_element; }
+    DOM::NodeImpl::Id attribute() const { return m_attribute; }
+    DOM::DOMString value() const { return m_value; }
+    
+private:
+    DOM::ElementImpl *m_element;
+    DOM::NodeImpl::Id m_attribute;
+    DOM::DOMString m_value;
+    DOM::DOMString m_oldValue;
+};
+
+//------------------------------------------------------------------------------------------
 // SplitTextNodeCommandImpl
 
 class SplitTextNodeCommandImpl : public EditCommandImpl
diff --git a/WebCore/khtml/editing/selection.cpp b/WebCore/khtml/editing/selection.cpp
index 086487a..04217f4 100644
--- a/WebCore/khtml/editing/selection.cpp
+++ b/WebCore/khtml/editing/selection.cpp
@@ -397,7 +397,9 @@ Range Selection::toRange() const
     if (isEmpty())
         return Range();
 
-    return Range(Node(start().node()), start().offset(), Node(end().node()), end().offset());
+    Position s(start().equivalentRangeCompliantPosition());
+    Position e(end().equivalentRangeCompliantPosition());
+    return Range(Node(s.node()), s.offset(), Node(e.node()), e.offset());
 }
 
 void Selection::layoutCaret()
diff --git a/WebCore/khtml/xml/dom2_traversalimpl.cpp b/WebCore/khtml/xml/dom2_traversalimpl.cpp
index fd2dc27..601e15b 100644
--- a/WebCore/khtml/xml/dom2_traversalimpl.cpp
+++ b/WebCore/khtml/xml/dom2_traversalimpl.cpp
@@ -450,7 +450,7 @@ NodeImpl *TreeWalkerImpl::parentNode()
     NodeImpl *node = findParentNode(currentNode());
     if (node)
         setCurrentNode(node);
-    return currentNode();
+    return node;
 }
 
 NodeImpl *TreeWalkerImpl::firstChild()
@@ -458,7 +458,7 @@ NodeImpl *TreeWalkerImpl::firstChild()
     NodeImpl *node = findFirstChild(currentNode());
     if (node)
         setCurrentNode(node);
-    return currentNode();
+    return node;
 }
 
 NodeImpl *TreeWalkerImpl::lastChild()
@@ -466,7 +466,7 @@ NodeImpl *TreeWalkerImpl::lastChild()
     NodeImpl *node = findLastChild(currentNode());
     if (node)
         setCurrentNode(node);
-    return currentNode();
+    return node;
 }
 
 NodeImpl *TreeWalkerImpl::previousSibling()
@@ -474,7 +474,7 @@ NodeImpl *TreeWalkerImpl::previousSibling()
     NodeImpl *node = findPreviousSibling(currentNode());
     if (node)
         setCurrentNode(node);
-    return currentNode();
+    return node;
 }
 
 NodeImpl *TreeWalkerImpl::nextSibling()
@@ -482,7 +482,7 @@ NodeImpl *TreeWalkerImpl::nextSibling()
     NodeImpl *node = findNextSibling(currentNode());
     if (node)
         setCurrentNode(node);
-    return currentNode();
+    return node;
 }
 
 NodeImpl *TreeWalkerImpl::previousNode()
@@ -490,7 +490,7 @@ NodeImpl *TreeWalkerImpl::previousNode()
     NodeImpl *node = findPreviousNode(currentNode());
     if (node)
         setCurrentNode(node);
-    return currentNode();
+    return node;
 }
 
 NodeImpl *TreeWalkerImpl::nextNode()
@@ -498,7 +498,7 @@ NodeImpl *TreeWalkerImpl::nextNode()
     NodeImpl *node = findNextNode(currentNode());
     if (node)
         setCurrentNode(node);
-    return currentNode();
+    return node;
 }
 
 } // namespace DOM
diff --git a/WebCore/khtml/xml/dom_elementimpl.cpp b/WebCore/khtml/xml/dom_elementimpl.cpp
index 7d30e2a..464b7d5 100644
--- a/WebCore/khtml/xml/dom_elementimpl.cpp
+++ b/WebCore/khtml/xml/dom_elementimpl.cpp
@@ -312,6 +312,11 @@ void ElementImpl::setAttributeMap( NamedAttrMapImpl* list )
     }
 }
 
+bool ElementImpl::hasAttributes() const
+{
+    return namedAttrMap && namedAttrMap->length() > 0;
+}
+
 NodeImpl *ElementImpl::cloneNode(bool deep)
 {
     // ### we loose the namespace here ... FIXME
diff --git a/WebCore/khtml/xml/dom_elementimpl.h b/WebCore/khtml/xml/dom_elementimpl.h
index 66090af..fe954d3 100644
--- a/WebCore/khtml/xml/dom_elementimpl.h
+++ b/WebCore/khtml/xml/dom_elementimpl.h
@@ -166,6 +166,7 @@ public:
                                        const DOMString &localName) const;
     void setAttribute( NodeImpl::Id id, DOMStringImpl* value, int &exceptioncode );
     void removeAttribute( NodeImpl::Id id, int &exceptioncode );
+    bool hasAttributes() const;
     
     DOMString prefix() const { return m_prefix; }
     void setPrefix(const DOMString &_prefix, int &exceptioncode );
diff --git a/WebCore/khtml/xml/dom_position.cpp b/WebCore/khtml/xml/dom_position.cpp
index ce7fa68..5228d63 100644
--- a/WebCore/khtml/xml/dom_position.cpp
+++ b/WebCore/khtml/xml/dom_position.cpp
@@ -521,6 +521,40 @@ Position Position::equivalentDownstreamPosition() const
     return it.current();
 }
 
+Position Position::equivalentRangeCompliantPosition() const
+{
+    if (isEmpty())
+        return *this;
+
+    if (!node()->parentNode())
+        return *this;
+
+    RenderObject *renderer = node()->renderer();
+    if (!renderer)
+        return *this;
+        
+    if (!renderer->isReplaced() && !renderer->isBR())
+        return *this;
+    
+    int o = 0;
+    const NodeImpl *n = node();
+    while ((n = n->previousSibling()))
+        o++;
+    
+    return Position(node()->parentNode(), o + offset());
+}
+
+Position Position::equivalentShallowPosition() const
+{
+    if (isEmpty())
+        return *this;
+
+    Position pos(*this);
+    while (pos.offset() == pos.node()->caretMinOffset() && pos.node()->parentNode() && pos.node() == pos.node()->parentNode()->firstChild())
+        pos = Position(pos.node()->parentNode(), 0);
+    return pos;
+}
+
 bool Position::atStartOfContainingEditableBlock() const
 {
     return renderedOffset() == 0 && inFirstEditableInContainingEditableBlock();
@@ -844,4 +878,12 @@ bool Position::inLastEditableInContainingEditableBlock() const
     return true;
 }
 
+void Position::debugPosition(const char *msg) const
+{
+    if (isEmpty())
+        fprintf(stderr, "Position [%s]: empty\n");
+    else
+        fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, getTagName(node()->id()).string().latin1(), node(), offset());
+}
+
 } // namespace DOM
\ No newline at end of file
diff --git a/WebCore/khtml/xml/dom_position.h b/WebCore/khtml/xml/dom_position.h
index 09941e6..91755cd 100644
--- a/WebCore/khtml/xml/dom_position.h
+++ b/WebCore/khtml/xml/dom_position.h
@@ -57,6 +57,8 @@ public:
     Position nextLinePosition(int x) const;
     Position equivalentUpstreamPosition() const;
     Position equivalentDownstreamPosition() const;
+    Position equivalentRangeCompliantPosition() const;
+    Position equivalentShallowPosition() const;
     bool atStartOfContainingEditableBlock() const;
     bool atStartOfRootEditableBlock() const;
     bool inRenderedContent() const;
@@ -76,6 +78,8 @@ public:
     friend bool operator==(const Position &a, const Position &b);
     friend bool operator!=(const Position &a, const Position &b);
     
+    void debugPosition(const char *msg="") const;
+    
 private:
     NodeImpl *m_node;
     long m_offset;
diff --git a/WebCore/khtml/xml/dom_selection.cpp b/WebCore/khtml/xml/dom_selection.cpp
index 086487a..04217f4 100644
--- a/WebCore/khtml/xml/dom_selection.cpp
+++ b/WebCore/khtml/xml/dom_selection.cpp
@@ -397,7 +397,9 @@ Range Selection::toRange() const
     if (isEmpty())
         return Range();
 
-    return Range(Node(start().node()), start().offset(), Node(end().node()), end().offset());
+    Position s(start().equivalentRangeCompliantPosition());
+    Position e(end().equivalentRangeCompliantPosition());
+    return Range(Node(s.node()), s.offset(), Node(e.node()), e.offset());
 }
 
 void Selection::layoutCaret()
diff --git a/WebCore/kwq/WebCoreBridge.mm b/WebCore/kwq/WebCoreBridge.mm
index 4585cde..e825756 100644
--- a/WebCore/kwq/WebCoreBridge.mm
+++ b/WebCore/kwq/WebCoreBridge.mm
@@ -100,6 +100,7 @@ using khtml::EditCommand;
 using khtml::EditCommandImpl;
 using khtml::PasteMarkupCommand;
 using khtml::parseURL;
+using khtml::ApplyStyleCommand;
 using khtml::RenderCanvas;
 using khtml::RenderImage;
 using khtml::RenderObject;
@@ -1450,7 +1451,14 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 
 - (void)applyStyle:(DOMCSSStyleDeclaration *)style
 {
-    ERROR("unimplemented");
+    if (!_part || !_part->xmlDocImpl() || !style)
+        return;
+    
+    // FIXME: Temporarily hard-coded to BOLD until more styles are implemented.
+    //                 ...or...
+    // Any style you want, as long as it's BOLD. :)
+    ApplyStyleCommand cmd(_part->xmlDocImpl(), ApplyStyleCommand::BOLD);
+    cmd.apply();
 }
 
 - (void)ensureCaretVisible

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list