Commit 97172280 authored by kocienda's avatar kocienda
Browse files

Reviewed by Hyatt

        Rewrite of the command that deletes a selection. I deleted great
        big swaths of bug-ridden code to accomplish this and replaced it
        with code that is much cleaner and smarter.

        Also, renamed equivalentUpstreamPosition and equivalentDownstreamPosition to
        upstream to downstream, respectively.

        Added a couple of new helper methods.

        * khtml/editing/htmlediting.cpp: DeleteCollapsibleWhitespaceCommand and
        RemoveNodeAndPruneCommand now obsolete. A huge win.
        * khtml/editing/htmlediting.h: Ditto.
        * khtml/editing/htmlediting_impl.cpp:
        (khtml::debugPosition): Fix printf which had a placeholder, but no argument passed in the varargs.
        (khtml::CompositeEditCommandImpl::deleteUnrenderedText): New helper. Much simplified and cleaner
        version of
        (khtml::ApplyStyleCommandImpl::doApply): upstream/downstream name change
        (khtml::ApplyStyleCommandImpl::nodeFullySelected):  upstream/downstream name change
        (khtml::DeleteSelectionCommandImpl::doApply):  upstream/downstream name change
        (khtml::DeleteTextCommandImpl::DeleteTextCommandImpl): Add an assert to check that the
        passed offset is less than the length of the text node.
        (khtml::InputNewlineCommandImpl::insertNodeAfterPosition): upstream/downstream name change
        (khtml::InputNewlineCommandImpl::insertNodeBeforePosition): upstream/downstream name change
        (khtml::InputNewlineCommandImpl::doApply): upstream/downstream name change
        (khtml::InputTextCommandImpl::prepareForTextInsertion): upstream/downstream name change
        (khtml::InputTextCommandImpl::execute): upstream/downstream name change
        (khtml::InputTextCommandImpl::insertSpace): upstream/downstream name change
        (khtml::ReplaceSelectionCommandImpl::doApply): upstream/downstream name change
        (khtml::TypingCommandImpl::issueCommandForDeleteKey): upstream/downstream name change
        (khtml::TypingCommandImpl::deleteKeyPressed):
        * khtml/editing/htmlediting_impl.h:
        * khtml/xml/dom_position.cpp:
        (DOM::Position::previousWordBoundary):
        (DOM::Position::nextWordBoundary):
        (DOM::Position::upstream):
        (DOM::Position::downstream):
        (DOM::Position::inRenderedText): Add null check.
        (DOM::Position::isRenderedCharacter): New helper.
        (DOM::isWS): New helper in this file.
        (DOM::Position::leadingWhitespacePosition): New helper. Factored out from htmlediting_impl.cpp.
        (DOM::Position::trailingWhitespacePosition): Ditto.
        (DOM::Position::debugPosition): Add null check.
        * khtml/xml/dom_position.h:
        * khtml/xml/dom_selection.cpp:
        (DOM::Selection::toRange): upstream/downstream name change
        (DOM::Selection::validate): upstream/downstream name change
        (DOM::Selection::debugPosition): upstream/downstream name change
        * layout-tests/editing/deleting/delete-block-contents-003-expected.txt: Updated tests with new expected results.
        * layout-tests/editing/deleting/delete-contiguous-ws-001-expected.txt: Ditto.
        * layout-tests/editing/deleting/delete-selection-001-expected.txt: Ditto.
        * layout-tests/editing/deleting/delete-trailing-ws-001-expected.txt: Ditto.
        * layout-tests/editing/inserting/insert-br-case1-expected.txt: Ditto.
        * layout-tests/editing/inserting/insert-br-case2-expected.txt: Ditto.
        * layout-tests/editing/style/style-3681552-fix-002-expected.txt: Ditto.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@7277 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 913145a4
