Changeset 109371 in webkit
- Timestamp:
- Mar 1, 2012, 11:05:14 AM (15 years ago)
- Location:
- branches/chromium/963
- Files:
-
- 2 deleted
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/chromium/963/Source/WebCore/editing/CompositeEditCommand.cpp
r109368 r109371 29 29 #include "AppendNodeCommand.h" 30 30 #include "ApplyStyleCommand.h" 31 #include "DeleteButtonController.h"32 31 #include "DeleteFromTextNodeCommand.h" 33 32 #include "DeleteSelectionCommand.h" … … 54 53 #include "RenderBlock.h" 55 54 #include "RenderText.h" 56 #include "ScopedEventQueue.h"57 55 #include "SetNodeAttributeCommand.h" 58 56 #include "SplitElementCommand.h" … … 73 71 using namespace HTMLNames; 74 72 75 PassRefPtr<EditCommandComposition> EditCommandComposition::create(Document* document, 76 const VisibleSelection& startingSelection, const VisibleSelection& endingSelection, EditAction editAction) 77 { 78 return adoptRef(new EditCommandComposition(document, startingSelection, endingSelection, editAction)); 79 } 80 81 EditCommandComposition::EditCommandComposition(Document* document, const VisibleSelection& startingSelection, const VisibleSelection& endingSelection, EditAction editAction) 82 : m_document(document) 83 , m_startingSelection(startingSelection) 84 , m_endingSelection(endingSelection) 85 , m_startingRootEditableElement(startingSelection.rootEditableElement()) 86 , m_endingRootEditableElement(endingSelection.rootEditableElement()) 87 , m_editAction(editAction) 88 { 89 } 90 91 void EditCommandComposition::unapply() 92 { 93 ASSERT(m_document); 94 Frame* frame = m_document->frame(); 95 ASSERT(frame); 96 97 // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>. 98 // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one 99 // if one is necessary (like for the creation of VisiblePositions). 100 m_document->updateLayoutIgnorePendingStylesheets(); 101 102 DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController(); 103 deleteButtonController->disable(); 73 CompositeEditCommand::CompositeEditCommand(Document *document) 74 : EditCommand(document) 75 { 76 } 77 78 CompositeEditCommand::~CompositeEditCommand() 79 { 80 } 81 82 void CompositeEditCommand::doUnapply() 83 { 104 84 size_t size = m_commands.size(); 105 85 for (size_t i = size; i != 0; --i) 106 m_commands[i - 1]->doUnapply(); 107 deleteButtonController->enable(); 108 109 frame->editor()->unappliedEditing(this); 110 } 111 112 void EditCommandComposition::reapply() 113 { 114 ASSERT(m_document); 115 Frame* frame = m_document->frame(); 116 ASSERT(frame); 117 118 // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>. 119 // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one 120 // if one is necessary (like for the creation of VisiblePositions). 121 m_document->updateLayoutIgnorePendingStylesheets(); 122 123 DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController(); 124 deleteButtonController->disable(); 86 m_commands[i - 1]->unapply(); 87 } 88 89 void CompositeEditCommand::doReapply() 90 { 125 91 size_t size = m_commands.size(); 126 92 for (size_t i = 0; i != size; ++i) 127 m_commands[i]->doReapply(); 128 deleteButtonController->enable(); 129 130 frame->editor()->reappliedEditing(this); 131 } 132 133 void EditCommandComposition::append(SimpleEditCommand* command) 134 { 135 m_commands.append(command); 136 } 137 138 void EditCommandComposition::setStartingSelection(const VisibleSelection& selection) 139 { 140 m_startingSelection = selection; 141 m_startingRootEditableElement = selection.rootEditableElement(); 142 } 143 144 void EditCommandComposition::setEndingSelection(const VisibleSelection& selection) 145 { 146 m_endingSelection = selection; 147 m_endingRootEditableElement = selection.rootEditableElement(); 148 } 149 150 #ifndef NDEBUG 151 void EditCommandComposition::getNodesInCommand(HashSet<Node*>& nodes) 152 { 153 size_t size = m_commands.size(); 154 for (size_t i = 0; i < size; ++i) 155 m_commands[i]->getNodesInCommand(nodes); 156 } 157 #endif 158 159 void applyCommand(PassRefPtr<CompositeEditCommand> command) 160 { 161 command->apply(); 162 } 163 164 CompositeEditCommand::CompositeEditCommand(Document *document) 165 : EditCommand(document) 166 { 167 } 168 169 CompositeEditCommand::~CompositeEditCommand() 170 { 171 ASSERT(isTopLevelCommand() || !m_composition); 172 } 173 174 void CompositeEditCommand::apply() 175 { 176 if (!endingSelection().isContentRichlyEditable()) { 177 switch (editingAction()) { 178 case EditActionTyping: 179 case EditActionPaste: 180 case EditActionDrag: 181 case EditActionSetWritingDirection: 182 case EditActionCut: 183 case EditActionUnspecified: 184 break; 185 default: 186 ASSERT_NOT_REACHED(); 187 return; 188 } 189 } 190 ensureComposition(); 191 192 // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>. 193 // Low level operations, like RemoveNodeCommand, don't require a layout because the high level operations that use them perform one 194 // if one is necessary (like for the creation of VisiblePositions). 195 ASSERT(document()); 196 document()->updateLayoutIgnorePendingStylesheets(); 197 198 Frame* frame = document()->frame(); 199 ASSERT(frame); 200 { 201 EventQueueScope scope; 202 DeleteButtonController* deleteButtonController = frame->editor()->deleteButtonController(); 203 deleteButtonController->disable(); 204 doApply(); 205 deleteButtonController->enable(); 206 } 207 208 // Only need to call appliedEditing for top-level commands, 209 // and TypingCommands do it on their own (see TypingCommand::typingAddedToOpenCommand). 210 if (!isTypingCommand()) 211 frame->editor()->appliedEditing(this); 212 setShouldRetainAutocorrectionIndicator(false); 213 } 214 215 EditCommandComposition* CompositeEditCommand::ensureComposition() 216 { 217 CompositeEditCommand* command = this; 218 while (command && command->parent()) 219 command = command->parent(); 220 if (!command->m_composition) 221 command->m_composition = EditCommandComposition::create(document(), startingSelection(), endingSelection(), editingAction()); 222 return command->m_composition.get(); 223 } 224 225 bool CompositeEditCommand::isCreateLinkCommand() const 226 { 227 return false; 228 } 229 230 bool CompositeEditCommand::preservesTypingStyle() const 231 { 232 return false; 233 } 234 235 bool CompositeEditCommand::isTypingCommand() const 236 { 237 return false; 238 } 239 240 bool CompositeEditCommand::shouldRetainAutocorrectionIndicator() const 241 { 242 return false; 243 } 244 245 void CompositeEditCommand::setShouldRetainAutocorrectionIndicator(bool) 246 { 93 m_commands[i]->reapply(); 247 94 } 248 95 … … 250 97 // sugary-sweet convenience functions to help create and apply edit commands in composite commands 251 98 // 252 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> prpCommand) 253 { 254 RefPtr<EditCommand> command = prpCommand; 255 command->setParent(this); 256 command->doApply(); 257 if (command->isSimpleEditCommand()) { 258 command->setParent(0); 259 ensureComposition()->append(toSimpleEditCommand(command.get())); 260 } 261 m_commands.append(command.release()); 99 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> cmd) 100 { 101 cmd->setParent(this); 102 cmd->apply(); 103 m_commands.append(cmd); 262 104 } 263 105 … … 269 111 command->setEndingSelection(selection); 270 112 } 271 command-> doApply();113 command->apply(); 272 114 m_commands.append(command); 273 115 } … … 301 143 { 302 144 applyCommandToComposite(InsertLineBreakCommand::create(document())); 303 }304 305 bool CompositeEditCommand::isRemovableBlock(const Node* node)306 {307 Node* parentNode = node->parentNode();308 if ((parentNode && parentNode->firstChild() != parentNode->lastChild()) || !node->hasTagName(divTag))309 return false;310 311 if (!node->isElementNode() || !toElement(node)->hasAttributes())312 return true;313 314 return false;315 145 } 316 146 … … 357 187 insertNodeBefore(insertChild, refChild); 358 188 else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) { 359 splitTextNode( toText(refChild), offset);189 splitTextNode(static_cast<Text *>(refChild), offset); 360 190 361 191 // Mutation events (bug 22634) from the text node insertion may have removed the refChild … … 533 363 return positionInParentAfterNode(tabSpan); 534 364 535 splitTextNodeContainingElement( toText(pos.containerNode()), pos.offsetInContainerNode());365 splitTextNodeContainingElement(static_cast<Text *>(pos.containerNode()), pos.offsetInContainerNode()); 536 366 return positionInParentBeforeNode(tabSpan); 537 367 } … … 591 421 return false; 592 422 593 Text* textNode = toText(node);423 Text* textNode = static_cast<Text*>(node); 594 424 if (textNode->length() == 0) 595 425 return false; … … 611 441 // If the rebalance is for the single offset, and neither text[offset] nor text[offset - 1] are some form of whitespace, do nothing. 612 442 int offset = position.deprecatedEditingOffset(); 613 String text = toText(node)->data();443 String text = static_cast<Text*>(node)->data(); 614 444 if (!isWhitespace(text[offset])) { 615 445 offset--; … … 618 448 } 619 449 620 rebalanceWhitespaceOnTextSubstring( toText(node), position.offsetInContainerNode(), position.offsetInContainerNode());450 rebalanceWhitespaceOnTextSubstring(static_cast<Text*>(node), position.offsetInContainerNode(), position.offsetInContainerNode()); 621 451 } 622 452 … … 660 490 if (!node || !node->isTextNode()) 661 491 return; 662 Text* textNode = toText(node);492 Text* textNode = static_cast<Text*>(node); 663 493 664 494 if (textNode->length() == 0) … … 678 508 679 509 if (isCollapsibleWhitespace(previousVisiblePos.characterAfter()) && previous.deprecatedNode()->isTextNode() && !previous.deprecatedNode()->hasTagName(brTag)) 680 replaceTextInNodePreservingMarkers( toText(previous.deprecatedNode()), previous.deprecatedEditingOffset(), 1, nonBreakingSpaceString());510 replaceTextInNodePreservingMarkers(static_cast<Text*>(previous.deprecatedNode()), previous.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); 681 511 if (isCollapsibleWhitespace(visiblePos.characterAfter()) && position.deprecatedNode()->isTextNode() && !position.deprecatedNode()->hasTagName(brTag)) 682 replaceTextInNodePreservingMarkers( toText(position.deprecatedNode()), position.deprecatedEditingOffset(), 1, nonBreakingSpaceString());512 replaceTextInNodePreservingMarkers(static_cast<Text*>(position.deprecatedNode()), position.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); 683 513 } 684 514 … … 698 528 if (!textNode || start >= end) 699 529 return; 700 701 document()->updateLayout();702 530 703 531 RenderText* textRenderer = toRenderText(textNode->renderer()); … … 783 611 return; 784 612 785 Vector<RefPtr<Text> > nodes; 786 for (Node* node = start.deprecatedNode(); node; node = node->traverseNextNode()) { 787 if (node->isTextNode()) 788 nodes.append(toText(node)); 613 Node* next; 614 for (Node* node = start.deprecatedNode(); node; node = next) { 615 next = node->traverseNextNode(); 616 if (node->isTextNode()) { 617 Text* textNode = static_cast<Text*>(node); 618 int startOffset = node == start.deprecatedNode() ? start.deprecatedEditingOffset() : 0; 619 int endOffset = node == end.deprecatedNode() ? end.deprecatedEditingOffset() : static_cast<int>(textNode->length()); 620 deleteInsignificantText(textNode, startOffset, endOffset); 621 } 789 622 if (node == end.deprecatedNode()) 790 623 break; 791 }792 793 for (size_t i = 0; i < nodes.size(); ++i) {794 Text* textNode = nodes[i].get();795 int startOffset = textNode == start.deprecatedNode() ? start.deprecatedEditingOffset() : 0;796 int endOffset = textNode == end.deprecatedNode() ? end.deprecatedEditingOffset() : static_cast<int>(textNode->length());797 deleteInsignificantText(textNode, startOffset, endOffset);798 624 } 799 625 } … … 836 662 return 0; 837 663 838 document()->updateLayoutIgnorePendingStylesheets();664 updateLayout(); 839 665 840 666 RenderObject* renderer = container->renderer(); … … 862 688 } 863 689 864 deleteTextFromNode( toText(p.anchorNode()), p.offsetInContainerNode(), 1);690 deleteTextFromNode(static_cast<Text*>(p.anchorNode()), p.offsetInContainerNode(), 1); 865 691 } 866 692 … … 881 707 return 0; 882 708 883 document()->updateLayoutIgnorePendingStylesheets();709 updateLayout(); 884 710 885 711 // It's strange that this function is responsible for verifying that pos has not been invalidated … … 1038 864 // There is a preserved '\n' at caretAfterDelete. 1039 865 // We can safely assume this is a text node. 1040 Text* textNode = toText(node);866 Text* textNode = static_cast<Text*>(node); 1041 867 if (textNode->length() == 1) 1042 868 removeNodeAndPruneAncestors(node); … … 1191 1017 insertNodeAt(createBreakElement(document()), beforeParagraph.deepEquivalent()); 1192 1018 // Need an updateLayout here in case inserting the br has split a text node. 1193 document()->updateLayoutIgnorePendingStylesheets();1019 updateLayout(); 1194 1020 } 1195 1021 … … 1331 1157 else if (caretPos.deprecatedNode()->isTextNode()) { 1332 1158 ASSERT(caretPos.deprecatedEditingOffset() == 0); 1333 Text* textNode = toText(caretPos.deprecatedNode());1159 Text* textNode = static_cast<Text*>(caretPos.deprecatedNode()); 1334 1160 ContainerNode* parentNode = textNode->parentNode(); 1335 1161 // The preserved newline must be the first thing in the node, since otherwise the previous
Note:
See TracChangeset
for help on using the changeset viewer.