Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(476)

Side by Side Diff: Source/core/editing/DeleteSelectionCommand.cpp

Issue 1245843003: [CodeHealth] Use Position::anchorNode instead of deprecatedNode. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. 2 * Copyright (C) 2005 Apple Computer, 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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end) 103 void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
104 { 104 {
105 HTMLElement* startSpecialContainer = nullptr; 105 HTMLElement* startSpecialContainer = nullptr;
106 HTMLElement* endSpecialContainer = nullptr; 106 HTMLElement* endSpecialContainer = nullptr;
107 107
108 start = m_selectionToDelete.start(); 108 start = m_selectionToDelete.start();
109 end = m_selectionToDelete.end(); 109 end = m_selectionToDelete.end();
110 110
111 // For HRs, we'll get a position at (HR,1) when hitting delete from the begi nning of the previous line, or (HR,0) when forward deleting, 111 // For HRs, we'll get a position at (HR,1) when hitting delete from the begi nning of the previous line, or (HR,0) when forward deleting,
112 // but in these cases, we want to delete it, so manually expand the selectio n 112 // but in these cases, we want to delete it, so manually expand the selectio n
113 if (isHTMLHRElement(*start.deprecatedNode())) 113 if (isHTMLHRElement(*start.anchorNode()))
114 start = positionBeforeNode(start.deprecatedNode()); 114 start = positionBeforeNode(start.anchorNode());
115 else if (isHTMLHRElement(*end.deprecatedNode())) 115 else if (isHTMLHRElement(*end.anchorNode()))
116 end = positionAfterNode(end.deprecatedNode()); 116 end = positionAfterNode(end.anchorNode());
117 117
118 // FIXME: This is only used so that moveParagraphs can avoid the bugs in spe cial element expansion. 118 // FIXME: This is only used so that moveParagraphs can avoid the bugs in spe cial element expansion.
119 if (!m_expandForSpecialElements) 119 if (!m_expandForSpecialElements)
120 return; 120 return;
121 121
122 while (1) { 122 while (1) {
123 startSpecialContainer = 0; 123 startSpecialContainer = 0;
124 endSpecialContainer = 0; 124 endSpecialContainer = 0;
125 125
126 Position s = positionBeforeContainingSpecialElement(start, &startSpecial Container); 126 Position s = positionBeforeContainingSpecialElement(start, &startSpecial Container);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 272
273 void DeleteSelectionCommand::saveTypingStyleState() 273 void DeleteSelectionCommand::saveTypingStyleState()
274 { 274 {
275 // A common case is deleting characters that are all from the same text node . In 275 // A common case is deleting characters that are all from the same text node . In
276 // that case, the style at the start of the selection before deletion will b e the 276 // that case, the style at the start of the selection before deletion will b e the
277 // same as the style at the start of the selection after deletion (since tho se 277 // same as the style at the start of the selection after deletion (since tho se
278 // two positions will be identical). Therefore there is no need to save the 278 // two positions will be identical). Therefore there is no need to save the
279 // typing style at the start of the selection, nor is there a reason to 279 // typing style at the start of the selection, nor is there a reason to
280 // compute the style at the start of the selection after deletion (see the 280 // compute the style at the start of the selection after deletion (see the
281 // early return in calculateTypingStyleAfterDelete). 281 // early return in calculateTypingStyleAfterDelete).
282 if (m_upstreamStart.deprecatedNode() == m_downstreamEnd.deprecatedNode() && m_upstreamStart.deprecatedNode()->isTextNode()) 282 if (m_upstreamStart.anchorNode() == m_downstreamEnd.anchorNode() && m_upstre amStart.anchorNode()->isTextNode())
283 return; 283 return;
284 284
285 if (shouldNotInheritStyleFrom(*m_selectionToDelete.start().anchorNode())) 285 if (shouldNotInheritStyleFrom(*m_selectionToDelete.start().anchorNode()))
286 return; 286 return;
287 287
288 // Figure out the typing style in effect before the delete is done. 288 // Figure out the typing style in effect before the delete is done.
289 m_typingStyle = EditingStyle::create(m_selectionToDelete.start(), EditingSty le::EditingPropertiesInEffect); 289 m_typingStyle = EditingStyle::create(m_selectionToDelete.start(), EditingSty le::EditingPropertiesInEffect);
290 m_typingStyle->removeStyleAddedByElement(enclosingAnchorElement(m_selectionT oDelete.start())); 290 m_typingStyle->removeStyleAddedByElement(enclosingAnchorElement(m_selectionT oDelete.start()));
291 291
292 // If we're deleting into a Mail blockquote, save the style at end() instead of start() 292 // If we're deleting into a Mail blockquote, save the style at end() instead of start()
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 node = nextNode; 441 node = nextNode;
442 } 442 }
443 } 443 }
444 444
445 void DeleteSelectionCommand::handleGeneralDelete() 445 void DeleteSelectionCommand::handleGeneralDelete()
446 { 446 {
447 if (m_upstreamStart.isNull()) 447 if (m_upstreamStart.isNull())
448 return; 448 return;
449 449
450 int startOffset = m_upstreamStart.deprecatedEditingOffset(); 450 int startOffset = m_upstreamStart.deprecatedEditingOffset();
451 Node* startNode = m_upstreamStart.deprecatedNode(); 451 Node* startNode = m_upstreamStart.anchorNode();
452 ASSERT(startNode); 452 ASSERT(startNode);
453 453
454 makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss(); 454 makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss();
455 455
456 // Never remove the start block unless it's a table, in which case we won't merge content in. 456 // Never remove the start block unless it's a table, in which case we won't merge content in.
457 if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChil drenForEditing(startNode) && !isHTMLTableElement(*startNode)) { 457 if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChil drenForEditing(startNode) && !isHTMLTableElement(*startNode)) {
458 startOffset = 0; 458 startOffset = 0;
459 startNode = NodeTraversal::next(*startNode); 459 startNode = NodeTraversal::next(*startNode);
460 if (!startNode) 460 if (!startNode)
461 return; 461 return;
462 } 462 }
463 463
464 if (startOffset >= caretMaxOffset(startNode) && startNode->isTextNode()) { 464 if (startOffset >= caretMaxOffset(startNode) && startNode->isTextNode()) {
465 Text* text = toText(startNode); 465 Text* text = toText(startNode);
466 if (text->length() > (unsigned)caretMaxOffset(startNode)) 466 if (text->length() > (unsigned)caretMaxOffset(startNode))
467 deleteTextFromNode(text, caretMaxOffset(startNode), text->length() - caretMaxOffset(startNode)); 467 deleteTextFromNode(text, caretMaxOffset(startNode), text->length() - caretMaxOffset(startNode));
468 } 468 }
469 469
470 if (startOffset >= lastOffsetForEditing(startNode)) { 470 if (startOffset >= lastOffsetForEditing(startNode)) {
471 startNode = NodeTraversal::nextSkippingChildren(*startNode); 471 startNode = NodeTraversal::nextSkippingChildren(*startNode);
472 startOffset = 0; 472 startOffset = 0;
473 } 473 }
474 474
475 // Done adjusting the start. See if we're all done. 475 // Done adjusting the start. See if we're all done.
476 if (!startNode) 476 if (!startNode)
477 return; 477 return;
478 478
479 if (startNode == m_downstreamEnd.deprecatedNode()) { 479 if (startNode == m_downstreamEnd.anchorNode()) {
480 if (m_downstreamEnd.deprecatedEditingOffset() - startOffset > 0) { 480 if (m_downstreamEnd.deprecatedEditingOffset() - startOffset > 0) {
481 if (startNode->isTextNode()) { 481 if (startNode->isTextNode()) {
482 // in a text node that needs to be trimmed 482 // in a text node that needs to be trimmed
483 Text* text = toText(startNode); 483 Text* text = toText(startNode);
484 deleteTextFromNode(text, startOffset, m_downstreamEnd.deprecated EditingOffset() - startOffset); 484 deleteTextFromNode(text, startOffset, m_downstreamEnd.deprecated EditingOffset() - startOffset);
485 } else { 485 } else {
486 removeChildrenInRange(startNode, startOffset, m_downstreamEnd.de precatedEditingOffset()); 486 removeChildrenInRange(startNode, startOffset, m_downstreamEnd.de precatedEditingOffset());
487 m_endingPosition = m_upstreamStart; 487 m_endingPosition = m_upstreamStart;
488 } 488 }
489 } 489 }
490 490
491 // The selection to delete is all in one node. 491 // The selection to delete is all in one node.
492 if (!startNode->layoutObject() || (!startOffset && m_downstreamEnd.atLas tEditingPositionForNode())) 492 if (!startNode->layoutObject() || (!startOffset && m_downstreamEnd.atLas tEditingPositionForNode()))
493 removeNode(startNode); 493 removeNode(startNode);
494 } 494 }
495 else { 495 else {
496 bool startNodeWasDescendantOfEndNode = m_upstreamStart.deprecatedNode()- >isDescendantOf(m_downstreamEnd.deprecatedNode()); 496 bool startNodeWasDescendantOfEndNode = m_upstreamStart.anchorNode()->isD escendantOf(m_downstreamEnd.anchorNode());
497 // The selection to delete spans more than one node. 497 // The selection to delete spans more than one node.
498 RefPtrWillBeRawPtr<Node> node(startNode); 498 RefPtrWillBeRawPtr<Node> node(startNode);
499 499
500 if (startOffset > 0) { 500 if (startOffset > 0) {
501 if (startNode->isTextNode()) { 501 if (startNode->isTextNode()) {
502 // in a text node that needs to be trimmed 502 // in a text node that needs to be trimmed
503 Text* text = toText(node); 503 Text* text = toText(node);
504 deleteTextFromNode(text, startOffset, text->length() - startOffs et); 504 deleteTextFromNode(text, startOffset, text->length() - startOffs et);
505 node = NodeTraversal::next(*node); 505 node = NodeTraversal::next(*node);
506 } else { 506 } else {
507 node = NodeTraversal::childAt(*startNode, startOffset); 507 node = NodeTraversal::childAt(*startNode, startOffset);
508 } 508 }
509 } else if (startNode == m_upstreamEnd.deprecatedNode() && startNode->isT extNode()) { 509 } else if (startNode == m_upstreamEnd.anchorNode() && startNode->isTextN ode()) {
510 Text* text = toText(m_upstreamEnd.deprecatedNode()); 510 Text* text = toText(m_upstreamEnd.anchorNode());
511 deleteTextFromNode(text, 0, m_upstreamEnd.deprecatedEditingOffset()) ; 511 deleteTextFromNode(text, 0, m_upstreamEnd.deprecatedEditingOffset()) ;
512 } 512 }
513 513
514 // handle deleting all nodes that are completely selected 514 // handle deleting all nodes that are completely selected
515 while (node && node != m_downstreamEnd.deprecatedNode()) { 515 while (node && node != m_downstreamEnd.anchorNode()) {
516 if (comparePositions(firstPositionInOrBeforeNode(node.get()), m_down streamEnd) >= 0) { 516 if (comparePositions(firstPositionInOrBeforeNode(node.get()), m_down streamEnd) >= 0) {
517 // NodeTraversal::nextSkippingChildren just blew past the end po sition, so stop deleting 517 // NodeTraversal::nextSkippingChildren just blew past the end po sition, so stop deleting
518 node = nullptr; 518 node = nullptr;
519 } else if (!m_downstreamEnd.deprecatedNode()->isDescendantOf(node.ge t())) { 519 } else if (!m_downstreamEnd.anchorNode()->isDescendantOf(node.get()) ) {
520 RefPtrWillBeRawPtr<Node> nextNode = NodeTraversal::nextSkippingC hildren(*node); 520 RefPtrWillBeRawPtr<Node> nextNode = NodeTraversal::nextSkippingC hildren(*node);
521 // if we just removed a node from the end container, update end position so the 521 // if we just removed a node from the end container, update end position so the
522 // check above will work 522 // check above will work
523 updatePositionForNodeRemoval(m_downstreamEnd, *node); 523 updatePositionForNodeRemoval(m_downstreamEnd, *node);
524 removeNode(node.get()); 524 removeNode(node.get());
525 node = nextNode.get(); 525 node = nextNode.get();
526 } else { 526 } else {
527 Node& n = NodeTraversal::lastWithinOrSelf(*node); 527 Node& n = NodeTraversal::lastWithinOrSelf(*node);
528 if (m_downstreamEnd.deprecatedNode() == n && m_downstreamEnd.dep recatedEditingOffset() >= caretMaxOffset(&n)) { 528 if (m_downstreamEnd.anchorNode() == n && m_downstreamEnd.depreca tedEditingOffset() >= caretMaxOffset(&n)) {
529 removeNode(node.get()); 529 removeNode(node.get());
530 node = nullptr; 530 node = nullptr;
531 } else { 531 } else {
532 node = NodeTraversal::next(*node); 532 node = NodeTraversal::next(*node);
533 } 533 }
534 } 534 }
535 } 535 }
536 536
537 if (m_downstreamEnd.deprecatedNode() != startNode && !m_upstreamStart.de precatedNode()->isDescendantOf(m_downstreamEnd.deprecatedNode()) && m_downstream End.inDocument() && m_downstreamEnd.deprecatedEditingOffset() >= caretMinOffset( m_downstreamEnd.deprecatedNode())) { 537 if (m_downstreamEnd.anchorNode() != startNode && !m_upstreamStart.anchor Node()->isDescendantOf(m_downstreamEnd.anchorNode()) && m_downstreamEnd.inDocume nt() && m_downstreamEnd.deprecatedEditingOffset() >= caretMinOffset(m_downstream End.anchorNode())) {
538 if (m_downstreamEnd.atLastEditingPositionForNode() && !canHaveChildr enForEditing(m_downstreamEnd.deprecatedNode())) { 538 if (m_downstreamEnd.atLastEditingPositionForNode() && !canHaveChildr enForEditing(m_downstreamEnd.anchorNode())) {
539 // The node itself is fully selected, not just its contents. De lete it. 539 // The node itself is fully selected, not just its contents. De lete it.
540 removeNode(m_downstreamEnd.deprecatedNode()); 540 removeNode(m_downstreamEnd.anchorNode());
541 } else { 541 } else {
542 if (m_downstreamEnd.deprecatedNode()->isTextNode()) { 542 if (m_downstreamEnd.anchorNode()->isTextNode()) {
543 // in a text node that needs to be trimmed 543 // in a text node that needs to be trimmed
544 Text* text = toText(m_downstreamEnd.deprecatedNode()); 544 Text* text = toText(m_downstreamEnd.anchorNode());
545 if (m_downstreamEnd.deprecatedEditingOffset() > 0) { 545 if (m_downstreamEnd.deprecatedEditingOffset() > 0) {
546 deleteTextFromNode(text, 0, m_downstreamEnd.deprecatedEd itingOffset()); 546 deleteTextFromNode(text, 0, m_downstreamEnd.deprecatedEd itingOffset());
547 } 547 }
548 // Remove children of m_downstreamEnd.deprecatedNode() that come after m_upstreamStart. 548 // Remove children of m_downstreamEnd.anchorNode() that come aft er m_upstreamStart.
549 // Don't try to remove children if m_upstreamStart was inside m_ downstreamEnd.deprecatedNode() 549 // Don't try to remove children if m_upstreamStart was inside m_ downstreamEnd.anchorNode()
550 // and m_upstreamStart has been removed from the document, becau se then we don't 550 // and m_upstreamStart has been removed from the document, becau se then we don't
551 // know how many children to remove. 551 // know how many children to remove.
552 // FIXME: Make m_upstreamStart a position we update as we remove content, then we can 552 // FIXME: Make m_upstreamStart a position we update as we remove content, then we can
553 // always know which children to remove. 553 // always know which children to remove.
554 } else if (!(startNodeWasDescendantOfEndNode && !m_upstreamStart .inDocument())) { 554 } else if (!(startNodeWasDescendantOfEndNode && !m_upstreamStart .inDocument())) {
555 int offset = 0; 555 int offset = 0;
556 if (m_upstreamStart.deprecatedNode()->isDescendantOf(m_downs treamEnd.deprecatedNode())) { 556 if (m_upstreamStart.anchorNode()->isDescendantOf(m_downstrea mEnd.anchorNode())) {
557 Node* n = m_upstreamStart.deprecatedNode(); 557 Node* n = m_upstreamStart.anchorNode();
558 while (n && n->parentNode() != m_downstreamEnd.deprecate dNode()) 558 while (n && n->parentNode() != m_downstreamEnd.anchorNod e())
559 n = n->parentNode(); 559 n = n->parentNode();
560 if (n) 560 if (n)
561 offset = n->nodeIndex() + 1; 561 offset = n->nodeIndex() + 1;
562 } 562 }
563 removeChildrenInRange(m_downstreamEnd.deprecatedNode(), offs et, m_downstreamEnd.deprecatedEditingOffset()); 563 removeChildrenInRange(m_downstreamEnd.anchorNode(), offset, m_downstreamEnd.deprecatedEditingOffset());
564 m_downstreamEnd = createLegacyEditingPosition(m_downstreamEn d.deprecatedNode(), offset); 564 m_downstreamEnd = createLegacyEditingPosition(m_downstreamEn d.anchorNode(), offset);
565 } 565 }
566 } 566 }
567 } 567 }
568 } 568 }
569 } 569 }
570 570
571 void DeleteSelectionCommand::fixupWhitespace() 571 void DeleteSelectionCommand::fixupWhitespace()
572 { 572 {
573 document().updateLayoutIgnorePendingStylesheets(); 573 document().updateLayoutIgnorePendingStylesheets();
574 // FIXME: isRenderedCharacter should be removed, and we should use VisiblePo sition::characterAfter and VisiblePosition::characterBefore 574 // FIXME: isRenderedCharacter should be removed, and we should use VisiblePo sition::characterAfter and VisiblePosition::characterBefore
575 if (m_leadingWhitespace.isNotNull() && !m_leadingWhitespace.isRenderedCharac ter() && m_leadingWhitespace.deprecatedNode()->isTextNode()) { 575 if (m_leadingWhitespace.isNotNull() && !m_leadingWhitespace.isRenderedCharac ter() && m_leadingWhitespace.anchorNode()->isTextNode()) {
576 Text* textNode = toText(m_leadingWhitespace.deprecatedNode()); 576 Text* textNode = toText(m_leadingWhitespace.anchorNode());
577 ASSERT(!textNode->layoutObject() || textNode->layoutObject()->style()->c ollapseWhiteSpace()); 577 ASSERT(!textNode->layoutObject() || textNode->layoutObject()->style()->c ollapseWhiteSpace());
578 replaceTextInNodePreservingMarkers(textNode, m_leadingWhitespace.depreca tedEditingOffset(), 1, nonBreakingSpaceString()); 578 replaceTextInNodePreservingMarkers(textNode, m_leadingWhitespace.depreca tedEditingOffset(), 1, nonBreakingSpaceString());
579 } 579 }
580 if (m_trailingWhitespace.isNotNull() && !m_trailingWhitespace.isRenderedChar acter() && m_trailingWhitespace.deprecatedNode()->isTextNode()) { 580 if (m_trailingWhitespace.isNotNull() && !m_trailingWhitespace.isRenderedChar acter() && m_trailingWhitespace.anchorNode()->isTextNode()) {
581 Text* textNode = toText(m_trailingWhitespace.deprecatedNode()); 581 Text* textNode = toText(m_trailingWhitespace.anchorNode());
582 ASSERT(!textNode->layoutObject() || textNode->layoutObject()->style()->c ollapseWhiteSpace()); 582 ASSERT(!textNode->layoutObject() || textNode->layoutObject()->style()->c ollapseWhiteSpace());
583 replaceTextInNodePreservingMarkers(textNode, m_trailingWhitespace.deprec atedEditingOffset(), 1, nonBreakingSpaceString()); 583 replaceTextInNodePreservingMarkers(textNode, m_trailingWhitespace.deprec atedEditingOffset(), 1, nonBreakingSpaceString());
584 } 584 }
585 } 585 }
586 586
587 // If a selection starts in one block and ends in another, we have to merge to b ring content before the 587 // If a selection starts in one block and ends in another, we have to merge to b ring content before the
588 // start together with content after the end. 588 // start together with content after the end.
589 void DeleteSelectionCommand::mergeParagraphs() 589 void DeleteSelectionCommand::mergeParagraphs()
590 { 590 {
591 if (!m_mergeBlocksAfterDelete) { 591 if (!m_mergeBlocksAfterDelete) {
(...skipping 20 matching lines...) Expand all
612 612
613 // There's nothing to merge. 613 // There's nothing to merge.
614 if (m_upstreamStart == m_downstreamEnd) 614 if (m_upstreamStart == m_downstreamEnd)
615 return; 615 return;
616 616
617 VisiblePosition startOfParagraphToMove(m_downstreamEnd); 617 VisiblePosition startOfParagraphToMove(m_downstreamEnd);
618 VisiblePosition mergeDestination(m_upstreamStart); 618 VisiblePosition mergeDestination(m_upstreamStart);
619 619
620 // m_downstreamEnd's block has been emptied out by deletion. There is no co ntent inside of it to 620 // m_downstreamEnd's block has been emptied out by deletion. There is no co ntent inside of it to
621 // move, so just remove it. 621 // move, so just remove it.
622 Element* endBlock = enclosingBlock(m_downstreamEnd.deprecatedNode()); 622 Element* endBlock = enclosingBlock(m_downstreamEnd.anchorNode());
623 if (!endBlock || !endBlock->contains(startOfParagraphToMove.deepEquivalent() .deprecatedNode()) || !startOfParagraphToMove.deepEquivalent().deprecatedNode()) { 623 if (!endBlock || !endBlock->contains(startOfParagraphToMove.deepEquivalent() .anchorNode()) || !startOfParagraphToMove.deepEquivalent().anchorNode()) {
624 removeNode(enclosingBlock(m_downstreamEnd.deprecatedNode())); 624 removeNode(enclosingBlock(m_downstreamEnd.anchorNode()));
625 return; 625 return;
626 } 626 }
627 627
628 // We need to merge into m_upstreamStart's block, but it's been emptied out and collapsed by deletion. 628 // We need to merge into m_upstreamStart's block, but it's been emptied out and collapsed by deletion.
629 if (!mergeDestination.deepEquivalent().deprecatedNode() || (!mergeDestinatio n.deepEquivalent().deprecatedNode()->isDescendantOf(enclosingBlock(m_upstreamSta rt.containerNode())) && (!mergeDestination.deepEquivalent().anchorNode()->hasChi ldren() || !m_upstreamStart.containerNode()->hasChildren())) || (m_startsAtEmpty Line && mergeDestination != startOfParagraphToMove)) { 629 if (!mergeDestination.deepEquivalent().anchorNode() || (!mergeDestination.de epEquivalent().anchorNode()->isDescendantOf(enclosingBlock(m_upstreamStart.conta inerNode())) && (!mergeDestination.deepEquivalent().anchorNode()->hasChildren() || !m_upstreamStart.containerNode()->hasChildren())) || (m_startsAtEmptyLine && mergeDestination != startOfParagraphToMove)) {
630 insertNodeAt(createBreakElement(document()).get(), m_upstreamStart); 630 insertNodeAt(createBreakElement(document()).get(), m_upstreamStart);
631 mergeDestination = VisiblePosition(m_upstreamStart); 631 mergeDestination = VisiblePosition(m_upstreamStart);
632 } 632 }
633 633
634 if (mergeDestination == startOfParagraphToMove) 634 if (mergeDestination == startOfParagraphToMove)
635 return; 635 return;
636 636
637 VisiblePosition endOfParagraphToMove = endOfParagraph(startOfParagraphToMove , CanSkipOverEditingBoundary); 637 VisiblePosition endOfParagraphToMove = endOfParagraph(startOfParagraphToMove , CanSkipOverEditingBoundary);
638 638
639 if (mergeDestination == endOfParagraphToMove) 639 if (mergeDestination == endOfParagraphToMove)
640 return; 640 return;
641 641
642 // If the merge destination and source to be moved are both list items of di fferent lists, merge them into single list. 642 // If the merge destination and source to be moved are both list items of di fferent lists, merge them into single list.
643 Node* listItemInFirstParagraph = enclosingNodeOfType(m_upstreamStart, isList Item); 643 Node* listItemInFirstParagraph = enclosingNodeOfType(m_upstreamStart, isList Item);
644 Node* listItemInSecondParagraph = enclosingNodeOfType(m_downstreamEnd, isLis tItem); 644 Node* listItemInSecondParagraph = enclosingNodeOfType(m_downstreamEnd, isLis tItem);
645 if (listItemInFirstParagraph && listItemInSecondParagraph 645 if (listItemInFirstParagraph && listItemInSecondParagraph
646 && listItemInFirstParagraph->parentElement() != listItemInSecondParagrap h->parentElement() 646 && listItemInFirstParagraph->parentElement() != listItemInSecondParagrap h->parentElement()
647 && canMergeLists(listItemInFirstParagraph->parentElement(), listItemInSe condParagraph->parentElement())) { 647 && canMergeLists(listItemInFirstParagraph->parentElement(), listItemInSe condParagraph->parentElement())) {
648 mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listIt emInSecondParagraph->parentElement()); 648 mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listIt emInSecondParagraph->parentElement());
649 m_endingPosition = mergeDestination.deepEquivalent(); 649 m_endingPosition = mergeDestination.deepEquivalent();
650 return; 650 return;
651 } 651 }
652 652
653 // The rule for merging into an empty block is: only do so if its farther to the right. 653 // The rule for merging into an empty block is: only do so if its farther to the right.
654 // FIXME: Consider RTL. 654 // FIXME: Consider RTL.
655 if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && startOfP aragraphToMove.absoluteCaretBounds().x() > mergeDestination.absoluteCaretBounds( ).x()) { 655 if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && startOfP aragraphToMove.absoluteCaretBounds().x() > mergeDestination.absoluteCaretBounds( ).x()) {
656 if (isHTMLBRElement(*mergeDestination.deepEquivalent().downstream().depr ecatedNode())) { 656 if (isHTMLBRElement(*mergeDestination.deepEquivalent().downstream().anch orNode())) {
657 removeNodeAndPruneAncestors(mergeDestination.deepEquivalent().downst ream().deprecatedNode()); 657 removeNodeAndPruneAncestors(mergeDestination.deepEquivalent().downst ream().anchorNode());
658 m_endingPosition = startOfParagraphToMove.deepEquivalent(); 658 m_endingPosition = startOfParagraphToMove.deepEquivalent();
659 return; 659 return;
660 } 660 }
661 } 661 }
662 662
663 // Block images, tables and horizontal rules cannot be made inline with cont ent at mergeDestination. If there is 663 // Block images, tables and horizontal rules cannot be made inline with cont ent at mergeDestination. If there is
664 // any (!isStartOfParagraph(mergeDestination)), don't merge, just move the c aret to just before the selection we deleted. 664 // any (!isStartOfParagraph(mergeDestination)), don't merge, just move the c aret to just before the selection we deleted.
665 // See https://bugs.webkit.org/show_bug.cgi?id=25439 665 // See https://bugs.webkit.org/show_bug.cgi?id=25439
666 if (isRenderedAsNonInlineTableImageOrHR(startOfParagraphToMove.deepEquivalen t().deprecatedNode()) && !isStartOfParagraph(mergeDestination)) { 666 if (isRenderedAsNonInlineTableImageOrHR(startOfParagraphToMove.deepEquivalen t().anchorNode()) && !isStartOfParagraph(mergeDestination)) {
667 m_endingPosition = m_upstreamStart; 667 m_endingPosition = m_upstreamStart;
668 return; 668 return;
669 } 669 }
670 670
671 // moveParagraphs will insert placeholders if it removes blocks that would r equire their use, don't let block 671 // moveParagraphs will insert placeholders if it removes blocks that would r equire their use, don't let block
672 // removals that it does cause the insertion of *another* placeholder. 672 // removals that it does cause the insertion of *another* placeholder.
673 bool needPlaceholder = m_needPlaceholder; 673 bool needPlaceholder = m_needPlaceholder;
674 bool paragraphToMergeIsEmpty = (startOfParagraphToMove == endOfParagraphToMo ve); 674 bool paragraphToMergeIsEmpty = (startOfParagraphToMove == endOfParagraphToMo ve);
675 moveParagraph(startOfParagraphToMove, endOfParagraphToMove, mergeDestination , false, !paragraphToMergeIsEmpty); 675 moveParagraph(startOfParagraphToMove, endOfParagraphToMove, mergeDestination , false, !paragraphToMergeIsEmpty);
676 m_needPlaceholder = needPlaceholder; 676 m_needPlaceholder = needPlaceholder;
(...skipping 22 matching lines...) Expand all
699 RefPtrWillBeRawPtr<Node> nextRow = row->nextSibling(); 699 RefPtrWillBeRawPtr<Node> nextRow = row->nextSibling();
700 if (isTableRowEmpty(row)) 700 if (isTableRowEmpty(row))
701 CompositeEditCommand::removeNode(row); 701 CompositeEditCommand::removeNode(row);
702 row = nextRow.get(); 702 row = nextRow.get();
703 } 703 }
704 } 704 }
705 705
706 if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_start TableRow) 706 if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_start TableRow)
707 if (isTableRowEmpty(m_endTableRow.get())) { 707 if (isTableRowEmpty(m_endTableRow.get())) {
708 // Don't remove m_endTableRow if it's where we're putting the ending selection. 708 // Don't remove m_endTableRow if it's where we're putting the ending selection.
709 if (!m_endingPosition.deprecatedNode()->isDescendantOf(m_endTableRow .get())) { 709 if (!m_endingPosition.anchorNode()->isDescendantOf(m_endTableRow.get ())) {
710 // FIXME: We probably shouldn't remove m_endTableRow unless it's fully selected, even if it is empty. 710 // FIXME: We probably shouldn't remove m_endTableRow unless it's fully selected, even if it is empty.
711 // We'll need to start adjusting the selection endpoints during deletion to know whether or not m_endTableRow 711 // We'll need to start adjusting the selection endpoints during deletion to know whether or not m_endTableRow
712 // was fully selected here. 712 // was fully selected here.
713 CompositeEditCommand::removeNode(m_endTableRow.get()); 713 CompositeEditCommand::removeNode(m_endTableRow.get());
714 } 714 }
715 } 715 }
716 } 716 }
717 717
718 void DeleteSelectionCommand::calculateTypingStyleAfterDelete() 718 void DeleteSelectionCommand::calculateTypingStyleAfterDelete()
719 { 719 {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_ selectionToDelete.visibleEnd()); 793 bool lineBreakAtEndOfSelectionToDelete = lineBreakExistsAtVisiblePosition(m_ selectionToDelete.visibleEnd());
794 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder 794 m_needPlaceholder = !rootWillStayOpenWithoutPlaceholder
795 && isStartOfParagraph(m_selectionToDelete.visibleStart(), CanCrossEditin gBoundary) 795 && isStartOfParagraph(m_selectionToDelete.visibleStart(), CanCrossEditin gBoundary)
796 && isEndOfParagraph(m_selectionToDelete.visibleEnd(), CanCrossEditingBou ndary) 796 && isEndOfParagraph(m_selectionToDelete.visibleEnd(), CanCrossEditingBou ndary)
797 && !lineBreakAtEndOfSelectionToDelete; 797 && !lineBreakAtEndOfSelectionToDelete;
798 if (m_needPlaceholder) { 798 if (m_needPlaceholder) {
799 // Don't need a placeholder when deleting a selection that starts just b efore a table 799 // Don't need a placeholder when deleting a selection that starts just b efore a table
800 // and ends inside it (we do need placeholders to hold open empty cells, but that's 800 // and ends inside it (we do need placeholders to hold open empty cells, but that's
801 // handled elsewhere). 801 // handled elsewhere).
802 if (Element* table = isLastPositionBeforeTable(m_selectionToDelete.visib leStart())) 802 if (Element* table = isLastPositionBeforeTable(m_selectionToDelete.visib leStart()))
803 if (m_selectionToDelete.end().deprecatedNode()->isDescendantOf(table )) 803 if (m_selectionToDelete.end().anchorNode()->isDescendantOf(table))
804 m_needPlaceholder = false; 804 m_needPlaceholder = false;
805 } 805 }
806 806
807 807
808 // set up our state 808 // set up our state
809 initializePositionData(); 809 initializePositionData();
810 810
811 bool lineBreakBeforeStart = lineBreakExistsAtVisiblePosition(VisiblePosition (m_upstreamStart).previous()); 811 bool lineBreakBeforeStart = lineBreakExistsAtVisiblePosition(VisiblePosition (m_upstreamStart).previous());
812 812
813 // Delete any text that may hinder our ability to fixup whitespace after the delete 813 // Delete any text that may hinder our ability to fixup whitespace after the delete
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 visitor->trace(m_deleteIntoBlockquoteStyle); 891 visitor->trace(m_deleteIntoBlockquoteStyle);
892 visitor->trace(m_startRoot); 892 visitor->trace(m_startRoot);
893 visitor->trace(m_endRoot); 893 visitor->trace(m_endRoot);
894 visitor->trace(m_startTableRow); 894 visitor->trace(m_startTableRow);
895 visitor->trace(m_endTableRow); 895 visitor->trace(m_endTableRow);
896 visitor->trace(m_temporaryPlaceholder); 896 visitor->trace(m_temporaryPlaceholder);
897 CompositeEditCommand::trace(visitor); 897 CompositeEditCommand::trace(visitor);
898 } 898 }
899 899
900 } // namespace blink 900 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/CompositeEditCommand.cpp ('k') | Source/core/editing/DragCaretController.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698