Index: Source/WebCore/editing/CompositeEditCommand.cpp |
=================================================================== |
--- Source/WebCore/editing/CompositeEditCommand.cpp (revision 109370) |
+++ Source/WebCore/editing/CompositeEditCommand.cpp (working copy) |
@@ -28,7 +28,6 @@ |
#include "AppendNodeCommand.h" |
#include "ApplyStyleCommand.h" |
-#include "DeleteButtonController.h" |
#include "DeleteFromTextNodeCommand.h" |
#include "DeleteSelectionCommand.h" |
#include "Document.h" |
@@ -53,7 +52,6 @@ |
#include "ReplaceSelectionCommand.h" |
#include "RenderBlock.h" |
#include "RenderText.h" |
-#include "ScopedEventQueue.h" |
#include "SetNodeAttributeCommand.h" |
#include "SplitElementCommand.h" |
#include "SplitTextNodeCommand.h" |
@@ -72,193 +70,37 @@ |
using namespace HTMLNames; |
-PassRefPtr<EditCommandComposition> EditCommandComposition::create(Document* document, |
- const VisibleSelection& startingSelection, const VisibleSelection& endingSelection, EditAction editAction) |
+CompositeEditCommand::CompositeEditCommand(Document *document) |
+ : EditCommand(document) |
{ |
- return adoptRef(new EditCommandComposition(document, startingSelection, endingSelection, editAction)); |
} |
-EditCommandComposition::EditCommandComposition(Document* document, const VisibleSelection& startingSelection, const VisibleSelection& endingSelection, EditAction editAction) |
- : m_document(document) |
- , m_startingSelection(startingSelection) |
- , m_endingSelection(endingSelection) |
- , m_startingRootEditableElement(startingSelection.rootEditableElement()) |
- , m_endingRootEditableElement(endingSelection.rootEditableElement()) |
- , m_editAction(editAction) |
+CompositeEditCommand::~CompositeEditCommand() |
{ |
} |
-void EditCommandComposition::unapply() |
+void CompositeEditCommand::doUnapply() |
{ |
- ASSERT(m_document); |
- Frame* frame = m_document->frame(); |
- ASSERT(frame); |
- |
- // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>. |
- // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one |
- // if one is necessary (like for the creation of VisiblePositions). |
- m_document->updateLayoutIgnorePendingStylesheets(); |
- |
- DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController(); |
- deleteButtonController->disable(); |
size_t size = m_commands.size(); |
for (size_t i = size; i != 0; --i) |
- m_commands[i - 1]->doUnapply(); |
- deleteButtonController->enable(); |
- |
- frame->editor()->unappliedEditing(this); |
+ m_commands[i - 1]->unapply(); |
} |
-void EditCommandComposition::reapply() |
+void CompositeEditCommand::doReapply() |
{ |
- ASSERT(m_document); |
- Frame* frame = m_document->frame(); |
- ASSERT(frame); |
- |
- // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>. |
- // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one |
- // if one is necessary (like for the creation of VisiblePositions). |
- m_document->updateLayoutIgnorePendingStylesheets(); |
- |
- DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController(); |
- deleteButtonController->disable(); |
size_t size = m_commands.size(); |
for (size_t i = 0; i != size; ++i) |
- m_commands[i]->doReapply(); |
- deleteButtonController->enable(); |
- |
- frame->editor()->reappliedEditing(this); |
+ m_commands[i]->reapply(); |
} |
-void EditCommandComposition::append(SimpleEditCommand* command) |
-{ |
- m_commands.append(command); |
-} |
- |
-void EditCommandComposition::setStartingSelection(const VisibleSelection& selection) |
-{ |
- m_startingSelection = selection; |
- m_startingRootEditableElement = selection.rootEditableElement(); |
-} |
- |
-void EditCommandComposition::setEndingSelection(const VisibleSelection& selection) |
-{ |
- m_endingSelection = selection; |
- m_endingRootEditableElement = selection.rootEditableElement(); |
-} |
- |
-#ifndef NDEBUG |
-void EditCommandComposition::getNodesInCommand(HashSet<Node*>& nodes) |
-{ |
- size_t size = m_commands.size(); |
- for (size_t i = 0; i < size; ++i) |
- m_commands[i]->getNodesInCommand(nodes); |
-} |
-#endif |
- |
-void applyCommand(PassRefPtr<CompositeEditCommand> command) |
-{ |
- command->apply(); |
-} |
- |
-CompositeEditCommand::CompositeEditCommand(Document *document) |
- : EditCommand(document) |
-{ |
-} |
- |
-CompositeEditCommand::~CompositeEditCommand() |
-{ |
- ASSERT(isTopLevelCommand() || !m_composition); |
-} |
- |
-void CompositeEditCommand::apply() |
-{ |
- if (!endingSelection().isContentRichlyEditable()) { |
- switch (editingAction()) { |
- case EditActionTyping: |
- case EditActionPaste: |
- case EditActionDrag: |
- case EditActionSetWritingDirection: |
- case EditActionCut: |
- case EditActionUnspecified: |
- break; |
- default: |
- ASSERT_NOT_REACHED(); |
- return; |
- } |
- } |
- ensureComposition(); |
- |
- // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>. |
- // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one |
- // if one is necessary (like for the creation of VisiblePositions). |
- ASSERT(document()); |
- document()->updateLayoutIgnorePendingStylesheets(); |
- |
- Frame* frame = document()->frame(); |
- ASSERT(frame); |
- { |
- EventQueueScope scope; |
- DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController(); |
- deleteButtonController->disable(); |
- doApply(); |
- deleteButtonController->enable(); |
- } |
- |
- // Only need to call appliedEditing for top-level commands, |
- // and TypingCommands do it on their own (see TypingCommand::typingAddedToOpenCommand). |
- if (!isTypingCommand()) |
- frame->editor()->appliedEditing(this); |
- setShouldRetainAutocorrectionIndicator(false); |
-} |
- |
-EditCommandComposition* CompositeEditCommand::ensureComposition() |
-{ |
- CompositeEditCommand* command = this; |
- while (command && command->parent()) |
- command = command->parent(); |
- if (!command->m_composition) |
- command->m_composition = EditCommandComposition::create(document(), startingSelection(), endingSelection(), editingAction()); |
- return command->m_composition.get(); |
-} |
- |
-bool CompositeEditCommand::isCreateLinkCommand() const |
-{ |
- return false; |
-} |
- |
-bool CompositeEditCommand::preservesTypingStyle() const |
-{ |
- return false; |
-} |
- |
-bool CompositeEditCommand::isTypingCommand() const |
-{ |
- return false; |
-} |
- |
-bool CompositeEditCommand::shouldRetainAutocorrectionIndicator() const |
-{ |
- return false; |
-} |
- |
-void CompositeEditCommand::setShouldRetainAutocorrectionIndicator(bool) |
-{ |
-} |
- |
// |
// sugary-sweet convenience functions to help create and apply edit commands in composite commands |
// |
-void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> prpCommand) |
+void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> cmd) |
{ |
- RefPtr<EditCommand> command = prpCommand; |
- command->setParent(this); |
- command->doApply(); |
- if (command->isSimpleEditCommand()) { |
- command->setParent(0); |
- ensureComposition()->append(toSimpleEditCommand(command.get())); |
- } |
- m_commands.append(command.release()); |
+ cmd->setParent(this); |
+ cmd->apply(); |
+ m_commands.append(cmd); |
} |
void CompositeEditCommand::applyCommandToComposite(PassRefPtr<CompositeEditCommand> command, const VisibleSelection& selection) |
@@ -268,7 +110,7 @@ |
command->setStartingSelection(selection); |
command->setEndingSelection(selection); |
} |
- command->doApply(); |
+ command->apply(); |
m_commands.append(command); |
} |
@@ -302,18 +144,6 @@ |
applyCommandToComposite(InsertLineBreakCommand::create(document())); |
} |
-bool CompositeEditCommand::isRemovableBlock(const Node* node) |
-{ |
- Node* parentNode = node->parentNode(); |
- if ((parentNode && parentNode->firstChild() != parentNode->lastChild()) || !node->hasTagName(divTag)) |
- return false; |
- |
- if (!node->isElementNode() || !toElement(node)->hasAttributes()) |
- return true; |
- |
- return false; |
-} |
- |
void CompositeEditCommand::insertNodeBefore(PassRefPtr<Node> insertChild, PassRefPtr<Node> refChild) |
{ |
ASSERT(!refChild->hasTagName(bodyTag)); |
@@ -356,7 +186,7 @@ |
} else if (caretMinOffset(refChild) >= offset) |
insertNodeBefore(insertChild, refChild); |
else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) { |
- splitTextNode(toText(refChild), offset); |
+ splitTextNode(static_cast<Text *>(refChild), offset); |
// Mutation events (bug 22634) from the text node insertion may have removed the refChild |
if (!refChild->inDocument()) |
@@ -532,7 +362,7 @@ |
if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode())) |
return positionInParentAfterNode(tabSpan); |
- splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInContainerNode()); |
+ splitTextNodeContainingElement(static_cast<Text *>(pos.containerNode()), pos.offsetInContainerNode()); |
return positionInParentBeforeNode(tabSpan); |
} |
@@ -590,7 +420,7 @@ |
if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node || !node->isTextNode()) |
return false; |
- Text* textNode = toText(node); |
+ Text* textNode = static_cast<Text*>(node); |
if (textNode->length() == 0) |
return false; |
@@ -610,14 +440,14 @@ |
// If the rebalance is for the single offset, and neither text[offset] nor text[offset - 1] are some form of whitespace, do nothing. |
int offset = position.deprecatedEditingOffset(); |
- String text = toText(node)->data(); |
+ String text = static_cast<Text*>(node)->data(); |
if (!isWhitespace(text[offset])) { |
offset--; |
if (offset < 0 || !isWhitespace(text[offset])) |
return; |
} |
- rebalanceWhitespaceOnTextSubstring(toText(node), position.offsetInContainerNode(), position.offsetInContainerNode()); |
+ rebalanceWhitespaceOnTextSubstring(static_cast<Text*>(node), position.offsetInContainerNode(), position.offsetInContainerNode()); |
} |
void CompositeEditCommand::rebalanceWhitespaceOnTextSubstring(PassRefPtr<Text> prpTextNode, int startOffset, int endOffset) |
@@ -659,7 +489,7 @@ |
Node* node = position.deprecatedNode(); |
if (!node || !node->isTextNode()) |
return; |
- Text* textNode = toText(node); |
+ Text* textNode = static_cast<Text*>(node); |
if (textNode->length() == 0) |
return; |
@@ -677,9 +507,9 @@ |
Position previous(previousVisiblePos.deepEquivalent()); |
if (isCollapsibleWhitespace(previousVisiblePos.characterAfter()) && previous.deprecatedNode()->isTextNode() && !previous.deprecatedNode()->hasTagName(brTag)) |
- replaceTextInNodePreservingMarkers(toText(previous.deprecatedNode()), previous.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); |
+ replaceTextInNodePreservingMarkers(static_cast<Text*>(previous.deprecatedNode()), previous.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); |
if (isCollapsibleWhitespace(visiblePos.characterAfter()) && position.deprecatedNode()->isTextNode() && !position.deprecatedNode()->hasTagName(brTag)) |
- replaceTextInNodePreservingMarkers(toText(position.deprecatedNode()), position.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); |
+ replaceTextInNodePreservingMarkers(static_cast<Text*>(position.deprecatedNode()), position.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); |
} |
void CompositeEditCommand::rebalanceWhitespace() |
@@ -698,8 +528,6 @@ |
if (!textNode || start >= end) |
return; |
- document()->updateLayout(); |
- |
RenderText* textRenderer = toRenderText(textNode->renderer()); |
if (!textRenderer) |
return; |
@@ -782,20 +610,18 @@ |
if (comparePositions(start, end) >= 0) |
return; |
- Vector<RefPtr<Text> > nodes; |
- for (Node* node = start.deprecatedNode(); node; node = node->traverseNextNode()) { |
- if (node->isTextNode()) |
- nodes.append(toText(node)); |
+ Node* next; |
+ for (Node* node = start.deprecatedNode(); node; node = next) { |
+ next = node->traverseNextNode(); |
+ if (node->isTextNode()) { |
+ Text* textNode = static_cast<Text*>(node); |
+ int startOffset = node == start.deprecatedNode() ? start.deprecatedEditingOffset() : 0; |
+ int endOffset = node == end.deprecatedNode() ? end.deprecatedEditingOffset() : static_cast<int>(textNode->length()); |
+ deleteInsignificantText(textNode, startOffset, endOffset); |
+ } |
if (node == end.deprecatedNode()) |
break; |
} |
- |
- for (size_t i = 0; i < nodes.size(); ++i) { |
- Text* textNode = nodes[i].get(); |
- int startOffset = textNode == start.deprecatedNode() ? start.deprecatedEditingOffset() : 0; |
- int endOffset = textNode == end.deprecatedNode() ? end.deprecatedEditingOffset() : static_cast<int>(textNode->length()); |
- deleteInsignificantText(textNode, startOffset, endOffset); |
- } |
} |
void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos) |
@@ -835,7 +661,7 @@ |
if (!container) |
return 0; |
- document()->updateLayoutIgnorePendingStylesheets(); |
+ updateLayout(); |
RenderObject* renderer = container->renderer(); |
if (!renderer || !renderer->isBlockFlow()) |
@@ -861,7 +687,7 @@ |
return; |
} |
- deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1); |
+ deleteTextFromNode(static_cast<Text*>(p.anchorNode()), p.offsetInContainerNode(), 1); |
} |
PassRefPtr<Node> CompositeEditCommand::insertNewDefaultParagraphElementAt(const Position& position) |
@@ -880,7 +706,7 @@ |
if (pos.isNull()) |
return 0; |
- document()->updateLayoutIgnorePendingStylesheets(); |
+ updateLayout(); |
// It's strange that this function is responsible for verifying that pos has not been invalidated |
// by an earlier call to this function. The caller, applyBlockStyle, should do this. |
@@ -1037,7 +863,7 @@ |
else if (lineBreakExistsAtPosition(position)) { |
// There is a preserved '\n' at caretAfterDelete. |
// We can safely assume this is a text node. |
- Text* textNode = toText(node); |
+ Text* textNode = static_cast<Text*>(node); |
if (textNode->length() == 1) |
removeNodeAndPruneAncestors(node); |
else |
@@ -1190,7 +1016,7 @@ |
// FIXME: Trim text between beforeParagraph and afterParagraph if they aren't equal. |
insertNodeAt(createBreakElement(document()), beforeParagraph.deepEquivalent()); |
// Need an updateLayout here in case inserting the br has split a text node. |
- document()->updateLayoutIgnorePendingStylesheets(); |
+ updateLayout(); |
} |
RefPtr<Range> startToDestinationRange(Range::create(document(), firstPositionInNode(document()->documentElement()), destination.deepEquivalent().parentAnchoredEquivalent())); |
@@ -1330,7 +1156,7 @@ |
removeNodeAndPruneAncestors(caretPos.deprecatedNode()); |
else if (caretPos.deprecatedNode()->isTextNode()) { |
ASSERT(caretPos.deprecatedEditingOffset() == 0); |
- Text* textNode = toText(caretPos.deprecatedNode()); |
+ Text* textNode = static_cast<Text*>(caretPos.deprecatedNode()); |
ContainerNode* parentNode = textNode->parentNode(); |
// The preserved newline must be the first thing in the node, since otherwise the previous |
// paragraph would be quoted, and we verified that it wasn't above. |