......@@ -11,7 +11,8 @@ layer at (0,0) size 800x600
text run at (89,14) width 34: "baz"
RenderText {TEXT} at (0,0) size 0x0
RenderBlock {DIV} at (0,56) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 0x0
selection is CARET:
start: position 0 of child 3 {DIV} of child 2 {BODY} of child 1 {HTML} of root {}
upstream: position 0 of child 3 {DIV} of child 2 {BODY} of child 1 {HTML} of root {}
downstream: position 0 of child 3 {DIV} of child 2 {BODY} of child 1 {HTML} of root {}
start: position 0 of child 1 {SPAN} of child 3 {DIV} of child 2 {BODY} of child 1 {HTML} of root {}
upstream: position 0 of child 1 {SPAN} of child 3 {DIV} of child 2 {BODY} of child 1 {HTML} of root {}
downstream: position 1 of child 1 {SPAN} of child 3 {DIV} of child 2 {BODY} of child 1 {HTML} of root {}
......@@ -6,10 +6,10 @@ layer at (0,0) size 800x600
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 78x28
RenderText {TEXT} at (14,14) size 78x28
text run at (14,14) width 44: "foo "
text run at (58,14) width 34: "baz"
text run at (14,14) width 38: "foo "
text run at (52,14) width 40: " baz"
RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
start: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
start: position 8 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
upstream: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 8 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
......@@ -10,6 +10,6 @@ layer at (0,0) size 800x600
text run at (57,14) width 34: "baz"
RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
start: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
start: position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
upstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
downstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
downstream: position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
......@@ -10,6 +10,6 @@ layer at (0,0) size 800x600
text run at (57,14) width 34: "baz"
RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
start: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
start: position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
upstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
downstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
downstream: position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
......@@ -4,16 +4,14 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x84 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 34x28
RenderInline {SPAN} at (0,0) size 34x56
RenderText {TEXT} at (14,14) size 34x28
text run at (14,14) width 34: "test"
RenderText {TEXT} at (48,14) size 6x28
text run at (48,14) width 6: " "
RenderBR {BR} at (0,0) size 0x0
RenderText {TEXT} at (14,42) size 12x28
text run at (14,42) width 12: "x"
RenderBR {BR} at (14,42) size 0x28
RenderBR {BR} at (0,0) size 0x0
RenderText {TEXT} at (14,42) size 12x28
text run at (14,42) width 12: "x"
RenderBR {BR} at (14,42) size 0x28
selection is CARET:
start: position 1 of child 5 {TEXT} of root {DIV}
upstream: position 1 of child 5 {TEXT} of root {DIV}
downstream: position 0 of child 6 {BR} of root {DIV}
start: position 1 of child 3 {TEXT} of child 2 {SPAN} of root {DIV}
upstream: position 1 of child 3 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 0 of child 4 {BR} of child 2 {SPAN} of root {DIV}
......@@ -4,17 +4,16 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x112 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 34x84
RenderInline {SPAN} at (0,0) size 46x84
RenderText {TEXT} at (14,14) size 34x28
text run at (14,14) width 34: "test"
RenderBR {BR} at (0,0) size 0x0
RenderText {TEXT} at (14,42) size 12x28
text run at (14,42) width 12: "x"
RenderBR {BR} at (14,42) size 0x28
RenderText {TEXT} at (14,70) size 34x28
text run at (14,70) width 34: "test"
RenderText {TEXT} at (0,0) size 0x0
RenderBR {BR} at (0,0) size 0x0
RenderText {TEXT} at (14,70) size 46x28
text run at (14,70) width 46: "xtest"
RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
start: position 1 of child 3 {TEXT} of child 2 {SPAN} of root {DIV}
upstream: position 1 of child 3 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 0 of child 4 {BR} of child 2 {SPAN} of root {DIV}
start: position 1 of child 5 {TEXT} of child 2 {SPAN} of root {DIV}
upstream: position 1 of child 5 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 1 of child 5 {TEXT} of child 2 {SPAN} of root {DIV}
......@@ -4,13 +4,16 @@ layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
RenderInline {SPAN} at (0,0) size 161x28
RenderInline {SPAN} at (0,0) size 167x28
RenderText {TEXT} at (14,14) size 118x28
text run at (14,14) width 118: "here is xxxx"
RenderText {TEXT} at (132,14) size 43x28
text run at (132,14) width 43: " text"
RenderInline {I} at (0,0) size 6x28
RenderText {TEXT} at (132,14) size 6x28
text run at (132,14) width 6: " "
RenderText {TEXT} at (138,14) size 43x28
text run at (138,14) width 43: " text"
RenderText {TEXT} at (0,0) size 0x0
selection is CARET:
start: position 12 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
upstream: position 12 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 0 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
downstream: position 0 of child 1 {TEXT} of child 2 {I} of child 2 {SPAN} of root {DIV}
2004-08-17 Ken Kocienda <kocienda@apple.com>
Reviewed by Hyatt
Rewrite of the command that deletes a selection. I deleted great
big swaths of bug-ridden code to accomplish this and replaced it
with code that is much cleaner and smarter.
Also, renamed equivalentUpstreamPosition and equivalentDownstreamPosition to
upstream to downstream, respectively.
Added a couple of new helper methods.
* khtml/editing/htmlediting.cpp: DeleteCollapsibleWhitespaceCommand and
RemoveNodeAndPruneCommand now obsolete. A huge win.
* khtml/editing/htmlediting.h: Ditto.
* khtml/editing/htmlediting_impl.cpp:
(khtml::debugPosition): Fix printf which had a placeholder, but no argument passed in the varargs.
(khtml::CompositeEditCommandImpl::deleteUnrenderedText): New helper. Much simplified and cleaner
version of
(khtml::ApplyStyleCommandImpl::doApply): upstream/downstream name change
(khtml::ApplyStyleCommandImpl::nodeFullySelected): upstream/downstream name change
(khtml::DeleteSelectionCommandImpl::doApply): upstream/downstream name change
(khtml::DeleteTextCommandImpl::DeleteTextCommandImpl): Add an assert to check that the
passed offset is less than the length of the text node.
(khtml::InputNewlineCommandImpl::insertNodeAfterPosition): upstream/downstream name change
(khtml::InputNewlineCommandImpl::insertNodeBeforePosition): upstream/downstream name change
(khtml::InputNewlineCommandImpl::doApply): upstream/downstream name change
(khtml::InputTextCommandImpl::prepareForTextInsertion): upstream/downstream name change
(khtml::InputTextCommandImpl::execute): upstream/downstream name change
(khtml::InputTextCommandImpl::insertSpace): upstream/downstream name change
(khtml::ReplaceSelectionCommandImpl::doApply): upstream/downstream name change
(khtml::TypingCommandImpl::issueCommandForDeleteKey): upstream/downstream name change
(khtml::TypingCommandImpl::deleteKeyPressed):
* khtml/editing/htmlediting_impl.h:
* khtml/xml/dom_position.cpp:
(DOM::Position::previousWordBoundary):
(DOM::Position::nextWordBoundary):
(DOM::Position::upstream):
(DOM::Position::downstream):
(DOM::Position::inRenderedText): Add null check.
(DOM::Position::isRenderedCharacter): New helper.
(DOM::isWS): New helper in this file.
(DOM::Position::leadingWhitespacePosition): New helper. Factored out from htmlediting_impl.cpp.
(DOM::Position::trailingWhitespacePosition): Ditto.
(DOM::Position::debugPosition): Add null check.
* khtml/xml/dom_position.h:
* khtml/xml/dom_selection.cpp:
(DOM::Selection::toRange): upstream/downstream name change
(DOM::Selection::validate): upstream/downstream name change
(DOM::Selection::debugPosition): upstream/downstream name change
* layout-tests/editing/deleting/delete-block-contents-003-expected.txt: Updated tests with new expected results.
* layout-tests/editing/deleting/delete-contiguous-ws-001-expected.txt: Ditto.
* layout-tests/editing/deleting/delete-selection-001-expected.txt: Ditto.
* layout-tests/editing/deleting/delete-trailing-ws-001-expected.txt: Ditto.
* layout-tests/editing/inserting/insert-br-case1-expected.txt: Ditto.
* layout-tests/editing/inserting/insert-br-case2-expected.txt: Ditto.
* layout-tests/editing/style/style-3681552-fix-002-expected.txt: Ditto.
2004-08-17 Trey Matteson <trey@apple.com>
 
