OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 10 matching lines...) Expand all Loading... |
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "config.h" | 26 #include "config.h" |
27 #include "CompositeEditCommand.h" | 27 #include "CompositeEditCommand.h" |
28 | 28 |
29 #include "AppendNodeCommand.h" | 29 #include "AppendNodeCommand.h" |
30 #include "ApplyStyleCommand.h" | 30 #include "ApplyStyleCommand.h" |
31 #include "DeleteButtonController.h" | |
32 #include "DeleteFromTextNodeCommand.h" | 31 #include "DeleteFromTextNodeCommand.h" |
33 #include "DeleteSelectionCommand.h" | 32 #include "DeleteSelectionCommand.h" |
34 #include "Document.h" | 33 #include "Document.h" |
35 #include "DocumentFragment.h" | 34 #include "DocumentFragment.h" |
36 #include "DocumentMarkerController.h" | 35 #include "DocumentMarkerController.h" |
37 #include "EditorInsertAction.h" | 36 #include "EditorInsertAction.h" |
38 #include "Frame.h" | 37 #include "Frame.h" |
39 #include "HTMLElement.h" | 38 #include "HTMLElement.h" |
40 #include "HTMLNames.h" | 39 #include "HTMLNames.h" |
41 #include "InlineTextBox.h" | 40 #include "InlineTextBox.h" |
42 #include "InsertIntoTextNodeCommand.h" | 41 #include "InsertIntoTextNodeCommand.h" |
43 #include "InsertLineBreakCommand.h" | 42 #include "InsertLineBreakCommand.h" |
44 #include "InsertNodeBeforeCommand.h" | 43 #include "InsertNodeBeforeCommand.h" |
45 #include "InsertParagraphSeparatorCommand.h" | 44 #include "InsertParagraphSeparatorCommand.h" |
46 #include "InsertTextCommand.h" | 45 #include "InsertTextCommand.h" |
47 #include "MergeIdenticalElementsCommand.h" | 46 #include "MergeIdenticalElementsCommand.h" |
48 #include "Range.h" | 47 #include "Range.h" |
49 #include "RemoveCSSPropertyCommand.h" | 48 #include "RemoveCSSPropertyCommand.h" |
50 #include "RemoveNodeCommand.h" | 49 #include "RemoveNodeCommand.h" |
51 #include "RemoveNodePreservingChildrenCommand.h" | 50 #include "RemoveNodePreservingChildrenCommand.h" |
52 #include "ReplaceNodeWithSpanCommand.h" | 51 #include "ReplaceNodeWithSpanCommand.h" |
53 #include "ReplaceSelectionCommand.h" | 52 #include "ReplaceSelectionCommand.h" |
54 #include "RenderBlock.h" | 53 #include "RenderBlock.h" |
55 #include "RenderText.h" | 54 #include "RenderText.h" |
56 #include "ScopedEventQueue.h" | |
57 #include "SetNodeAttributeCommand.h" | 55 #include "SetNodeAttributeCommand.h" |
58 #include "SplitElementCommand.h" | 56 #include "SplitElementCommand.h" |
59 #include "SplitTextNodeCommand.h" | 57 #include "SplitTextNodeCommand.h" |
60 #include "SplitTextNodeContainingElementCommand.h" | 58 #include "SplitTextNodeContainingElementCommand.h" |
61 #include "Text.h" | 59 #include "Text.h" |
62 #include "TextIterator.h" | 60 #include "TextIterator.h" |
63 #include "WrapContentsInDummySpanCommand.h" | 61 #include "WrapContentsInDummySpanCommand.h" |
64 #include "htmlediting.h" | 62 #include "htmlediting.h" |
65 #include "markup.h" | 63 #include "markup.h" |
66 #include "visible_units.h" | 64 #include "visible_units.h" |
67 #include <wtf/unicode/CharacterNames.h> | 65 #include <wtf/unicode/CharacterNames.h> |
68 | 66 |
69 using namespace std; | 67 using namespace std; |
70 | 68 |
71 namespace WebCore { | 69 namespace WebCore { |
72 | 70 |
73 using namespace HTMLNames; | 71 using namespace HTMLNames; |
74 | 72 |
75 PassRefPtr<EditCommandComposition> EditCommandComposition::create(Document* docu
ment, | |
76 const VisibleSelection& startingSelection, const VisibleSelection& endingSel
ection, EditAction editAction) | |
77 { | |
78 return adoptRef(new EditCommandComposition(document, startingSelection, endi
ngSelection, editAction)); | |
79 } | |
80 | |
81 EditCommandComposition::EditCommandComposition(Document* document, const Visible
Selection& startingSelection, const VisibleSelection& endingSelection, EditActio
n 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 operati
on that require a layout, as in <rdar://problem/5658603>. | |
98 // Low level operations, like RemoveNodeCommand, don't require a layout beca
use 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()->deleteButt
onController(); | |
103 deleteButtonController->disable(); | |
104 size_t size = m_commands.size(); | |
105 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 operati
on that require a layout, as in <rdar://problem/5658603>. | |
119 // Low level operations, like RemoveNodeCommand, don't require a layout beca
use 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()->deleteButt
onController(); | |
124 deleteButtonController->disable(); | |
125 size_t size = m_commands.size(); | |
126 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& select
ion) | |
139 { | |
140 m_startingSelection = selection; | |
141 m_startingRootEditableElement = selection.rootEditableElement(); | |
142 } | |
143 | |
144 void EditCommandComposition::setEndingSelection(const VisibleSelection& selectio
n) | |
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) | 73 CompositeEditCommand::CompositeEditCommand(Document *document) |
165 : EditCommand(document) | 74 : EditCommand(document) |
166 { | 75 { |
167 } | 76 } |
168 | 77 |
169 CompositeEditCommand::~CompositeEditCommand() | 78 CompositeEditCommand::~CompositeEditCommand() |
170 { | 79 { |
171 ASSERT(isTopLevelCommand() || !m_composition); | |
172 } | 80 } |
173 | 81 |
174 void CompositeEditCommand::apply() | 82 void CompositeEditCommand::doUnapply() |
175 { | 83 { |
176 if (!endingSelection().isContentRichlyEditable()) { | 84 size_t size = m_commands.size(); |
177 switch (editingAction()) { | 85 for (size_t i = size; i != 0; --i) |
178 case EditActionTyping: | 86 m_commands[i - 1]->unapply(); |
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 operati
on that require a layout, as in <rdar://problem/5658603>. | |
193 // Low level operations, like RemoveNodeCommand, don't require a layout beca
use 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()->delete
ButtonController(); | |
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::typingAddedToOp
enCommand). | |
210 if (!isTypingCommand()) | |
211 frame->editor()->appliedEditing(this); | |
212 setShouldRetainAutocorrectionIndicator(false); | |
213 } | 87 } |
214 | 88 |
215 EditCommandComposition* CompositeEditCommand::ensureComposition() | 89 void CompositeEditCommand::doReapply() |
216 { | 90 { |
217 CompositeEditCommand* command = this; | 91 size_t size = m_commands.size(); |
218 while (command && command->parent()) | 92 for (size_t i = 0; i != size; ++i) |
219 command = command->parent(); | 93 m_commands[i]->reapply(); |
220 if (!command->m_composition) | |
221 command->m_composition = EditCommandComposition::create(document(), star
tingSelection(), 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 { | |
247 } | 94 } |
248 | 95 |
249 // | 96 // |
250 // sugary-sweet convenience functions to help create and apply edit commands in
composite commands | 97 // sugary-sweet convenience functions to help create and apply edit commands in
composite commands |
251 // | 98 // |
252 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> prpCo
mmand) | 99 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> cmd) |
253 { | 100 { |
254 RefPtr<EditCommand> command = prpCommand; | 101 cmd->setParent(this); |
255 command->setParent(this); | 102 cmd->apply(); |
256 command->doApply(); | 103 m_commands.append(cmd); |
257 if (command->isSimpleEditCommand()) { | |
258 command->setParent(0); | |
259 ensureComposition()->append(toSimpleEditCommand(command.get())); | |
260 } | |
261 m_commands.append(command.release()); | |
262 } | 104 } |
263 | 105 |
264 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<CompositeEditComma
nd> command, const VisibleSelection& selection) | 106 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<CompositeEditComma
nd> command, const VisibleSelection& selection) |
265 { | 107 { |
266 command->setParent(this); | 108 command->setParent(this); |
267 if (selection != command->endingSelection()) { | 109 if (selection != command->endingSelection()) { |
268 command->setStartingSelection(selection); | 110 command->setStartingSelection(selection); |
269 command->setEndingSelection(selection); | 111 command->setEndingSelection(selection); |
270 } | 112 } |
271 command->doApply(); | 113 command->apply(); |
272 m_commands.append(command); | 114 m_commands.append(command); |
273 } | 115 } |
274 | 116 |
275 void CompositeEditCommand::applyStyle(const EditingStyle* style, EditAction edit
ingAction) | 117 void CompositeEditCommand::applyStyle(const EditingStyle* style, EditAction edit
ingAction) |
276 { | 118 { |
277 applyCommandToComposite(ApplyStyleCommand::create(document(), style, editing
Action)); | 119 applyCommandToComposite(ApplyStyleCommand::create(document(), style, editing
Action)); |
278 } | 120 } |
279 | 121 |
280 void CompositeEditCommand::applyStyle(const EditingStyle* style, const Position&
start, const Position& end, EditAction editingAction) | 122 void CompositeEditCommand::applyStyle(const EditingStyle* style, const Position&
start, const Position& end, EditAction editingAction) |
281 { | 123 { |
(...skipping 13 matching lines...) Expand all Loading... |
295 void CompositeEditCommand::insertParagraphSeparator(bool useDefaultParagraphElem
ent) | 137 void CompositeEditCommand::insertParagraphSeparator(bool useDefaultParagraphElem
ent) |
296 { | 138 { |
297 applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(),
useDefaultParagraphElement)); | 139 applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(),
useDefaultParagraphElement)); |
298 } | 140 } |
299 | 141 |
300 void CompositeEditCommand::insertLineBreak() | 142 void CompositeEditCommand::insertLineBreak() |
301 { | 143 { |
302 applyCommandToComposite(InsertLineBreakCommand::create(document())); | 144 applyCommandToComposite(InsertLineBreakCommand::create(document())); |
303 } | 145 } |
304 | 146 |
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 } | |
316 | |
317 void CompositeEditCommand::insertNodeBefore(PassRefPtr<Node> insertChild, PassRe
fPtr<Node> refChild) | 147 void CompositeEditCommand::insertNodeBefore(PassRefPtr<Node> insertChild, PassRe
fPtr<Node> refChild) |
318 { | 148 { |
319 ASSERT(!refChild->hasTagName(bodyTag)); | 149 ASSERT(!refChild->hasTagName(bodyTag)); |
320 applyCommandToComposite(InsertNodeBeforeCommand::create(insertChild, refChil
d)); | 150 applyCommandToComposite(InsertNodeBeforeCommand::create(insertChild, refChil
d)); |
321 } | 151 } |
322 | 152 |
323 void CompositeEditCommand::insertNodeAfter(PassRefPtr<Node> insertChild, PassRef
Ptr<Node> refChild) | 153 void CompositeEditCommand::insertNodeAfter(PassRefPtr<Node> insertChild, PassRef
Ptr<Node> refChild) |
324 { | 154 { |
325 ASSERT(insertChild); | 155 ASSERT(insertChild); |
326 ASSERT(refChild); | 156 ASSERT(refChild); |
(...skipping 22 matching lines...) Expand all Loading... |
349 Node* child = refChild->firstChild(); | 179 Node* child = refChild->firstChild(); |
350 for (int i = 0; child && i < offset; i++) | 180 for (int i = 0; child && i < offset; i++) |
351 child = child->nextSibling(); | 181 child = child->nextSibling(); |
352 if (child) | 182 if (child) |
353 insertNodeBefore(insertChild, child); | 183 insertNodeBefore(insertChild, child); |
354 else | 184 else |
355 appendNode(insertChild, static_cast<Element*>(refChild)); | 185 appendNode(insertChild, static_cast<Element*>(refChild)); |
356 } else if (caretMinOffset(refChild) >= offset) | 186 } else if (caretMinOffset(refChild) >= offset) |
357 insertNodeBefore(insertChild, refChild); | 187 insertNodeBefore(insertChild, refChild); |
358 else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) { | 188 else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) { |
359 splitTextNode(toText(refChild), offset); | 189 splitTextNode(static_cast<Text *>(refChild), offset); |
360 | 190 |
361 // Mutation events (bug 22634) from the text node insertion may have rem
oved the refChild | 191 // Mutation events (bug 22634) from the text node insertion may have rem
oved the refChild |
362 if (!refChild->inDocument()) | 192 if (!refChild->inDocument()) |
363 return; | 193 return; |
364 insertNodeBefore(insertChild, refChild); | 194 insertNodeBefore(insertChild, refChild); |
365 } else | 195 } else |
366 insertNodeAfter(insertChild, refChild); | 196 insertNodeAfter(insertChild, refChild); |
367 } | 197 } |
368 | 198 |
369 void CompositeEditCommand::appendNode(PassRefPtr<Node> node, PassRefPtr<Containe
rNode> parent) | 199 void CompositeEditCommand::appendNode(PassRefPtr<Node> node, PassRefPtr<Containe
rNode> parent) |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 355 } |
526 | 356 |
527 Node* tabSpan = tabSpanNode(pos.containerNode()); | 357 Node* tabSpan = tabSpanNode(pos.containerNode()); |
528 | 358 |
529 if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode())) | 359 if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode())) |
530 return positionInParentBeforeNode(tabSpan); | 360 return positionInParentBeforeNode(tabSpan); |
531 | 361 |
532 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode())) | 362 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode())) |
533 return positionInParentAfterNode(tabSpan); | 363 return positionInParentAfterNode(tabSpan); |
534 | 364 |
535 splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInCont
ainerNode()); | 365 splitTextNodeContainingElement(static_cast<Text *>(pos.containerNode()), pos
.offsetInContainerNode()); |
536 return positionInParentBeforeNode(tabSpan); | 366 return positionInParentBeforeNode(tabSpan); |
537 } | 367 } |
538 | 368 |
539 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, co
nst Position& pos) | 369 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, co
nst Position& pos) |
540 { | 370 { |
541 // insert node before, after, or at split of tab span | 371 // insert node before, after, or at split of tab span |
542 insertNodeAt(node, positionOutsideTabSpan(pos)); | 372 insertNodeAt(node, positionOutsideTabSpan(pos)); |
543 } | 373 } |
544 | 374 |
545 void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAft
erDelete, bool replace, bool expandForSpecialElements) | 375 void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAft
erDelete, bool replace, bool expandForSpecialElements) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 { | 413 { |
584 return containsOnlyWhitespace(text); | 414 return containsOnlyWhitespace(text); |
585 } | 415 } |
586 | 416 |
587 bool CompositeEditCommand::canRebalance(const Position& position) const | 417 bool CompositeEditCommand::canRebalance(const Position& position) const |
588 { | 418 { |
589 Node* node = position.containerNode(); | 419 Node* node = position.containerNode(); |
590 if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node ||
!node->isTextNode()) | 420 if (position.anchorType() != Position::PositionIsOffsetInAnchor || !node ||
!node->isTextNode()) |
591 return false; | 421 return false; |
592 | 422 |
593 Text* textNode = toText(node); | 423 Text* textNode = static_cast<Text*>(node); |
594 if (textNode->length() == 0) | 424 if (textNode->length() == 0) |
595 return false; | 425 return false; |
596 | 426 |
597 RenderObject* renderer = textNode->renderer(); | 427 RenderObject* renderer = textNode->renderer(); |
598 if (renderer && !renderer->style()->collapseWhiteSpace()) | 428 if (renderer && !renderer->style()->collapseWhiteSpace()) |
599 return false; | 429 return false; |
600 | 430 |
601 return true; | 431 return true; |
602 } | 432 } |
603 | 433 |
604 // FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, co
usins, etc). | 434 // FIXME: Doesn't go into text nodes that contribute adjacent text (siblings, co
usins, etc). |
605 void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position) | 435 void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position) |
606 { | 436 { |
607 Node* node = position.containerNode(); | 437 Node* node = position.containerNode(); |
608 if (!canRebalance(position)) | 438 if (!canRebalance(position)) |
609 return; | 439 return; |
610 | 440 |
611 // If the rebalance is for the single offset, and neither text[offset] nor t
ext[offset - 1] are some form of whitespace, do nothing. | 441 // If the rebalance is for the single offset, and neither text[offset] nor t
ext[offset - 1] are some form of whitespace, do nothing. |
612 int offset = position.deprecatedEditingOffset(); | 442 int offset = position.deprecatedEditingOffset(); |
613 String text = toText(node)->data(); | 443 String text = static_cast<Text*>(node)->data(); |
614 if (!isWhitespace(text[offset])) { | 444 if (!isWhitespace(text[offset])) { |
615 offset--; | 445 offset--; |
616 if (offset < 0 || !isWhitespace(text[offset])) | 446 if (offset < 0 || !isWhitespace(text[offset])) |
617 return; | 447 return; |
618 } | 448 } |
619 | 449 |
620 rebalanceWhitespaceOnTextSubstring(toText(node), position.offsetInContainerN
ode(), position.offsetInContainerNode()); | 450 rebalanceWhitespaceOnTextSubstring(static_cast<Text*>(node), position.offset
InContainerNode(), position.offsetInContainerNode()); |
621 } | 451 } |
622 | 452 |
623 void CompositeEditCommand::rebalanceWhitespaceOnTextSubstring(PassRefPtr<Text> p
rpTextNode, int startOffset, int endOffset) | 453 void CompositeEditCommand::rebalanceWhitespaceOnTextSubstring(PassRefPtr<Text> p
rpTextNode, int startOffset, int endOffset) |
624 { | 454 { |
625 RefPtr<Text> textNode = prpTextNode; | 455 RefPtr<Text> textNode = prpTextNode; |
626 | 456 |
627 String text = textNode->data(); | 457 String text = textNode->data(); |
628 ASSERT(!text.isEmpty()); | 458 ASSERT(!text.isEmpty()); |
629 | 459 |
630 // Set upstream and downstream to define the extent of the whitespace surrou
nding text[offset]. | 460 // Set upstream and downstream to define the extent of the whitespace surrou
nding text[offset]. |
(...skipping 21 matching lines...) Expand all Loading... |
652 | 482 |
653 if (string != rebalancedString) | 483 if (string != rebalancedString) |
654 replaceTextInNodePreservingMarkers(textNode.release(), upstream, length,
rebalancedString); | 484 replaceTextInNodePreservingMarkers(textNode.release(), upstream, length,
rebalancedString); |
655 } | 485 } |
656 | 486 |
657 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(Position& positio
n) | 487 void CompositeEditCommand::prepareWhitespaceAtPositionForSplit(Position& positio
n) |
658 { | 488 { |
659 Node* node = position.deprecatedNode(); | 489 Node* node = position.deprecatedNode(); |
660 if (!node || !node->isTextNode()) | 490 if (!node || !node->isTextNode()) |
661 return; | 491 return; |
662 Text* textNode = toText(node); | 492 Text* textNode = static_cast<Text*>(node); |
663 | 493 |
664 if (textNode->length() == 0) | 494 if (textNode->length() == 0) |
665 return; | 495 return; |
666 RenderObject* renderer = textNode->renderer(); | 496 RenderObject* renderer = textNode->renderer(); |
667 if (renderer && !renderer->style()->collapseWhiteSpace()) | 497 if (renderer && !renderer->style()->collapseWhiteSpace()) |
668 return; | 498 return; |
669 | 499 |
670 // Delete collapsed whitespace so that inserting nbsps doesn't uncollapse it
. | 500 // Delete collapsed whitespace so that inserting nbsps doesn't uncollapse it
. |
671 Position upstreamPos = position.upstream(); | 501 Position upstreamPos = position.upstream(); |
672 deleteInsignificantText(position.upstream(), position.downstream()); | 502 deleteInsignificantText(position.upstream(), position.downstream()); |
673 position = upstreamPos.downstream(); | 503 position = upstreamPos.downstream(); |
674 | 504 |
675 VisiblePosition visiblePos(position); | 505 VisiblePosition visiblePos(position); |
676 VisiblePosition previousVisiblePos(visiblePos.previous()); | 506 VisiblePosition previousVisiblePos(visiblePos.previous()); |
677 Position previous(previousVisiblePos.deepEquivalent()); | 507 Position previous(previousVisiblePos.deepEquivalent()); |
678 | 508 |
679 if (isCollapsibleWhitespace(previousVisiblePos.characterAfter()) && previous
.deprecatedNode()->isTextNode() && !previous.deprecatedNode()->hasTagName(brTag)
) | 509 if (isCollapsibleWhitespace(previousVisiblePos.characterAfter()) && previous
.deprecatedNode()->isTextNode() && !previous.deprecatedNode()->hasTagName(brTag)
) |
680 replaceTextInNodePreservingMarkers(toText(previous.deprecatedNode()), pr
evious.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); | 510 replaceTextInNodePreservingMarkers(static_cast<Text*>(previous.deprecate
dNode()), previous.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); |
681 if (isCollapsibleWhitespace(visiblePos.characterAfter()) && position.depreca
tedNode()->isTextNode() && !position.deprecatedNode()->hasTagName(brTag)) | 511 if (isCollapsibleWhitespace(visiblePos.characterAfter()) && position.depreca
tedNode()->isTextNode() && !position.deprecatedNode()->hasTagName(brTag)) |
682 replaceTextInNodePreservingMarkers(toText(position.deprecatedNode()), po
sition.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); | 512 replaceTextInNodePreservingMarkers(static_cast<Text*>(position.deprecate
dNode()), position.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); |
683 } | 513 } |
684 | 514 |
685 void CompositeEditCommand::rebalanceWhitespace() | 515 void CompositeEditCommand::rebalanceWhitespace() |
686 { | 516 { |
687 VisibleSelection selection = endingSelection(); | 517 VisibleSelection selection = endingSelection(); |
688 if (selection.isNone()) | 518 if (selection.isNone()) |
689 return; | 519 return; |
690 | 520 |
691 rebalanceWhitespaceAt(selection.start()); | 521 rebalanceWhitespaceAt(selection.start()); |
692 if (selection.isRange()) | 522 if (selection.isRange()) |
693 rebalanceWhitespaceAt(selection.end()); | 523 rebalanceWhitespaceAt(selection.end()); |
694 } | 524 } |
695 | 525 |
696 void CompositeEditCommand::deleteInsignificantText(PassRefPtr<Text> textNode, un
signed start, unsigned end) | 526 void CompositeEditCommand::deleteInsignificantText(PassRefPtr<Text> textNode, un
signed start, unsigned end) |
697 { | 527 { |
698 if (!textNode || start >= end) | 528 if (!textNode || start >= end) |
699 return; | 529 return; |
700 | 530 |
701 document()->updateLayout(); | |
702 | |
703 RenderText* textRenderer = toRenderText(textNode->renderer()); | 531 RenderText* textRenderer = toRenderText(textNode->renderer()); |
704 if (!textRenderer) | 532 if (!textRenderer) |
705 return; | 533 return; |
706 | 534 |
707 Vector<InlineTextBox*> sortedTextBoxes; | 535 Vector<InlineTextBox*> sortedTextBoxes; |
708 size_t sortedTextBoxesPosition = 0; | 536 size_t sortedTextBoxesPosition = 0; |
709 | 537 |
710 for (InlineTextBox* textBox = textRenderer->firstTextBox(); textBox; textBox
= textBox->nextTextBox()) | 538 for (InlineTextBox* textBox = textRenderer->firstTextBox(); textBox; textBox
= textBox->nextTextBox()) |
711 sortedTextBoxes.append(textBox); | 539 sortedTextBoxes.append(textBox); |
712 | 540 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 } | 603 } |
776 | 604 |
777 void CompositeEditCommand::deleteInsignificantText(const Position& start, const
Position& end) | 605 void CompositeEditCommand::deleteInsignificantText(const Position& start, const
Position& end) |
778 { | 606 { |
779 if (start.isNull() || end.isNull()) | 607 if (start.isNull() || end.isNull()) |
780 return; | 608 return; |
781 | 609 |
782 if (comparePositions(start, end) >= 0) | 610 if (comparePositions(start, end) >= 0) |
783 return; | 611 return; |
784 | 612 |
785 Vector<RefPtr<Text> > nodes; | 613 Node* next; |
786 for (Node* node = start.deprecatedNode(); node; node = node->traverseNextNod
e()) { | 614 for (Node* node = start.deprecatedNode(); node; node = next) { |
787 if (node->isTextNode()) | 615 next = node->traverseNextNode(); |
788 nodes.append(toText(node)); | 616 if (node->isTextNode()) { |
| 617 Text* textNode = static_cast<Text*>(node); |
| 618 int startOffset = node == start.deprecatedNode() ? start.deprecatedE
ditingOffset() : 0; |
| 619 int endOffset = node == end.deprecatedNode() ? end.deprecatedEditing
Offset() : static_cast<int>(textNode->length()); |
| 620 deleteInsignificantText(textNode, startOffset, endOffset); |
| 621 } |
789 if (node == end.deprecatedNode()) | 622 if (node == end.deprecatedNode()) |
790 break; | 623 break; |
791 } | 624 } |
792 | |
793 for (size_t i = 0; i < nodes.size(); ++i) { | |
794 Text* textNode = nodes[i].get(); | |
795 int startOffset = textNode == start.deprecatedNode() ? start.deprecatedE
ditingOffset() : 0; | |
796 int endOffset = textNode == end.deprecatedNode() ? end.deprecatedEditing
Offset() : static_cast<int>(textNode->length()); | |
797 deleteInsignificantText(textNode, startOffset, endOffset); | |
798 } | |
799 } | 625 } |
800 | 626 |
801 void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos
) | 627 void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos
) |
802 { | 628 { |
803 Position end = VisiblePosition(pos, VP_DEFAULT_AFFINITY).next().deepEquivale
nt().downstream(); | 629 Position end = VisiblePosition(pos, VP_DEFAULT_AFFINITY).next().deepEquivale
nt().downstream(); |
804 deleteInsignificantText(pos, end); | 630 deleteInsignificantText(pos, end); |
805 } | 631 } |
806 | 632 |
807 PassRefPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRefPtr<Element
> container) | 633 PassRefPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRefPtr<Element
> container) |
808 { | 634 { |
(...skipping 19 matching lines...) Expand all Loading... |
828 RefPtr<Node> placeholder = createBlockPlaceholderElement(document()); | 654 RefPtr<Node> placeholder = createBlockPlaceholderElement(document()); |
829 insertNodeAt(placeholder, pos); | 655 insertNodeAt(placeholder, pos); |
830 return placeholder.release(); | 656 return placeholder.release(); |
831 } | 657 } |
832 | 658 |
833 PassRefPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* cont
ainer) | 659 PassRefPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* cont
ainer) |
834 { | 660 { |
835 if (!container) | 661 if (!container) |
836 return 0; | 662 return 0; |
837 | 663 |
838 document()->updateLayoutIgnorePendingStylesheets(); | 664 updateLayout(); |
839 | 665 |
840 RenderObject* renderer = container->renderer(); | 666 RenderObject* renderer = container->renderer(); |
841 if (!renderer || !renderer->isBlockFlow()) | 667 if (!renderer || !renderer->isBlockFlow()) |
842 return 0; | 668 return 0; |
843 | 669 |
844 // append the placeholder to make sure it follows | 670 // append the placeholder to make sure it follows |
845 // any unrendered blocks | 671 // any unrendered blocks |
846 RenderBlock* block = toRenderBlock(renderer); | 672 RenderBlock* block = toRenderBlock(renderer); |
847 if (block->height() == 0 || (block->isListItem() && block->isEmpty())) | 673 if (block->height() == 0 || (block->isListItem() && block->isEmpty())) |
848 return appendBlockPlaceholder(container); | 674 return appendBlockPlaceholder(container); |
849 | 675 |
850 return 0; | 676 return 0; |
851 } | 677 } |
852 | 678 |
853 // Assumes that the position is at a placeholder and does the removal without mu
ch checking. | 679 // Assumes that the position is at a placeholder and does the removal without mu
ch checking. |
854 void CompositeEditCommand::removePlaceholderAt(const Position& p) | 680 void CompositeEditCommand::removePlaceholderAt(const Position& p) |
855 { | 681 { |
856 ASSERT(lineBreakExistsAtPosition(p)); | 682 ASSERT(lineBreakExistsAtPosition(p)); |
857 | 683 |
858 // We are certain that the position is at a line break, but it may be a br o
r a preserved newline. | 684 // We are certain that the position is at a line break, but it may be a br o
r a preserved newline. |
859 if (p.anchorNode()->hasTagName(brTag)) { | 685 if (p.anchorNode()->hasTagName(brTag)) { |
860 removeNode(p.anchorNode()); | 686 removeNode(p.anchorNode()); |
861 return; | 687 return; |
862 } | 688 } |
863 | 689 |
864 deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1); | 690 deleteTextFromNode(static_cast<Text*>(p.anchorNode()), p.offsetInContainerNo
de(), 1); |
865 } | 691 } |
866 | 692 |
867 PassRefPtr<Node> CompositeEditCommand::insertNewDefaultParagraphElementAt(const
Position& position) | 693 PassRefPtr<Node> CompositeEditCommand::insertNewDefaultParagraphElementAt(const
Position& position) |
868 { | 694 { |
869 RefPtr<Element> paragraphElement = createDefaultParagraphElement(document())
; | 695 RefPtr<Element> paragraphElement = createDefaultParagraphElement(document())
; |
870 ExceptionCode ec; | 696 ExceptionCode ec; |
871 paragraphElement->appendChild(createBreakElement(document()), ec); | 697 paragraphElement->appendChild(createBreakElement(document()), ec); |
872 insertNodeAt(paragraphElement, position); | 698 insertNodeAt(paragraphElement, position); |
873 return paragraphElement.release(); | 699 return paragraphElement.release(); |
874 } | 700 } |
875 | 701 |
876 // If the paragraph is not entirely within it's own block, create one and move t
he paragraph into | 702 // If the paragraph is not entirely within it's own block, create one and move t
he paragraph into |
877 // it, and return that block. Otherwise return 0. | 703 // it, and return that block. Otherwise return 0. |
878 PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessar
y(const Position& pos) | 704 PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessar
y(const Position& pos) |
879 { | 705 { |
880 if (pos.isNull()) | 706 if (pos.isNull()) |
881 return 0; | 707 return 0; |
882 | 708 |
883 document()->updateLayoutIgnorePendingStylesheets(); | 709 updateLayout(); |
884 | 710 |
885 // It's strange that this function is responsible for verifying that pos has
not been invalidated | 711 // It's strange that this function is responsible for verifying that pos has
not been invalidated |
886 // by an earlier call to this function. The caller, applyBlockStyle, should
do this. | 712 // by an earlier call to this function. The caller, applyBlockStyle, should
do this. |
887 VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY); | 713 VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY); |
888 VisiblePosition visibleParagraphStart(startOfParagraph(visiblePos)); | 714 VisiblePosition visibleParagraphStart(startOfParagraph(visiblePos)); |
889 VisiblePosition visibleParagraphEnd = endOfParagraph(visiblePos); | 715 VisiblePosition visibleParagraphEnd = endOfParagraph(visiblePos); |
890 VisiblePosition next = visibleParagraphEnd.next(); | 716 VisiblePosition next = visibleParagraphEnd.next(); |
891 VisiblePosition visibleEnd = next.isNotNull() ? next : visibleParagraphEnd; | 717 VisiblePosition visibleEnd = next.isNotNull() ? next : visibleParagraphEnd; |
892 | 718 |
893 Position upstreamStart = visibleParagraphStart.deepEquivalent().upstream(); | 719 Position upstreamStart = visibleParagraphStart.deepEquivalent().upstream(); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 removeNodeAndPruneAncestors(node); | 856 removeNodeAndPruneAncestors(node); |
1031 // If the selection to move was empty and in an empty block that | 857 // If the selection to move was empty and in an empty block that |
1032 // doesn't require a placeholder to prop itself open (like a bordered | 858 // doesn't require a placeholder to prop itself open (like a bordered |
1033 // div or an li), remove it during the move (the list removal code | 859 // div or an li), remove it during the move (the list removal code |
1034 // expects this behavior). | 860 // expects this behavior). |
1035 else if (isBlock(node)) | 861 else if (isBlock(node)) |
1036 removeNodeAndPruneAncestors(node); | 862 removeNodeAndPruneAncestors(node); |
1037 else if (lineBreakExistsAtPosition(position)) { | 863 else if (lineBreakExistsAtPosition(position)) { |
1038 // There is a preserved '\n' at caretAfterDelete. | 864 // There is a preserved '\n' at caretAfterDelete. |
1039 // We can safely assume this is a text node. | 865 // We can safely assume this is a text node. |
1040 Text* textNode = toText(node); | 866 Text* textNode = static_cast<Text*>(node); |
1041 if (textNode->length() == 1) | 867 if (textNode->length() == 1) |
1042 removeNodeAndPruneAncestors(node); | 868 removeNodeAndPruneAncestors(node); |
1043 else | 869 else |
1044 deleteTextFromNode(textNode, position.deprecatedEditingOffset(),
1); | 870 deleteTextFromNode(textNode, position.deprecatedEditingOffset(),
1); |
1045 } | 871 } |
1046 } | 872 } |
1047 } | 873 } |
1048 | 874 |
1049 // This is a version of moveParagraph that preserves style by keeping the origin
al markup | 875 // This is a version of moveParagraph that preserves style by keeping the origin
al markup |
1050 // It is currently used only by IndentOutdentCommand but it is meant to be used
in the | 876 // It is currently used only by IndentOutdentCommand but it is meant to be used
in the |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1183 // baz | 1009 // baz |
1184 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That
would | 1010 // Imagine moving 'bar' to ^. 'bar' will be deleted and its div pruned. That
would |
1185 // cause 'baz' to collapse onto the line with 'foobar' unless we insert a br
. | 1011 // cause 'baz' to collapse onto the line with 'foobar' unless we insert a br
. |
1186 // Must recononicalize these two VisiblePositions after the pruning above. | 1012 // Must recononicalize these two VisiblePositions after the pruning above. |
1187 beforeParagraph = VisiblePosition(beforeParagraph.deepEquivalent()); | 1013 beforeParagraph = VisiblePosition(beforeParagraph.deepEquivalent()); |
1188 afterParagraph = VisiblePosition(afterParagraph.deepEquivalent()); | 1014 afterParagraph = VisiblePosition(afterParagraph.deepEquivalent()); |
1189 if (beforeParagraph.isNotNull() && (!isEndOfParagraph(beforeParagraph) || be
foreParagraph == afterParagraph)) { | 1015 if (beforeParagraph.isNotNull() && (!isEndOfParagraph(beforeParagraph) || be
foreParagraph == afterParagraph)) { |
1190 // FIXME: Trim text between beforeParagraph and afterParagraph if they a
ren't equal. | 1016 // FIXME: Trim text between beforeParagraph and afterParagraph if they a
ren't equal. |
1191 insertNodeAt(createBreakElement(document()), beforeParagraph.deepEquival
ent()); | 1017 insertNodeAt(createBreakElement(document()), beforeParagraph.deepEquival
ent()); |
1192 // Need an updateLayout here in case inserting the br has split a text n
ode. | 1018 // Need an updateLayout here in case inserting the br has split a text n
ode. |
1193 document()->updateLayoutIgnorePendingStylesheets(); | 1019 updateLayout(); |
1194 } | 1020 } |
1195 | 1021 |
1196 RefPtr<Range> startToDestinationRange(Range::create(document(), firstPositio
nInNode(document()->documentElement()), destination.deepEquivalent().parentAncho
redEquivalent())); | 1022 RefPtr<Range> startToDestinationRange(Range::create(document(), firstPositio
nInNode(document()->documentElement()), destination.deepEquivalent().parentAncho
redEquivalent())); |
1197 destinationIndex = TextIterator::rangeLength(startToDestinationRange.get(),
true); | 1023 destinationIndex = TextIterator::rangeLength(startToDestinationRange.get(),
true); |
1198 | 1024 |
1199 setEndingSelection(VisibleSelection(destination, originalIsDirectional)); | 1025 setEndingSelection(VisibleSelection(destination, originalIsDirectional)); |
1200 ASSERT(endingSelection().isCaretOrRange()); | 1026 ASSERT(endingSelection().isCaretOrRange()); |
1201 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S
electReplacement | ReplaceSelectionCommand::MovingParagraph; | 1027 ReplaceSelectionCommand::CommandOptions options = ReplaceSelectionCommand::S
electReplacement | ReplaceSelectionCommand::MovingParagraph; |
1202 if (!preserveStyle) | 1028 if (!preserveStyle) |
1203 options |= ReplaceSelectionCommand::MatchStyle; | 1029 options |= ReplaceSelectionCommand::MatchStyle; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 return false; | 1149 return false; |
1324 | 1150 |
1325 Position caretPos(caret.deepEquivalent().downstream()); | 1151 Position caretPos(caret.deepEquivalent().downstream()); |
1326 // A line break is either a br or a preserved newline. | 1152 // A line break is either a br or a preserved newline. |
1327 ASSERT(caretPos.deprecatedNode()->hasTagName(brTag) || (caretPos.deprecatedN
ode()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveN
ewline())); | 1153 ASSERT(caretPos.deprecatedNode()->hasTagName(brTag) || (caretPos.deprecatedN
ode()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveN
ewline())); |
1328 | 1154 |
1329 if (caretPos.deprecatedNode()->hasTagName(brTag)) | 1155 if (caretPos.deprecatedNode()->hasTagName(brTag)) |
1330 removeNodeAndPruneAncestors(caretPos.deprecatedNode()); | 1156 removeNodeAndPruneAncestors(caretPos.deprecatedNode()); |
1331 else if (caretPos.deprecatedNode()->isTextNode()) { | 1157 else if (caretPos.deprecatedNode()->isTextNode()) { |
1332 ASSERT(caretPos.deprecatedEditingOffset() == 0); | 1158 ASSERT(caretPos.deprecatedEditingOffset() == 0); |
1333 Text* textNode = toText(caretPos.deprecatedNode()); | 1159 Text* textNode = static_cast<Text*>(caretPos.deprecatedNode()); |
1334 ContainerNode* parentNode = textNode->parentNode(); | 1160 ContainerNode* parentNode = textNode->parentNode(); |
1335 // The preserved newline must be the first thing in the node, since othe
rwise the previous | 1161 // The preserved newline must be the first thing in the node, since othe
rwise the previous |
1336 // paragraph would be quoted, and we verified that it wasn't above. | 1162 // paragraph would be quoted, and we verified that it wasn't above. |
1337 deleteTextFromNode(textNode, 0, 1); | 1163 deleteTextFromNode(textNode, 0, 1); |
1338 prune(parentNode); | 1164 prune(parentNode); |
1339 } | 1165 } |
1340 | 1166 |
1341 return true; | 1167 return true; |
1342 } | 1168 } |
1343 | 1169 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 return node.release(); | 1254 return node.release(); |
1429 } | 1255 } |
1430 | 1256 |
1431 PassRefPtr<Element> createBlockPlaceholderElement(Document* document) | 1257 PassRefPtr<Element> createBlockPlaceholderElement(Document* document) |
1432 { | 1258 { |
1433 RefPtr<Element> breakNode = document->createElement(brTag, false); | 1259 RefPtr<Element> breakNode = document->createElement(brTag, false); |
1434 return breakNode.release(); | 1260 return breakNode.release(); |
1435 } | 1261 } |
1436 | 1262 |
1437 } // namespace WebCore | 1263 } // namespace WebCore |
OLD | NEW |