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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 #include "core/rendering/RenderBlock.h" | 68 #include "core/rendering/RenderBlock.h" |
69 #include "core/rendering/RenderListItem.h" | 69 #include "core/rendering/RenderListItem.h" |
70 #include "core/rendering/RenderText.h" | 70 #include "core/rendering/RenderText.h" |
71 | 71 |
72 using namespace std; | 72 using namespace std; |
73 | 73 |
74 namespace WebCore { | 74 namespace WebCore { |
75 | 75 |
76 using namespace HTMLNames; | 76 using namespace HTMLNames; |
77 | 77 |
78 PassRefPtr<EditCommandComposition> EditCommandComposition::create(Document* docu
ment, | 78 PassRefPtrWillBeRawPtr<EditCommandComposition> EditCommandComposition::create(Do
cument* document, |
79 const VisibleSelection& startingSelection, const VisibleSelection& endingSel
ection, EditAction editAction) | 79 const VisibleSelection& startingSelection, const VisibleSelection& endingSel
ection, EditAction editAction) |
80 { | 80 { |
81 return adoptRef(new EditCommandComposition(document, startingSelection, endi
ngSelection, editAction)); | 81 return adoptRefWillBeNoop(new EditCommandComposition(document, startingSelec
tion, endingSelection, editAction)); |
82 } | 82 } |
83 | 83 |
84 EditCommandComposition::EditCommandComposition(Document* document, const Visible
Selection& startingSelection, const VisibleSelection& endingSelection, EditActio
n editAction) | 84 EditCommandComposition::EditCommandComposition(Document* document, const Visible
Selection& startingSelection, const VisibleSelection& endingSelection, EditActio
n editAction) |
85 : m_document(document) | 85 : m_document(document) |
86 , m_startingSelection(startingSelection) | 86 , m_startingSelection(startingSelection) |
87 , m_endingSelection(endingSelection) | 87 , m_endingSelection(endingSelection) |
88 , m_startingRootEditableElement(startingSelection.rootEditableElement()) | 88 , m_startingRootEditableElement(startingSelection.rootEditableElement()) |
89 , m_endingRootEditableElement(endingSelection.rootEditableElement()) | 89 , m_endingRootEditableElement(endingSelection.rootEditableElement()) |
90 , m_editAction(editAction) | 90 , m_editAction(editAction) |
91 { | 91 { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 m_startingSelection = selection; | 147 m_startingSelection = selection; |
148 m_startingRootEditableElement = selection.rootEditableElement(); | 148 m_startingRootEditableElement = selection.rootEditableElement(); |
149 } | 149 } |
150 | 150 |
151 void EditCommandComposition::setEndingSelection(const VisibleSelection& selectio
n) | 151 void EditCommandComposition::setEndingSelection(const VisibleSelection& selectio
n) |
152 { | 152 { |
153 m_endingSelection = selection; | 153 m_endingSelection = selection; |
154 m_endingRootEditableElement = selection.rootEditableElement(); | 154 m_endingRootEditableElement = selection.rootEditableElement(); |
155 } | 155 } |
156 | 156 |
| 157 void EditCommandComposition::trace(Visitor* visitor) |
| 158 { |
| 159 visitor->trace(m_document); |
| 160 visitor->trace(m_startingSelection); |
| 161 visitor->trace(m_endingSelection); |
| 162 visitor->trace(m_commands); |
| 163 visitor->trace(m_startingRootEditableElement); |
| 164 visitor->trace(m_endingRootEditableElement); |
| 165 UndoStep::trace(visitor); |
| 166 } |
| 167 |
157 CompositeEditCommand::CompositeEditCommand(Document& document) | 168 CompositeEditCommand::CompositeEditCommand(Document& document) |
158 : EditCommand(document) | 169 : EditCommand(document) |
159 { | 170 { |
160 } | 171 } |
161 | 172 |
162 CompositeEditCommand::~CompositeEditCommand() | 173 CompositeEditCommand::~CompositeEditCommand() |
163 { | 174 { |
164 ASSERT(isTopLevelCommand() || !m_composition); | 175 ASSERT(isTopLevelCommand() || !m_composition); |
165 } | 176 } |
166 | 177 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 return false; | 232 return false; |
222 } | 233 } |
223 | 234 |
224 void CompositeEditCommand::setShouldRetainAutocorrectionIndicator(bool) | 235 void CompositeEditCommand::setShouldRetainAutocorrectionIndicator(bool) |
225 { | 236 { |
226 } | 237 } |
227 | 238 |
228 // | 239 // |
229 // sugary-sweet convenience functions to help create and apply edit commands in
composite commands | 240 // sugary-sweet convenience functions to help create and apply edit commands in
composite commands |
230 // | 241 // |
231 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> prpCo
mmand) | 242 void CompositeEditCommand::applyCommandToComposite(PassRefPtrWillBeRawPtr<EditCo
mmand> prpCommand) |
232 { | 243 { |
233 RefPtr<EditCommand> command = prpCommand; | 244 RefPtrWillBeRawPtr<EditCommand> command = prpCommand; |
234 command->setParent(this); | 245 command->setParent(this); |
235 command->doApply(); | 246 command->doApply(); |
236 if (command->isSimpleEditCommand()) { | 247 if (command->isSimpleEditCommand()) { |
237 command->setParent(0); | 248 command->setParent(0); |
238 ensureComposition()->append(toSimpleEditCommand(command.get())); | 249 ensureComposition()->append(toSimpleEditCommand(command.get())); |
239 } | 250 } |
240 m_commands.append(command.release()); | 251 m_commands.append(command.release()); |
241 } | 252 } |
242 | 253 |
243 void CompositeEditCommand::applyCommandToComposite(PassRefPtr<CompositeEditComma
nd> command, const VisibleSelection& selection) | 254 void CompositeEditCommand::applyCommandToComposite(PassRefPtrWillBeRawPtr<Compos
iteEditCommand> command, const VisibleSelection& selection) |
244 { | 255 { |
245 command->setParent(this); | 256 command->setParent(this); |
246 if (selection != command->endingSelection()) { | 257 if (selection != command->endingSelection()) { |
247 command->setStartingSelection(selection); | 258 command->setStartingSelection(selection); |
248 command->setEndingSelection(selection); | 259 command->setEndingSelection(selection); |
249 } | 260 } |
250 command->doApply(); | 261 command->doApply(); |
251 m_commands.append(command); | 262 m_commands.append(command); |
252 } | 263 } |
253 | 264 |
254 void CompositeEditCommand::applyStyle(const EditingStyle* style, EditAction edit
ingAction) | 265 void CompositeEditCommand::applyStyle(const EditingStyle* style, EditAction edit
ingAction) |
255 { | 266 { |
256 applyCommandToComposite(ApplyStyleCommand::create(document(), style, editing
Action)); | 267 applyCommandToComposite(ApplyStyleCommand::create(document(), style, editing
Action)); |
257 } | 268 } |
258 | 269 |
259 void CompositeEditCommand::applyStyle(const EditingStyle* style, const Position&
start, const Position& end, EditAction editingAction) | 270 void CompositeEditCommand::applyStyle(const EditingStyle* style, const Position&
start, const Position& end, EditAction editingAction) |
260 { | 271 { |
261 applyCommandToComposite(ApplyStyleCommand::create(document(), style, start,
end, editingAction)); | 272 applyCommandToComposite(ApplyStyleCommand::create(document(), style, start,
end, editingAction)); |
262 } | 273 } |
263 | 274 |
264 void CompositeEditCommand::applyStyledElement(PassRefPtr<Element> element) | 275 void CompositeEditCommand::applyStyledElement(PassRefPtrWillBeRawPtr<Element> el
ement) |
265 { | 276 { |
266 applyCommandToComposite(ApplyStyleCommand::create(element, false)); | 277 applyCommandToComposite(ApplyStyleCommand::create(element, false)); |
267 } | 278 } |
268 | 279 |
269 void CompositeEditCommand::removeStyledElement(PassRefPtr<Element> element) | 280 void CompositeEditCommand::removeStyledElement(PassRefPtrWillBeRawPtr<Element> e
lement) |
270 { | 281 { |
271 applyCommandToComposite(ApplyStyleCommand::create(element, true)); | 282 applyCommandToComposite(ApplyStyleCommand::create(element, true)); |
272 } | 283 } |
273 | 284 |
274 void CompositeEditCommand::insertParagraphSeparator(bool useDefaultParagraphElem
ent, bool pasteBlockqutoeIntoUnquotedArea) | 285 void CompositeEditCommand::insertParagraphSeparator(bool useDefaultParagraphElem
ent, bool pasteBlockqutoeIntoUnquotedArea) |
275 { | 286 { |
276 applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(),
useDefaultParagraphElement, pasteBlockqutoeIntoUnquotedArea)); | 287 applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(),
useDefaultParagraphElement, pasteBlockqutoeIntoUnquotedArea)); |
277 } | 288 } |
278 | 289 |
279 bool CompositeEditCommand::isRemovableBlock(const Node* node) | 290 bool CompositeEditCommand::isRemovableBlock(const Node* node) |
280 { | 291 { |
281 ASSERT(node); | 292 ASSERT(node); |
282 if (!isHTMLDivElement(*node)) | 293 if (!isHTMLDivElement(*node)) |
283 return false; | 294 return false; |
284 | 295 |
285 Node* parentNode = node->parentNode(); | 296 Node* parentNode = node->parentNode(); |
286 if (parentNode && parentNode->firstChild() != parentNode->lastChild()) | 297 if (parentNode && parentNode->firstChild() != parentNode->lastChild()) |
287 return false; | 298 return false; |
288 | 299 |
289 if (!toElement(node)->hasAttributes()) | 300 if (!toElement(node)->hasAttributes()) |
290 return true; | 301 return true; |
291 | 302 |
292 return false; | 303 return false; |
293 } | 304 } |
294 | 305 |
295 void CompositeEditCommand::insertNodeBefore(PassRefPtr<Node> insertChild, PassRe
fPtr<Node> refChild, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAl
waysEditable) | 306 void CompositeEditCommand::insertNodeBefore(PassRefPtrWillBeRawPtr<Node> insertC
hild, PassRefPtrWillBeRawPtr<Node> refChild, ShouldAssumeContentIsAlwaysEditable
shouldAssumeContentIsAlwaysEditable) |
296 { | 307 { |
297 ASSERT(!isHTMLBodyElement(*refChild)); | 308 ASSERT(!isHTMLBodyElement(*refChild)); |
298 applyCommandToComposite(InsertNodeBeforeCommand::create(insertChild, refChil
d, shouldAssumeContentIsAlwaysEditable)); | 309 applyCommandToComposite(InsertNodeBeforeCommand::create(insertChild, refChil
d, shouldAssumeContentIsAlwaysEditable)); |
299 } | 310 } |
300 | 311 |
301 void CompositeEditCommand::insertNodeAfter(PassRefPtr<Node> insertChild, PassRef
Ptr<Node> refChild) | 312 void CompositeEditCommand::insertNodeAfter(PassRefPtrWillBeRawPtr<Node> insertCh
ild, PassRefPtrWillBeRawPtr<Node> refChild) |
302 { | 313 { |
303 ASSERT(insertChild); | 314 ASSERT(insertChild); |
304 ASSERT(refChild); | 315 ASSERT(refChild); |
305 ASSERT(!isHTMLBodyElement(*refChild)); | 316 ASSERT(!isHTMLBodyElement(*refChild)); |
306 ContainerNode* parent = refChild->parentNode(); | 317 ContainerNode* parent = refChild->parentNode(); |
307 ASSERT(parent); | 318 ASSERT(parent); |
308 ASSERT(!parent->isShadowRoot()); | 319 ASSERT(!parent->isShadowRoot()); |
309 if (parent->lastChild() == refChild) | 320 if (parent->lastChild() == refChild) |
310 appendNode(insertChild, parent); | 321 appendNode(insertChild, parent); |
311 else { | 322 else { |
312 ASSERT(refChild->nextSibling()); | 323 ASSERT(refChild->nextSibling()); |
313 insertNodeBefore(insertChild, refChild->nextSibling()); | 324 insertNodeBefore(insertChild, refChild->nextSibling()); |
314 } | 325 } |
315 } | 326 } |
316 | 327 |
317 void CompositeEditCommand::insertNodeAt(PassRefPtr<Node> insertChild, const Posi
tion& editingPosition) | 328 void CompositeEditCommand::insertNodeAt(PassRefPtrWillBeRawPtr<Node> insertChild
, const Position& editingPosition) |
318 { | 329 { |
319 ASSERT(isEditablePosition(editingPosition, ContentIsEditable, DoNotUpdateSty
le)); | 330 ASSERT(isEditablePosition(editingPosition, ContentIsEditable, DoNotUpdateSty
le)); |
320 // For editing positions like [table, 0], insert before the table, | 331 // For editing positions like [table, 0], insert before the table, |
321 // likewise for replaced elements, brs, etc. | 332 // likewise for replaced elements, brs, etc. |
322 Position p = editingPosition.parentAnchoredEquivalent(); | 333 Position p = editingPosition.parentAnchoredEquivalent(); |
323 Node* refChild = p.deprecatedNode(); | 334 Node* refChild = p.deprecatedNode(); |
324 int offset = p.deprecatedEditingOffset(); | 335 int offset = p.deprecatedEditingOffset(); |
325 | 336 |
326 if (canHaveChildrenForEditing(refChild)) { | 337 if (canHaveChildrenForEditing(refChild)) { |
327 Node* child = refChild->firstChild(); | 338 Node* child = refChild->firstChild(); |
328 for (int i = 0; child && i < offset; i++) | 339 for (int i = 0; child && i < offset; i++) |
329 child = child->nextSibling(); | 340 child = child->nextSibling(); |
330 if (child) | 341 if (child) |
331 insertNodeBefore(insertChild, child); | 342 insertNodeBefore(insertChild, child); |
332 else | 343 else |
333 appendNode(insertChild, toContainerNode(refChild)); | 344 appendNode(insertChild, toContainerNode(refChild)); |
334 } else if (caretMinOffset(refChild) >= offset) | 345 } else if (caretMinOffset(refChild) >= offset) |
335 insertNodeBefore(insertChild, refChild); | 346 insertNodeBefore(insertChild, refChild); |
336 else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) { | 347 else if (refChild->isTextNode() && caretMaxOffset(refChild) > offset) { |
337 splitTextNode(toText(refChild), offset); | 348 splitTextNode(toText(refChild), offset); |
338 | 349 |
339 // Mutation events (bug 22634) from the text node insertion may have rem
oved the refChild | 350 // Mutation events (bug 22634) from the text node insertion may have rem
oved the refChild |
340 if (!refChild->inDocument()) | 351 if (!refChild->inDocument()) |
341 return; | 352 return; |
342 insertNodeBefore(insertChild, refChild); | 353 insertNodeBefore(insertChild, refChild); |
343 } else | 354 } else |
344 insertNodeAfter(insertChild, refChild); | 355 insertNodeAfter(insertChild, refChild); |
345 } | 356 } |
346 | 357 |
347 void CompositeEditCommand::appendNode(PassRefPtr<Node> node, PassRefPtr<Containe
rNode> parent) | 358 void CompositeEditCommand::appendNode(PassRefPtrWillBeRawPtr<Node> node, PassRef
PtrWillBeRawPtr<ContainerNode> parent) |
348 { | 359 { |
349 ASSERT(canHaveChildrenForEditing(parent.get())); | 360 ASSERT(canHaveChildrenForEditing(parent.get())); |
350 applyCommandToComposite(AppendNodeCommand::create(parent, node)); | 361 applyCommandToComposite(AppendNodeCommand::create(parent, node)); |
351 } | 362 } |
352 | 363 |
353 void CompositeEditCommand::removeChildrenInRange(PassRefPtr<Node> node, unsigned
from, unsigned to) | 364 void CompositeEditCommand::removeChildrenInRange(PassRefPtrWillBeRawPtr<Node> no
de, unsigned from, unsigned to) |
354 { | 365 { |
355 Vector<RefPtr<Node> > children; | 366 WillBeHeapVector<RefPtrWillBeMember<Node> > children; |
356 Node* child = node->traverseToChildAt(from); | 367 Node* child = node->traverseToChildAt(from); |
357 for (unsigned i = from; child && i < to; i++, child = child->nextSibling()) | 368 for (unsigned i = from; child && i < to; i++, child = child->nextSibling()) |
358 children.append(child); | 369 children.append(child); |
359 | 370 |
360 size_t size = children.size(); | 371 size_t size = children.size(); |
361 for (size_t i = 0; i < size; ++i) | 372 for (size_t i = 0; i < size; ++i) |
362 removeNode(children[i].release()); | 373 removeNode(children[i].release()); |
363 } | 374 } |
364 | 375 |
365 void CompositeEditCommand::removeNode(PassRefPtr<Node> node, ShouldAssumeContent
IsAlwaysEditable shouldAssumeContentIsAlwaysEditable) | 376 void CompositeEditCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, ShouldA
ssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable) |
366 { | 377 { |
367 if (!node || !node->nonShadowBoundaryParentNode()) | 378 if (!node || !node->nonShadowBoundaryParentNode()) |
368 return; | 379 return; |
369 applyCommandToComposite(RemoveNodeCommand::create(node, shouldAssumeContentI
sAlwaysEditable)); | 380 applyCommandToComposite(RemoveNodeCommand::create(node, shouldAssumeContentI
sAlwaysEditable)); |
370 } | 381 } |
371 | 382 |
372 void CompositeEditCommand::removeNodePreservingChildren(PassRefPtr<Node> node, S
houldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable) | 383 void CompositeEditCommand::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<N
ode> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditab
le) |
373 { | 384 { |
374 applyCommandToComposite(RemoveNodePreservingChildrenCommand::create(node, sh
ouldAssumeContentIsAlwaysEditable)); | 385 applyCommandToComposite(RemoveNodePreservingChildrenCommand::create(node, sh
ouldAssumeContentIsAlwaysEditable)); |
375 } | 386 } |
376 | 387 |
377 void CompositeEditCommand::removeNodeAndPruneAncestors(PassRefPtr<Node> node, No
de* excludeNode) | 388 void CompositeEditCommand::removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<No
de> node, Node* excludeNode) |
378 { | 389 { |
379 ASSERT(node.get() != excludeNode); | 390 ASSERT(node.get() != excludeNode); |
380 RefPtr<ContainerNode> parent = node->parentNode(); | 391 RefPtrWillBeRawPtr<ContainerNode> parent = node->parentNode(); |
381 removeNode(node); | 392 removeNode(node); |
382 prune(parent.release(), excludeNode); | 393 prune(parent.release(), excludeNode); |
383 } | 394 } |
384 | 395 |
385 void CompositeEditCommand::moveRemainingSiblingsToNewParent(Node* node, Node* pa
stLastNodeToMove, PassRefPtr<Element> prpNewParent) | 396 void CompositeEditCommand::moveRemainingSiblingsToNewParent(Node* node, Node* pa
stLastNodeToMove, PassRefPtrWillBeRawPtr<Element> prpNewParent) |
386 { | 397 { |
387 NodeVector nodesToRemove; | 398 NodeVector nodesToRemove; |
388 RefPtr<Element> newParent = prpNewParent; | 399 RefPtrWillBeRawPtr<Element> newParent = prpNewParent; |
389 | 400 |
390 for (; node && node != pastLastNodeToMove; node = node->nextSibling()) | 401 for (; node && node != pastLastNodeToMove; node = node->nextSibling()) |
391 nodesToRemove.append(node); | 402 nodesToRemove.append(node); |
392 | 403 |
393 for (unsigned i = 0; i < nodesToRemove.size(); i++) { | 404 for (unsigned i = 0; i < nodesToRemove.size(); i++) { |
394 removeNode(nodesToRemove[i]); | 405 removeNode(nodesToRemove[i]); |
395 appendNode(nodesToRemove[i], newParent); | 406 appendNode(nodesToRemove[i], newParent); |
396 } | 407 } |
397 } | 408 } |
398 | 409 |
399 void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Positi
on& position, Node& node) | 410 void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Positi
on& position, Node& node) |
400 { | 411 { |
401 int offset = (position.anchorType() == Position::PositionIsOffsetInAnchor) ?
position.offsetInContainerNode() : 0; | 412 int offset = (position.anchorType() == Position::PositionIsOffsetInAnchor) ?
position.offsetInContainerNode() : 0; |
402 updatePositionForNodeRemoval(position, node); | 413 updatePositionForNodeRemoval(position, node); |
403 if (offset) | 414 if (offset) |
404 position.moveToOffset(offset); | 415 position.moveToOffset(offset); |
405 } | 416 } |
406 | 417 |
407 HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAt
tributes(PassRefPtrWillBeRawPtr<HTMLElement> node) | 418 HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAt
tributes(PassRefPtrWillBeRawPtr<HTMLElement> node) |
408 { | 419 { |
409 // It would also be possible to implement all of ReplaceNodeWithSpanCommand | 420 // It would also be possible to implement all of ReplaceNodeWithSpanCommand |
410 // as a series of existing smaller edit commands. Someone who wanted to | 421 // as a series of existing smaller edit commands. Someone who wanted to |
411 // reduce the number of edit commands could do so here. | 422 // reduce the number of edit commands could do so here. |
412 RefPtr<ReplaceNodeWithSpanCommand> command = ReplaceNodeWithSpanCommand::cre
ate(node); | 423 RefPtrWillBeRawPtr<ReplaceNodeWithSpanCommand> command = ReplaceNodeWithSpan
Command::create(node); |
413 applyCommandToComposite(command); | 424 applyCommandToComposite(command); |
414 // Returning a raw pointer here is OK because the command is retained by | 425 // Returning a raw pointer here is OK because the command is retained by |
415 // applyCommandToComposite (thus retaining the span), and the span is also | 426 // applyCommandToComposite (thus retaining the span), and the span is also |
416 // in the DOM tree, and thus alive whie it has a parent. | 427 // in the DOM tree, and thus alive whie it has a parent. |
417 ASSERT(command->spanElement()->inDocument()); | 428 ASSERT(command->spanElement()->inDocument()); |
418 return command->spanElement(); | 429 return command->spanElement(); |
419 } | 430 } |
420 | 431 |
421 void CompositeEditCommand::prune(PassRefPtr<Node> node, Node* excludeNode) | 432 void CompositeEditCommand::prune(PassRefPtrWillBeRawPtr<Node> node, Node* exclud
eNode) |
422 { | 433 { |
423 if (RefPtr<Node> highestNodeToRemove = highestNodeToRemoveInPruning(node.get
(), excludeNode)) | 434 if (RefPtrWillBeRawPtr<Node> highestNodeToRemove = highestNodeToRemoveInPrun
ing(node.get(), excludeNode)) |
424 removeNode(highestNodeToRemove.release()); | 435 removeNode(highestNodeToRemove.release()); |
425 } | 436 } |
426 | 437 |
427 void CompositeEditCommand::splitTextNode(PassRefPtrWillBeRawPtr<Text> node, unsi
gned offset) | 438 void CompositeEditCommand::splitTextNode(PassRefPtrWillBeRawPtr<Text> node, unsi
gned offset) |
428 { | 439 { |
429 applyCommandToComposite(SplitTextNodeCommand::create(node, offset)); | 440 applyCommandToComposite(SplitTextNodeCommand::create(node, offset)); |
430 } | 441 } |
431 | 442 |
432 void CompositeEditCommand::splitElement(PassRefPtr<Element> element, PassRefPtr<
Node> atChild) | 443 void CompositeEditCommand::splitElement(PassRefPtrWillBeRawPtr<Element> element,
PassRefPtrWillBeRawPtr<Node> atChild) |
433 { | 444 { |
434 applyCommandToComposite(SplitElementCommand::create(element, atChild)); | 445 applyCommandToComposite(SplitElementCommand::create(element, atChild)); |
435 } | 446 } |
436 | 447 |
437 void CompositeEditCommand::mergeIdenticalElements(PassRefPtr<Element> prpFirst,
PassRefPtr<Element> prpSecond) | 448 void CompositeEditCommand::mergeIdenticalElements(PassRefPtrWillBeRawPtr<Element
> prpFirst, PassRefPtrWillBeRawPtr<Element> prpSecond) |
438 { | 449 { |
439 RefPtr<Element> first = prpFirst; | 450 RefPtrWillBeRawPtr<Element> first = prpFirst; |
440 RefPtr<Element> second = prpSecond; | 451 RefPtrWillBeRawPtr<Element> second = prpSecond; |
441 ASSERT(!first->isDescendantOf(second.get()) && second != first); | 452 ASSERT(!first->isDescendantOf(second.get()) && second != first); |
442 if (first->nextSibling() != second) { | 453 if (first->nextSibling() != second) { |
443 removeNode(second); | 454 removeNode(second); |
444 insertNodeAfter(second, first); | 455 insertNodeAfter(second, first); |
445 } | 456 } |
446 applyCommandToComposite(MergeIdenticalElementsCommand::create(first, second)
); | 457 applyCommandToComposite(MergeIdenticalElementsCommand::create(first, second)
); |
447 } | 458 } |
448 | 459 |
449 void CompositeEditCommand::wrapContentsInDummySpan(PassRefPtr<Element> element) | 460 void CompositeEditCommand::wrapContentsInDummySpan(PassRefPtrWillBeRawPtr<Elemen
t> element) |
450 { | 461 { |
451 applyCommandToComposite(WrapContentsInDummySpanCommand::create(element)); | 462 applyCommandToComposite(WrapContentsInDummySpanCommand::create(element)); |
452 } | 463 } |
453 | 464 |
454 void CompositeEditCommand::splitTextNodeContainingElement(PassRefPtrWillBeRawPtr
<Text> text, unsigned offset) | 465 void CompositeEditCommand::splitTextNodeContainingElement(PassRefPtrWillBeRawPtr
<Text> text, unsigned offset) |
455 { | 466 { |
456 applyCommandToComposite(SplitTextNodeContainingElementCommand::create(text,
offset)); | 467 applyCommandToComposite(SplitTextNodeContainingElementCommand::create(text,
offset)); |
457 } | 468 } |
458 | 469 |
459 void CompositeEditCommand::insertTextIntoNode(PassRefPtrWillBeRawPtr<Text> node,
unsigned offset, const String& text) | 470 void CompositeEditCommand::insertTextIntoNode(PassRefPtrWillBeRawPtr<Text> node,
unsigned offset, const String& text) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
532 if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode())) | 543 if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode())) |
533 return positionInParentBeforeNode(*tabSpan); | 544 return positionInParentBeforeNode(*tabSpan); |
534 | 545 |
535 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode())) | 546 if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode())) |
536 return positionInParentAfterNode(*tabSpan); | 547 return positionInParentAfterNode(*tabSpan); |
537 | 548 |
538 splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInCont
ainerNode()); | 549 splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInCont
ainerNode()); |
539 return positionInParentBeforeNode(*tabSpan); | 550 return positionInParentBeforeNode(*tabSpan); |
540 } | 551 } |
541 | 552 |
542 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, co
nst Position& pos) | 553 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtrWillBeRawPtr<No
de> node, const Position& pos) |
543 { | 554 { |
544 // insert node before, after, or at split of tab span | 555 // insert node before, after, or at split of tab span |
545 insertNodeAt(node, positionOutsideTabSpan(pos)); | 556 insertNodeAt(node, positionOutsideTabSpan(pos)); |
546 } | 557 } |
547 | 558 |
548 void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAft
erDelete, bool expandForSpecialElements, bool sanitizeMarkup) | 559 void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAft
erDelete, bool expandForSpecialElements, bool sanitizeMarkup) |
549 { | 560 { |
550 if (endingSelection().isRange()) | 561 if (endingSelection().isRange()) |
551 applyCommandToComposite(DeleteSelectionCommand::create(document(), smart
Delete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup)); | 562 applyCommandToComposite(DeleteSelectionCommand::create(document(), smart
Delete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup)); |
552 } | 563 } |
553 | 564 |
554 void CompositeEditCommand::deleteSelection(const VisibleSelection &selection, bo
ol smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool
sanitizeMarkup) | 565 void CompositeEditCommand::deleteSelection(const VisibleSelection &selection, bo
ol smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool
sanitizeMarkup) |
555 { | 566 { |
556 if (selection.isRange()) | 567 if (selection.isRange()) |
557 applyCommandToComposite(DeleteSelectionCommand::create(selection, smartD
elete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup)); | 568 applyCommandToComposite(DeleteSelectionCommand::create(selection, smartD
elete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup)); |
558 } | 569 } |
559 | 570 |
560 void CompositeEditCommand::removeCSSProperty(PassRefPtr<Element> element, CSSPro
pertyID property) | 571 void CompositeEditCommand::removeCSSProperty(PassRefPtrWillBeRawPtr<Element> ele
ment, CSSPropertyID property) |
561 { | 572 { |
562 applyCommandToComposite(RemoveCSSPropertyCommand::create(document(), element
, property)); | 573 applyCommandToComposite(RemoveCSSPropertyCommand::create(document(), element
, property)); |
563 } | 574 } |
564 | 575 |
565 void CompositeEditCommand::removeNodeAttribute(PassRefPtr<Element> element, cons
t QualifiedName& attribute) | 576 void CompositeEditCommand::removeNodeAttribute(PassRefPtrWillBeRawPtr<Element> e
lement, const QualifiedName& attribute) |
566 { | 577 { |
567 setNodeAttribute(element, attribute, AtomicString()); | 578 setNodeAttribute(element, attribute, AtomicString()); |
568 } | 579 } |
569 | 580 |
570 void CompositeEditCommand::setNodeAttribute(PassRefPtr<Element> element, const Q
ualifiedName& attribute, const AtomicString& value) | 581 void CompositeEditCommand::setNodeAttribute(PassRefPtrWillBeRawPtr<Element> elem
ent, const QualifiedName& attribute, const AtomicString& value) |
571 { | 582 { |
572 applyCommandToComposite(SetNodeAttributeCommand::create(element, attribute,
value)); | 583 applyCommandToComposite(SetNodeAttributeCommand::create(element, attribute,
value)); |
573 } | 584 } |
574 | 585 |
575 static inline bool containsOnlyWhitespace(const String& text) | 586 static inline bool containsOnlyWhitespace(const String& text) |
576 { | 587 { |
577 for (unsigned i = 0; i < text.length(); ++i) { | 588 for (unsigned i = 0; i < text.length(); ++i) { |
578 if (!isWhitespace(text[i])) | 589 if (!isWhitespace(text[i])) |
579 return false; | 590 return false; |
580 } | 591 } |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 deleteInsignificantText(textNode, startOffset, endOffset); | 816 deleteInsignificantText(textNode, startOffset, endOffset); |
806 } | 817 } |
807 } | 818 } |
808 | 819 |
809 void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos
) | 820 void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos
) |
810 { | 821 { |
811 Position end = VisiblePosition(pos, VP_DEFAULT_AFFINITY).next().deepEquivale
nt().downstream(); | 822 Position end = VisiblePosition(pos, VP_DEFAULT_AFFINITY).next().deepEquivale
nt().downstream(); |
812 deleteInsignificantText(pos, end); | 823 deleteInsignificantText(pos, end); |
813 } | 824 } |
814 | 825 |
815 PassRefPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRefPtr<Element
> container) | 826 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRe
fPtrWillBeRawPtr<Element> container) |
816 { | 827 { |
817 if (!container) | 828 if (!container) |
818 return nullptr; | 829 return nullptr; |
819 | 830 |
820 document().updateLayoutIgnorePendingStylesheets(); | 831 document().updateLayoutIgnorePendingStylesheets(); |
821 | 832 |
822 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. | 833 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. |
823 ASSERT(container->renderer()); | 834 ASSERT(container->renderer()); |
824 | 835 |
825 RefPtr<Node> placeholder = createBlockPlaceholderElement(document()); | 836 RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(documen
t()); |
826 appendNode(placeholder, container); | 837 appendNode(placeholder, container); |
827 return placeholder.release(); | 838 return placeholder.release(); |
828 } | 839 } |
829 | 840 |
830 PassRefPtr<Node> CompositeEditCommand::insertBlockPlaceholder(const Position& po
s) | 841 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::insertBlockPlaceholder(const
Position& pos) |
831 { | 842 { |
832 if (pos.isNull()) | 843 if (pos.isNull()) |
833 return nullptr; | 844 return nullptr; |
834 | 845 |
835 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. | 846 // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. S
ee 4244964. |
836 ASSERT(pos.deprecatedNode()->renderer()); | 847 ASSERT(pos.deprecatedNode()->renderer()); |
837 | 848 |
838 RefPtr<Node> placeholder = createBlockPlaceholderElement(document()); | 849 RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(documen
t()); |
839 insertNodeAt(placeholder, pos); | 850 insertNodeAt(placeholder, pos); |
840 return placeholder.release(); | 851 return placeholder.release(); |
841 } | 852 } |
842 | 853 |
843 PassRefPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* cont
ainer) | 854 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(E
lement* container) |
844 { | 855 { |
845 if (!container) | 856 if (!container) |
846 return nullptr; | 857 return nullptr; |
847 | 858 |
848 document().updateLayoutIgnorePendingStylesheets(); | 859 document().updateLayoutIgnorePendingStylesheets(); |
849 | 860 |
850 RenderObject* renderer = container->renderer(); | 861 RenderObject* renderer = container->renderer(); |
851 if (!renderer || !renderer->isRenderBlockFlow()) | 862 if (!renderer || !renderer->isRenderBlockFlow()) |
852 return nullptr; | 863 return nullptr; |
853 | 864 |
(...skipping 13 matching lines...) Expand all Loading... |
867 | 878 |
868 // We are certain that the position is at a line break, but it may be a br o
r a preserved newline. | 879 // We are certain that the position is at a line break, but it may be a br o
r a preserved newline. |
869 if (isHTMLBRElement(*p.anchorNode())) { | 880 if (isHTMLBRElement(*p.anchorNode())) { |
870 removeNode(p.anchorNode()); | 881 removeNode(p.anchorNode()); |
871 return; | 882 return; |
872 } | 883 } |
873 | 884 |
874 deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1); | 885 deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1); |
875 } | 886 } |
876 | 887 |
877 PassRefPtr<Node> CompositeEditCommand::insertNewDefaultParagraphElementAt(const
Position& position) | 888 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::insertNewDefaultParagraphElem
entAt(const Position& position) |
878 { | 889 { |
879 RefPtr<Element> paragraphElement = createDefaultParagraphElement(document())
; | 890 RefPtrWillBeRawPtr<Element> paragraphElement = createDefaultParagraphElement
(document()); |
880 paragraphElement->appendChild(createBreakElement(document())); | 891 paragraphElement->appendChild(createBreakElement(document())); |
881 insertNodeAt(paragraphElement, position); | 892 insertNodeAt(paragraphElement, position); |
882 return paragraphElement.release(); | 893 return paragraphElement.release(); |
883 } | 894 } |
884 | 895 |
885 // If the paragraph is not entirely within it's own block, create one and move t
he paragraph into | 896 // If the paragraph is not entirely within it's own block, create one and move t
he paragraph into |
886 // it, and return that block. Otherwise return 0. | 897 // it, and return that block. Otherwise return 0. |
887 PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessar
y(const Position& pos) | 898 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlo
ckIfNecessary(const Position& pos) |
888 { | 899 { |
889 if (pos.isNull()) | 900 if (pos.isNull()) |
890 return nullptr; | 901 return nullptr; |
891 | 902 |
892 document().updateLayoutIgnorePendingStylesheets(); | 903 document().updateLayoutIgnorePendingStylesheets(); |
893 | 904 |
894 // It's strange that this function is responsible for verifying that pos has
not been invalidated | 905 // It's strange that this function is responsible for verifying that pos has
not been invalidated |
895 // by an earlier call to this function. The caller, applyBlockStyle, should
do this. | 906 // by an earlier call to this function. The caller, applyBlockStyle, should
do this. |
896 VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY); | 907 VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY); |
897 VisiblePosition visibleParagraphStart(startOfParagraph(visiblePos)); | 908 VisiblePosition visibleParagraphStart(startOfParagraph(visiblePos)); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 return nullptr; | 940 return nullptr; |
930 } else if (isEndOfEditableOrNonEditableContent(visibleEnd)) { | 941 } else if (isEndOfEditableOrNonEditableContent(visibleEnd)) { |
931 // At the end of the editable region. We can bail here as well. | 942 // At the end of the editable region. We can bail here as well. |
932 return nullptr; | 943 return nullptr; |
933 } | 944 } |
934 } | 945 } |
935 | 946 |
936 if (visibleParagraphEnd.isNull()) | 947 if (visibleParagraphEnd.isNull()) |
937 return nullptr; | 948 return nullptr; |
938 | 949 |
939 RefPtr<Node> newBlock = insertNewDefaultParagraphElementAt(upstreamStart); | 950 RefPtrWillBeRawPtr<Node> newBlock = insertNewDefaultParagraphElementAt(upstr
eamStart); |
940 | 951 |
941 bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().deprec
atedNode()); | 952 bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().deprec
atedNode()); |
942 | 953 |
943 moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(f
irstPositionInNode(newBlock.get()))); | 954 moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(f
irstPositionInNode(newBlock.get()))); |
944 | 955 |
945 if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) && !end
WasBr) | 956 if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) && !end
WasBr) |
946 removeNode(newBlock->lastChild()); | 957 removeNode(newBlock->lastChild()); |
947 | 958 |
948 return newBlock.release(); | 959 return newBlock.release(); |
949 } | 960 } |
(...skipping 15 matching lines...) Expand all Loading... |
965 // Clone the paragraph between start and end under blockElement, | 976 // Clone the paragraph between start and end under blockElement, |
966 // preserving the hierarchy up to outerNode. | 977 // preserving the hierarchy up to outerNode. |
967 | 978 |
968 void CompositeEditCommand::cloneParagraphUnderNewElement(const Position& start,
const Position& end, Node* passedOuterNode, Element* blockElement) | 979 void CompositeEditCommand::cloneParagraphUnderNewElement(const Position& start,
const Position& end, Node* passedOuterNode, Element* blockElement) |
969 { | 980 { |
970 ASSERT(comparePositions(start, end) <= 0); | 981 ASSERT(comparePositions(start, end) <= 0); |
971 ASSERT(passedOuterNode); | 982 ASSERT(passedOuterNode); |
972 ASSERT(blockElement); | 983 ASSERT(blockElement); |
973 | 984 |
974 // First we clone the outerNode | 985 // First we clone the outerNode |
975 RefPtr<Node> lastNode; | 986 RefPtrWillBeRawPtr<Node> lastNode = nullptr; |
976 RefPtr<Node> outerNode = passedOuterNode; | 987 RefPtrWillBeRawPtr<Node> outerNode = passedOuterNode; |
977 | 988 |
978 if (outerNode->isRootEditableElement()) { | 989 if (outerNode->isRootEditableElement()) { |
979 lastNode = blockElement; | 990 lastNode = blockElement; |
980 } else { | 991 } else { |
981 lastNode = outerNode->cloneNode(isRenderedTableElement(outerNode.get()))
; | 992 lastNode = outerNode->cloneNode(isRenderedTableElement(outerNode.get()))
; |
982 appendNode(lastNode, blockElement); | 993 appendNode(lastNode, blockElement); |
983 } | 994 } |
984 | 995 |
985 if (start.anchorNode() != outerNode && lastNode->isElementNode() && start.an
chorNode()->isDescendantOf(outerNode.get())) { | 996 if (start.anchorNode() != outerNode && lastNode->isElementNode() && start.an
chorNode()->isDescendantOf(outerNode.get())) { |
986 Vector<RefPtr<Node> > ancestors; | 997 WillBeHeapVector<RefPtrWillBeMember<Node> > ancestors; |
987 | 998 |
988 // Insert each node from innerNode to outerNode (excluded) in a list. | 999 // Insert each node from innerNode to outerNode (excluded) in a list. |
989 for (Node* n = start.deprecatedNode(); n && n != outerNode; n = n->paren
tNode()) | 1000 for (Node* n = start.deprecatedNode(); n && n != outerNode; n = n->paren
tNode()) |
990 ancestors.append(n); | 1001 ancestors.append(n); |
991 | 1002 |
992 // Clone every node between start.deprecatedNode() and outerBlock. | 1003 // Clone every node between start.deprecatedNode() and outerBlock. |
993 | 1004 |
994 for (size_t i = ancestors.size(); i != 0; --i) { | 1005 for (size_t i = ancestors.size(); i != 0; --i) { |
995 Node* item = ancestors[i - 1].get(); | 1006 Node* item = ancestors[i - 1].get(); |
996 RefPtr<Node> child = item->cloneNode(isRenderedTableElement(item)); | 1007 RefPtrWillBeRawPtr<Node> child = item->cloneNode(isRenderedTableElem
ent(item)); |
997 appendNode(child, toElement(lastNode)); | 1008 appendNode(child, toElement(lastNode)); |
998 lastNode = child.release(); | 1009 lastNode = child.release(); |
999 } | 1010 } |
1000 } | 1011 } |
1001 | 1012 |
1002 // Scripts specified in javascript protocol may remove |outerNode| | 1013 // Scripts specified in javascript protocol may remove |outerNode| |
1003 // during insertion, e.g. <iframe src="javascript:..."> | 1014 // during insertion, e.g. <iframe src="javascript:..."> |
1004 if (!outerNode->inDocument()) | 1015 if (!outerNode->inDocument()) |
1005 return; | 1016 return; |
1006 | 1017 |
1007 // Handle the case of paragraphs with more than one node, | 1018 // Handle the case of paragraphs with more than one node, |
1008 // cloning all the siblings until end.deprecatedNode() is reached. | 1019 // cloning all the siblings until end.deprecatedNode() is reached. |
1009 | 1020 |
1010 if (start.deprecatedNode() != end.deprecatedNode() && !start.deprecatedNode(
)->isDescendantOf(end.deprecatedNode())) { | 1021 if (start.deprecatedNode() != end.deprecatedNode() && !start.deprecatedNode(
)->isDescendantOf(end.deprecatedNode())) { |
1011 // If end is not a descendant of outerNode we need to | 1022 // If end is not a descendant of outerNode we need to |
1012 // find the first common ancestor to increase the scope | 1023 // find the first common ancestor to increase the scope |
1013 // of our nextSibling traversal. | 1024 // of our nextSibling traversal. |
1014 while (outerNode && !end.deprecatedNode()->isDescendantOf(outerNode.get(
))) { | 1025 while (outerNode && !end.deprecatedNode()->isDescendantOf(outerNode.get(
))) { |
1015 outerNode = outerNode->parentNode(); | 1026 outerNode = outerNode->parentNode(); |
1016 } | 1027 } |
1017 | 1028 |
1018 if (!outerNode) | 1029 if (!outerNode) |
1019 return; | 1030 return; |
1020 | 1031 |
1021 RefPtr<Node> startNode = start.deprecatedNode(); | 1032 RefPtrWillBeRawPtr<Node> startNode = start.deprecatedNode(); |
1022 for (RefPtr<Node> node = NodeTraversal::nextSkippingChildren(*startNode,
outerNode.get()); node; node = NodeTraversal::nextSkippingChildren(*node, outer
Node.get())) { | 1033 for (RefPtrWillBeRawPtr<Node> node = NodeTraversal::nextSkippingChildren
(*startNode, outerNode.get()); node; node = NodeTraversal::nextSkippingChildren(
*node, outerNode.get())) { |
1023 // Move lastNode up in the tree as much as node was moved up in the | 1034 // Move lastNode up in the tree as much as node was moved up in the |
1024 // tree by NodeTraversal::nextSkippingChildren, so that the relative
depth between | 1035 // tree by NodeTraversal::nextSkippingChildren, so that the relative
depth between |
1025 // node and the original start node is maintained in the clone. | 1036 // node and the original start node is maintained in the clone. |
1026 while (startNode && lastNode && startNode->parentNode() != node->par
entNode()) { | 1037 while (startNode && lastNode && startNode->parentNode() != node->par
entNode()) { |
1027 startNode = startNode->parentNode(); | 1038 startNode = startNode->parentNode(); |
1028 lastNode = lastNode->parentNode(); | 1039 lastNode = lastNode->parentNode(); |
1029 } | 1040 } |
1030 | 1041 |
1031 if (!lastNode || !lastNode->parentNode()) | 1042 if (!lastNode || !lastNode->parentNode()) |
1032 return; | 1043 return; |
1033 | 1044 |
1034 RefPtr<Node> clonedNode = node->cloneNode(true); | 1045 RefPtrWillBeRawPtr<Node> clonedNode = node->cloneNode(true); |
1035 insertNodeAfter(clonedNode, lastNode); | 1046 insertNodeAfter(clonedNode, lastNode); |
1036 lastNode = clonedNode.release(); | 1047 lastNode = clonedNode.release(); |
1037 if (node == end.deprecatedNode() || end.deprecatedNode()->isDescenda
ntOf(node.get())) | 1048 if (node == end.deprecatedNode() || end.deprecatedNode()->isDescenda
ntOf(node.get())) |
1038 break; | 1049 break; |
1039 } | 1050 } |
1040 } | 1051 } |
1041 } | 1052 } |
1042 | 1053 |
1043 | 1054 |
1044 // There are bugs in deletion when it removes a fully selected table/list. | 1055 // There are bugs in deletion when it removes a fully selected table/list. |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 RefPtrWillBeRawPtr<Range> range = Range::create(document(), startRangeCompli
ant.deprecatedNode(), startRangeCompliant.deprecatedEditingOffset(), endRangeCom
pliant.deprecatedNode(), endRangeCompliant.deprecatedEditingOffset()); | 1204 RefPtrWillBeRawPtr<Range> range = Range::create(document(), startRangeCompli
ant.deprecatedNode(), startRangeCompliant.deprecatedEditingOffset(), endRangeCom
pliant.deprecatedNode(), endRangeCompliant.deprecatedEditingOffset()); |
1194 | 1205 |
1195 // FIXME: This is an inefficient way to preserve style on nodes in the parag
raph to move. It | 1206 // FIXME: This is an inefficient way to preserve style on nodes in the parag
raph to move. It |
1196 // shouldn't matter though, since moved paragraphs will usually be quite sma
ll. | 1207 // shouldn't matter though, since moved paragraphs will usually be quite sma
ll. |
1197 RefPtrWillBeRawPtr<DocumentFragment> fragment = startOfParagraphToMove != en
dOfParagraphToMove ? | 1208 RefPtrWillBeRawPtr<DocumentFragment> fragment = startOfParagraphToMove != en
dOfParagraphToMove ? |
1198 createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotA
nnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor), "") : null
ptr; | 1209 createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotA
nnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor), "") : null
ptr; |
1199 | 1210 |
1200 // A non-empty paragraph's style is moved when we copy and move it. We don'
t move | 1211 // A non-empty paragraph's style is moved when we copy and move it. We don'
t move |
1201 // anything if we're given an empty paragraph, but an empty paragraph can ha
ve style | 1212 // anything if we're given an empty paragraph, but an empty paragraph can ha
ve style |
1202 // too, <div><b><br></b></div> for example. Save it so that we can preserve
it later. | 1213 // too, <div><b><br></b></div> for example. Save it so that we can preserve
it later. |
1203 RefPtr<EditingStyle> styleInEmptyParagraph; | 1214 RefPtrWillBeRawPtr<EditingStyle> styleInEmptyParagraph = nullptr; |
1204 if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) { | 1215 if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) { |
1205 styleInEmptyParagraph = EditingStyle::create(startOfParagraphToMove.deep
Equivalent()); | 1216 styleInEmptyParagraph = EditingStyle::create(startOfParagraphToMove.deep
Equivalent()); |
1206 styleInEmptyParagraph->mergeTypingStyle(&document()); | 1217 styleInEmptyParagraph->mergeTypingStyle(&document()); |
1207 // The moved paragraph should assume the block style of the destination. | 1218 // The moved paragraph should assume the block style of the destination. |
1208 styleInEmptyParagraph->removeBlockProperties(); | 1219 styleInEmptyParagraph->removeBlockProperties(); |
1209 } | 1220 } |
1210 | 1221 |
1211 // FIXME (5098931): We should add a new insert action "WebViewInsertActionMo
ved" and call shouldInsertFragment here. | 1222 // FIXME (5098931): We should add a new insert action "WebViewInsertActionMo
ved" and call shouldInsertFragment here. |
1212 | 1223 |
1213 setEndingSelection(VisibleSelection(start, end, DOWNSTREAM)); | 1224 setEndingSelection(VisibleSelection(start, end, DOWNSTREAM)); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 RefPtrWillBeRawPtr<Range> end = PlainTextRange(destinationIndex + en
dIndex).createRangeForSelection(*documentElement); | 1273 RefPtrWillBeRawPtr<Range> end = PlainTextRange(destinationIndex + en
dIndex).createRangeForSelection(*documentElement); |
1263 if (start && end) | 1274 if (start && end) |
1264 setEndingSelection(VisibleSelection(start->startPosition(), end-
>startPosition(), DOWNSTREAM, originalIsDirectional)); | 1275 setEndingSelection(VisibleSelection(start->startPosition(), end-
>startPosition(), DOWNSTREAM, originalIsDirectional)); |
1265 } | 1276 } |
1266 } | 1277 } |
1267 } | 1278 } |
1268 | 1279 |
1269 // FIXME: Send an appropriate shouldDeleteRange call. | 1280 // FIXME: Send an appropriate shouldDeleteRange call. |
1270 bool CompositeEditCommand::breakOutOfEmptyListItem() | 1281 bool CompositeEditCommand::breakOutOfEmptyListItem() |
1271 { | 1282 { |
1272 RefPtr<Node> emptyListItem = enclosingEmptyListItem(endingSelection().visibl
eStart()); | 1283 RefPtrWillBeRawPtr<Node> emptyListItem = enclosingEmptyListItem(endingSelect
ion().visibleStart()); |
1273 if (!emptyListItem) | 1284 if (!emptyListItem) |
1274 return false; | 1285 return false; |
1275 | 1286 |
1276 RefPtr<EditingStyle> style = EditingStyle::create(endingSelection().start())
; | 1287 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(endingSelectio
n().start()); |
1277 style->mergeTypingStyle(&document()); | 1288 style->mergeTypingStyle(&document()); |
1278 | 1289 |
1279 RefPtr<ContainerNode> listNode = emptyListItem->parentNode(); | 1290 RefPtrWillBeRawPtr<ContainerNode> listNode = emptyListItem->parentNode(); |
1280 // FIXME: Can't we do something better when the immediate parent wasn't a li
st node? | 1291 // FIXME: Can't we do something better when the immediate parent wasn't a li
st node? |
1281 if (!listNode | 1292 if (!listNode |
1282 || (!isHTMLUListElement(*listNode) && !isHTMLOListElement(*listNode)) | 1293 || (!isHTMLUListElement(*listNode) && !isHTMLOListElement(*listNode)) |
1283 || !listNode->rendererIsEditable() | 1294 || !listNode->rendererIsEditable() |
1284 || listNode == emptyListItem->rootEditableElement()) | 1295 || listNode == emptyListItem->rootEditableElement()) |
1285 return false; | 1296 return false; |
1286 | 1297 |
1287 RefPtr<Element> newBlock = nullptr; | 1298 RefPtrWillBeRawPtr<Element> newBlock = nullptr; |
1288 if (ContainerNode* blockEnclosingList = listNode->parentNode()) { | 1299 if (ContainerNode* blockEnclosingList = listNode->parentNode()) { |
1289 if (isHTMLLIElement(*blockEnclosingList)) { // listNode is inside anothe
r list item | 1300 if (isHTMLLIElement(*blockEnclosingList)) { // listNode is inside anothe
r list item |
1290 if (visiblePositionAfterNode(*blockEnclosingList) == visiblePosition
AfterNode(*listNode)) { | 1301 if (visiblePositionAfterNode(*blockEnclosingList) == visiblePosition
AfterNode(*listNode)) { |
1291 // If listNode appears at the end of the outer list item, then m
ove listNode outside of this list item | 1302 // If listNode appears at the end of the outer list item, then m
ove listNode outside of this list item |
1292 // e.g. <ul><li>hello <ul><li><br></li></ul> </li></ul> should b
ecome <ul><li>hello</li> <ul><li><br></li></ul> </ul> after this section | 1303 // e.g. <ul><li>hello <ul><li><br></li></ul> </li></ul> should b
ecome <ul><li>hello</li> <ul><li><br></li></ul> </ul> after this section |
1293 // If listNode does NOT appear at the end, then we should consid
er it as a regular paragraph. | 1304 // If listNode does NOT appear at the end, then we should consid
er it as a regular paragraph. |
1294 // e.g. <ul><li> <ul><li><br></li></ul> hello</li></ul> should b
ecome <ul><li> <div><br></div> hello</li></ul> at the end | 1305 // e.g. <ul><li> <ul><li><br></li></ul> hello</li></ul> should b
ecome <ul><li> <div><br></div> hello</li></ul> at the end |
1295 splitElement(toElement(blockEnclosingList), listNode); | 1306 splitElement(toElement(blockEnclosingList), listNode); |
1296 removeNodePreservingChildren(listNode->parentNode()); | 1307 removeNodePreservingChildren(listNode->parentNode()); |
1297 newBlock = createListItemElement(document()); | 1308 newBlock = createListItemElement(document()); |
1298 } | 1309 } |
1299 // If listNode does NOT appear at the end of the outer list item, th
en behave as if in a regular paragraph. | 1310 // If listNode does NOT appear at the end of the outer list item, th
en behave as if in a regular paragraph. |
1300 } else if (isHTMLOListElement(*blockEnclosingList) || isHTMLUListElement
(*blockEnclosingList)) { | 1311 } else if (isHTMLOListElement(*blockEnclosingList) || isHTMLUListElement
(*blockEnclosingList)) { |
1301 newBlock = createListItemElement(document()); | 1312 newBlock = createListItemElement(document()); |
1302 } | 1313 } |
1303 } | 1314 } |
1304 if (!newBlock) | 1315 if (!newBlock) |
1305 newBlock = createDefaultParagraphElement(document()); | 1316 newBlock = createDefaultParagraphElement(document()); |
1306 | 1317 |
1307 RefPtr<Node> previousListNode = emptyListItem->isElementNode() ? ElementTrav
ersal::previousSibling(*emptyListItem): emptyListItem->previousSibling(); | 1318 RefPtrWillBeRawPtr<Node> previousListNode = emptyListItem->isElementNode() ?
ElementTraversal::previousSibling(*emptyListItem): emptyListItem->previousSibli
ng(); |
1308 RefPtr<Node> nextListNode = emptyListItem->isElementNode() ? ElementTraversa
l::nextSibling(*emptyListItem): emptyListItem->nextSibling(); | 1319 RefPtrWillBeRawPtr<Node> nextListNode = emptyListItem->isElementNode() ? Ele
mentTraversal::nextSibling(*emptyListItem): emptyListItem->nextSibling(); |
1309 if (isListItem(nextListNode.get()) || isListElement(nextListNode.get())) { | 1320 if (isListItem(nextListNode.get()) || isListElement(nextListNode.get())) { |
1310 // If emptyListItem follows another list item or nested list, split the
list node. | 1321 // If emptyListItem follows another list item or nested list, split the
list node. |
1311 if (isListItem(previousListNode.get()) || isListElement(previousListNode
.get())) | 1322 if (isListItem(previousListNode.get()) || isListElement(previousListNode
.get())) |
1312 splitElement(toElement(listNode), emptyListItem); | 1323 splitElement(toElement(listNode), emptyListItem); |
1313 | 1324 |
1314 // If emptyListItem is followed by other list item or nested list, then
insert newBlock before the list node. | 1325 // If emptyListItem is followed by other list item or nested list, then
insert newBlock before the list node. |
1315 // Because we have splitted the element, emptyListItem is the first elem
ent in the list node. | 1326 // Because we have splitted the element, emptyListItem is the first elem
ent in the list node. |
1316 // i.e. insert newBlock before ul or ol whose first element is emptyList
Item | 1327 // i.e. insert newBlock before ul or ol whose first element is emptyList
Item |
1317 insertNodeBefore(newBlock, listNode); | 1328 insertNodeBefore(newBlock, listNode); |
1318 removeNode(emptyListItem); | 1329 removeNode(emptyListItem); |
(...skipping 27 matching lines...) Expand all Loading... |
1346 return false; | 1357 return false; |
1347 | 1358 |
1348 if (!isStartOfParagraph(caret) || !isEndOfParagraph(caret)) | 1359 if (!isStartOfParagraph(caret) || !isEndOfParagraph(caret)) |
1349 return false; | 1360 return false; |
1350 | 1361 |
1351 VisiblePosition previous(caret.previous(CannotCrossEditingBoundary)); | 1362 VisiblePosition previous(caret.previous(CannotCrossEditingBoundary)); |
1352 // Only move forward if there's nothing before the caret, or if there's unqu
oted content before it. | 1363 // Only move forward if there's nothing before the caret, or if there's unqu
oted content before it. |
1353 if (enclosingNodeOfType(previous.deepEquivalent(), &isMailBlockquote)) | 1364 if (enclosingNodeOfType(previous.deepEquivalent(), &isMailBlockquote)) |
1354 return false; | 1365 return false; |
1355 | 1366 |
1356 RefPtr<Node> br = createBreakElement(document()); | 1367 RefPtrWillBeRawPtr<Node> br = createBreakElement(document()); |
1357 // We want to replace this quoted paragraph with an unquoted one, so insert
a br | 1368 // We want to replace this quoted paragraph with an unquoted one, so insert
a br |
1358 // to hold the caret before the highest blockquote. | 1369 // to hold the caret before the highest blockquote. |
1359 insertNodeBefore(br, highestBlockquote); | 1370 insertNodeBefore(br, highestBlockquote); |
1360 VisiblePosition atBR(positionBeforeNode(br.get())); | 1371 VisiblePosition atBR(positionBeforeNode(br.get())); |
1361 // If the br we inserted collapsed, for example foo<br><blockquote>...</bloc
kquote>, insert | 1372 // If the br we inserted collapsed, for example foo<br><blockquote>...</bloc
kquote>, insert |
1362 // a second one. | 1373 // a second one. |
1363 if (!isStartOfParagraph(atBR)) | 1374 if (!isStartOfParagraph(atBR)) |
1364 insertNodeBefore(createBreakElement(document()), br); | 1375 insertNodeBefore(createBreakElement(document()), br); |
1365 setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional())
); | 1376 setEndingSelection(VisibleSelection(atBR, endingSelection().isDirectional())
); |
1366 | 1377 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1443 } | 1454 } |
1444 | 1455 |
1445 if (result.isNull() || !editableRootForPosition(result)) | 1456 if (result.isNull() || !editableRootForPosition(result)) |
1446 result = original; | 1457 result = original; |
1447 | 1458 |
1448 return result; | 1459 return result; |
1449 } | 1460 } |
1450 | 1461 |
1451 // Splits the tree parent by parent until we reach the specified ancestor. We us
e VisiblePositions | 1462 // Splits the tree parent by parent until we reach the specified ancestor. We us
e VisiblePositions |
1452 // to determine if the split is necessary. Returns the last split node. | 1463 // to determine if the split is necessary. Returns the last split node. |
1453 PassRefPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, b
ool shouldSplitAncestor) | 1464 PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start,
Node* end, bool shouldSplitAncestor) |
1454 { | 1465 { |
1455 ASSERT(start); | 1466 ASSERT(start); |
1456 ASSERT(end); | 1467 ASSERT(end); |
1457 ASSERT(start != end); | 1468 ASSERT(start != end); |
1458 | 1469 |
1459 if (shouldSplitAncestor && end->parentNode()) | 1470 if (shouldSplitAncestor && end->parentNode()) |
1460 end = end->parentNode(); | 1471 end = end->parentNode(); |
1461 if (!start->isDescendantOf(end)) | 1472 if (!start->isDescendantOf(end)) |
1462 return end; | 1473 return end; |
1463 | 1474 |
1464 RefPtr<Node> endNode = end; | 1475 RefPtrWillBeRawPtr<Node> endNode = end; |
1465 RefPtr<Node> node; | 1476 RefPtrWillBeRawPtr<Node> node = nullptr; |
1466 for (node = start; node->parentNode() != endNode; node = node->parentNode())
{ | 1477 for (node = start; node->parentNode() != endNode; node = node->parentNode())
{ |
1467 if (!node->parentNode()->isElementNode()) | 1478 if (!node->parentNode()->isElementNode()) |
1468 break; | 1479 break; |
1469 // Do not split a node when doing so introduces an empty node. | 1480 // Do not split a node when doing so introduces an empty node. |
1470 VisiblePosition positionInParent(firstPositionInNode(node->parentNode())
); | 1481 VisiblePosition positionInParent(firstPositionInNode(node->parentNode())
); |
1471 VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get())); | 1482 VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get())); |
1472 if (positionInParent != positionInNode) | 1483 if (positionInParent != positionInNode) |
1473 splitElement(toElement(node->parentNode()), node); | 1484 splitElement(toElement(node->parentNode()), node); |
1474 } | 1485 } |
1475 | 1486 |
1476 return node.release(); | 1487 return node.release(); |
1477 } | 1488 } |
1478 | 1489 |
1479 PassRefPtrWillBeRawPtr<Element> createBlockPlaceholderElement(Document& document
) | 1490 PassRefPtrWillBeRawPtr<Element> createBlockPlaceholderElement(Document& document
) |
1480 { | 1491 { |
1481 return document.createElement(brTag, false); | 1492 return document.createElement(brTag, false); |
1482 } | 1493 } |
1483 | 1494 |
| 1495 void CompositeEditCommand::trace(Visitor* visitor) |
| 1496 { |
| 1497 visitor->trace(m_commands); |
| 1498 visitor->trace(m_composition); |
| 1499 EditCommand::trace(visitor); |
| 1500 } |
| 1501 |
1484 } // namespace WebCore | 1502 } // namespace WebCore |
OLD | NEW |