Various spelling fixes.
......
......@@ -474,7 +474,7 @@ Range Selection::toRange() const
// If the selection is a caret, move the range start upstream. This helps us match
// the conventions of text editors tested, which make style determinations based
// on the character before the caret, if any.
s = start().equivalentUpstreamPosition().equivalentRangeCompliantPosition();
s = start().upstream().equivalentRangeCompliantPosition();
e = s;
}
else {
......@@ -490,8 +490,8 @@ Range Selection::toRange() const
// ^ selected
//
ASSERT(state() == RANGE);
s = start().equivalentDownstreamPosition();
e = end().equivalentUpstreamPosition();
s = start().downstream();
e = end().upstream();
if ((s.node() == e.node() && s.offset() > e.offset()) || !nodeIsBeforeNode(s.node(), e.node())) {
// Make sure the start is before the end.
// The end can wind up before the start if collapsed whitespace is the only thing selected.
......@@ -719,7 +719,7 @@ void Selection::validate(ETextGranularity granularity)
if (start().isEmpty() && end().isEmpty()) {
m_state = NONE;
}
else if (start() == end() || start().equivalentUpstreamPosition() == end().equivalentUpstreamPosition()) {
else if (start() == end() || start().upstream() == end().upstream()) {
m_state = CARET;
}
else {
......@@ -730,8 +730,8 @@ void Selection::validate(ETextGranularity granularity)
// purposes of comparing selections). This is an ideal point of the code
// to do this operation, since all selection changes that result in a RANGE
// come through here before anyone uses it.
assignStart(start().equivalentDownstreamPosition());
assignEnd(end().equivalentUpstreamPosition());
assignStart(start().downstream());
assignEnd(end().upstream());
}
m_needsCaretLayout = true;
......@@ -1009,23 +1009,23 @@ void Selection::debugPosition() const
if (start() == end()) {
Position pos = start();
Position upstream = pos.equivalentUpstreamPosition();
Position downstream = pos.equivalentDownstreamPosition();
Position upstream = pos.upstream();
Position downstream = pos.downstream();
fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
fprintf(stderr, "pos: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
}
else {
Position pos = start();
Position upstream = pos.equivalentUpstreamPosition();
Position downstream = pos.equivalentDownstreamPosition();
Position upstream = pos.upstream();
Position downstream = pos.downstream();
fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
fprintf(stderr, "start: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
fprintf(stderr, "-----------------------------------\n");
pos = end();
upstream = pos.equivalentUpstreamPosition();
downstream = pos.equivalentDownstreamPosition();
upstream = pos.upstream();
downstream = pos.downstream();
fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
fprintf(stderr, "end: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
......
......@@ -259,28 +259,6 @@ CSSStyleDeclarationImpl *ApplyStyleCommand::style() const
return impl()->style();
}
//------------------------------------------------------------------------------------------
// DeleteCollapsibleWhitespaceCommand
DeleteCollapsibleWhitespaceCommand::DeleteCollapsibleWhitespaceCommand(DocumentImpl *document)
: CompositeEditCommand(new DeleteCollapsibleWhitespaceCommandImpl(document))
{
}
DeleteCollapsibleWhitespaceCommand::DeleteCollapsibleWhitespaceCommand(DocumentImpl *document, const Selection &selection)
: CompositeEditCommand(new DeleteCollapsibleWhitespaceCommandImpl(document, selection))
{
}
DeleteCollapsibleWhitespaceCommand::~DeleteCollapsibleWhitespaceCommand()
{
}
DeleteCollapsibleWhitespaceCommandImpl *DeleteCollapsibleWhitespaceCommand::impl() const
{
return static_cast<DeleteCollapsibleWhitespaceCommandImpl *>(get());
}
//------------------------------------------------------------------------------------------
// DeleteSelectionCommand
......@@ -612,35 +590,6 @@ NodeImpl *RemoveNodeCommand::node() const
return impl()->node();
}
//------------------------------------------------------------------------------------------
// RemoveNodeAndPruneCommand
RemoveNodeAndPruneCommand::RemoveNodeAndPruneCommand(DocumentImpl *document, NodeImpl *pruneNode, NodeImpl *stopNode)
: CompositeEditCommand(new RemoveNodeAndPruneCommandImpl(document, pruneNode, stopNode))
{
}
RemoveNodeAndPruneCommand::~RemoveNodeAndPruneCommand()
{
}
RemoveNodeAndPruneCommandImpl *RemoveNodeAndPruneCommand::impl() const
{
return static_cast<RemoveNodeAndPruneCommandImpl *>(get());
}
NodeImpl *RemoveNodeAndPruneCommand::pruneNode() const
{
IF_IMPL_NULL_RETURN_ARG(0);
return impl()->pruneNode();
}
NodeImpl *RemoveNodeAndPruneCommand::stopNode() const
{
IF_IMPL_NULL_RETURN_ARG(0);
return impl()->stopNode();
}
//------------------------------------------------------------------------------------------
// RemoveNodePreservingChildrenCommand
......
......@@ -49,7 +49,6 @@ namespace khtml {
class AppendNodeCommandImpl;
class ApplyStyleCommandImpl;
class CompositeEditCommandImpl;
class DeleteCollapsibleWhitespaceCommandImpl;
class DeleteSelectionCommandImpl;
class DeleteTextCommandImpl;
class EditCommand;
......@@ -64,7 +63,6 @@ class ReplaceSelectionCommandImpl;
class RemoveCSSPropertyCommandImpl;
class RemoveNodeAttributeCommandImpl;
class RemoveNodeCommandImpl;
class RemoveNodeAndPruneCommandImpl;
class RemoveNodePreservingChildrenCommandImpl;
class SetNodeAttributeCommandImpl;
class SplitTextNodeCommandImpl;
......@@ -78,7 +76,6 @@ enum ECommandID {
AppendNodeCommandID,
ApplyStyleCommandID,
CompositeEditCommandID,
DeleteCollapsibleWhitespaceCommandID,
DeleteSelectionCommandID,
DeleteTextCommandID,
InputNewlineCommandID,
......@@ -91,7 +88,6 @@ enum ECommandID {
RemoveCSSPropertyCommandID,
RemoveNodeAttributeCommandID,
RemoveNodeCommandID,
RemoveNodeAndPruneCommandID,
RemoveNodePreservingChildrenCommandID,
SetNodeAttributeCommandID,
SplitTextNodeCommandID,
......@@ -210,21 +206,6 @@ private:
inline ApplyStyleCommandImpl *impl() const;
};
//------------------------------------------------------------------------------------------
// DeleteCollapsibleWhitespaceCommand
class DeleteCollapsibleWhitespaceCommand : public CompositeEditCommand
{
public:
DeleteCollapsibleWhitespaceCommand(DOM::DocumentImpl *document);
DeleteCollapsibleWhitespaceCommand(DOM::DocumentImpl *document, const DOM::Selection &selection);
virtual ~DeleteCollapsibleWhitespaceCommand();
private:
inline DeleteCollapsibleWhitespaceCommandImpl *impl() const;
};
//------------------------------------------------------------------------------------------
// DeleteSelectionCommand
......@@ -412,22 +393,6 @@ private:
inline RemoveNodeCommandImpl *impl() const;
};
//------------------------------------------------------------------------------------------
// RemoveNodeAndPruneCommand
class RemoveNodeAndPruneCommand : public CompositeEditCommand
{
public:
RemoveNodeAndPruneCommand(DOM::DocumentImpl *, DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode=0);
virtual ~RemoveNodeAndPruneCommand();
DOM::NodeImpl *pruneNode() const;
DOM::NodeImpl *stopNode() const;
private:
inline RemoveNodeAndPruneCommandImpl *impl() const;
};
//------------------------------------------------------------------------------------------
// RemoveNodePreservingChildrenCommand
......
This diff is collapsed.
......@@ -142,8 +142,6 @@ protected:
//
void appendNode(DOM::NodeImpl *appendChild, DOM::NodeImpl *parentNode);
void applyCommandToComposite(EditCommand &);
void deleteCollapsibleWhitespace();
void deleteCollapsibleWhitespace(const DOM::Selection &selection);
void deleteKeyPressed();
void deleteSelection();
void deleteSelection(const DOM::Selection &selection);
......@@ -157,13 +155,13 @@ protected:
void removeCSSProperty(DOM::CSSStyleDeclarationImpl *, int property);
void removeNodeAttribute(DOM::ElementImpl *, int attribute);
void removeNode(DOM::NodeImpl *removeChild);
void removeNodeAndPrune(DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode=0);
void removeNodePreservingChildren(DOM::NodeImpl *node);
void replaceText(DOM::TextImpl *node, long offset, long count, const DOM::DOMString &replacementText);
void setNodeAttribute(DOM::ElementImpl *, int attribute, const DOM::DOMString &);
void splitTextNode(DOM::TextImpl *text, long offset);
DOM::ElementImpl *applyTypingStyle(DOM::NodeImpl *) const;
void deleteUnrenderedText(const DOM::Position &pos);
QValueList<EditCommand> m_cmds;
};
......@@ -225,29 +223,6 @@ private:
DOM::CSSStyleDeclarationImpl *m_style;
};
//------------------------------------------------------------------------------------------
// DeleteCollapsibleWhitespaceCommandImpl
class DeleteCollapsibleWhitespaceCommandImpl : public CompositeEditCommandImpl
{
public:
DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document);
DeleteCollapsibleWhitespaceCommandImpl(DOM::DocumentImpl *document, const DOM::Selection &selection);
virtual ~DeleteCollapsibleWhitespaceCommandImpl();
virtual int commandID() const;
virtual void doApply();
private:
DOM::Position deleteWhitespace(const DOM::Position &pos);
unsigned long m_charactersDeleted;
DOM::Selection m_selectionToCollapse;
bool m_hasSelectionToCollapse;
};
//------------------------------------------------------------------------------------------
// DeleteSelectionCommandImpl
......@@ -266,7 +241,6 @@ public:
private:
void deleteDownstreamWS(const DOM::Position &start);
bool containsOnlyWhitespace(const DOM::Position &start, const DOM::Position &end);
void joinTextNodesWithSameStyle();
DOM::CSSStyleDeclarationImpl *computeTypingStyle(const DOM::Position &pos) const;
DOM::Selection m_selectionToDelete;
......@@ -516,27 +490,6 @@ private:
DOM::NodeImpl *m_refChild;
};
//------------------------------------------------------------------------------------------
// RemoveNodeAndPruneCommandImpl
class RemoveNodeAndPruneCommandImpl : public CompositeEditCommandImpl
{
public:
RemoveNodeAndPruneCommandImpl(DOM::DocumentImpl *, DOM::NodeImpl *pruneNode, DOM::NodeImpl *stopNode=0);
virtual ~RemoveNodeAndPruneCommandImpl();
virtual int commandID() const;
virtual void doApply();
DOM::NodeImpl *pruneNode() const { return m_pruneNode; }
DOM::NodeImpl *stopNode() const { return m_stopNode; }
private:
DOM::NodeImpl *m_pruneNode;
DOM::NodeImpl *m_stopNode;
};
//------------------------------------------------------------------------------------------
// RemoveNodePreservingChildrenCommandImpl
......
......@@ -474,7 +474,7 @@ Range Selection::toRange() const
// If the selection is a caret, move the range start upstream. This helps us match
// the conventions of text editors tested, which make style determinations based
// on the character before the caret, if any.
s = start().equivalentUpstreamPosition().equivalentRangeCompliantPosition();
s = start().upstream().equivalentRangeCompliantPosition();
e = s;
}
else {
......@@ -490,8 +490,8 @@ Range Selection::toRange() const
// ^ selected
//
ASSERT(state() == RANGE);
s = start().equivalentDownstreamPosition();
e = end().equivalentUpstreamPosition();
s = start().downstream();
e = end().upstream();
if ((s.node() == e.node() && s.offset() > e.offset()) || !nodeIsBeforeNode(s.node(), e.node())) {
// Make sure the start is before the end.
// The end can wind up before the start if collapsed whitespace is the only thing selected.
......@@ -719,7 +719,7 @@ void Selection::validate(ETextGranularity granularity)
if (start().isEmpty() && end().isEmpty()) {
m_state = NONE;
}
else if (start() == end() || start().equivalentUpstreamPosition() == end().equivalentUpstreamPosition()) {
else if (start() == end() || start().upstream() == end().upstream()) {
m_state = CARET;
}
else {
......@@ -730,8 +730,8 @@ void Selection::validate(ETextGranularity granularity)
// purposes of comparing selections). This is an ideal point of the code
// to do this operation, since all selection changes that result in a RANGE
// come through here before anyone uses it.
assignStart(start().equivalentDownstreamPosition());
assignEnd(end().equivalentUpstreamPosition());
assignStart(start().downstream());
assignEnd(end().upstream());
}
m_needsCaretLayout = true;
......@@ -1009,23 +1009,23 @@ void Selection::debugPosition() const
if (start() == end()) {
Position pos = start();
Position upstream = pos.equivalentUpstreamPosition();
Position downstream = pos.equivalentDownstreamPosition();
Position upstream = pos.upstream();
Position downstream = pos.downstream();
fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
fprintf(stderr, "pos: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
}
else {
Position pos = start();
Position upstream = pos.equivalentUpstreamPosition();
Position downstream = pos.equivalentDownstreamPosition();
Position upstream = pos.upstream();
Position downstream = pos.downstream();
fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
fprintf(stderr, "start: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
fprintf(stderr, "-----------------------------------\n");
pos = end();
upstream = pos.equivalentUpstreamPosition();
downstream = pos.equivalentDownstreamPosition();
upstream = pos.upstream();
downstream = pos.downstream();
fprintf(stderr, "upstream: %s %p:%d\n", getTagName(upstream.node()->id()).string().latin1(), upstream.node(), upstream.offset());
fprintf(stderr, "end: %s %p:%d\n", getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
fprintf(stderr, "downstream: %s %p:%d\n", getTagName(downstream.node()->id()).string().latin1(), downstream.node(), downstream.offset());
......
......@@ -312,6 +312,8 @@ Position Position::previousWordBoundary() const
while (tries < 2) {
if (pos.node()->nodeType() == Node::TEXT_NODE || pos.node()->nodeType() == Node::CDATA_SECTION_NODE) {
DOMString t = pos.node()->nodeValue();
if (t.isEmpty())
return *this;
QChar *chars = t.unicode();
uint len = t.length();
int start, end;
......@@ -348,6 +350,8 @@ Position Position::nextWordBoundary() const
while (tries < 2) {
if (pos.node()->nodeType() == Node::TEXT_NODE || pos.node()->nodeType() == Node::CDATA_SECTION_NODE) {
DOMString t = pos.node()->nodeValue();
if (t.isEmpty())
return *this;
QChar *chars = t.unicode();
uint len = t.length();
int start, end;
......@@ -610,7 +614,7 @@ Position Position::nextLinePosition(int x) const
return Position(rootElement, rootElement->childNodeCount());
}
Position Position::equivalentUpstreamPosition() const
Position Position::upstream(bool stayInBlock) const
{
if (!node())
return Position();
......@@ -618,10 +622,12 @@ Position Position::equivalentUpstreamPosition() const
NodeImpl *block = node()->enclosingBlockFlowElement();
PositionIterator it(*this);
for (; !it.atStart(); it.previous()) {
NodeImpl *currentBlock = it.current().node()->enclosingBlockFlowElement();
if (block != currentBlock)
return it.next();
for (; !it.atStart(); it.previous()) {
if (stayInBlock) {
NodeImpl *currentBlock = it.current().node()->enclosingBlockFlowElement();
if (block != currentBlock)
return it.next();
}
RenderObject *renderer = it.current().node()->renderer();