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