[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