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

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

Issue 54363006: Have ReplaceSelectionCommand::InsertedNodes API take references in argument (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase on master Created 7 years, 1 month 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
« no previous file with comments | « Source/core/editing/ReplaceSelectionCommand.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2009, 2010, 2011 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 while (node) { 315 while (node) {
316 RefPtr<Node> next = NodeTraversal::next(node); 316 RefPtr<Node> next = NodeTraversal::next(node);
317 if (isInterchangeConvertedSpaceSpan(node)) { 317 if (isInterchangeConvertedSpaceSpan(node)) {
318 next = NodeTraversal::nextSkippingChildren(node); 318 next = NodeTraversal::nextSkippingChildren(node);
319 removeNodePreservingChildren(node); 319 removeNodePreservingChildren(node);
320 } 320 }
321 node = next.get(); 321 node = next.get();
322 } 322 }
323 } 323 }
324 324
325 inline void ReplaceSelectionCommand::InsertedNodes::respondToNodeInsertion(Node* node) 325 inline void ReplaceSelectionCommand::InsertedNodes::respondToNodeInsertion(Node& node)
326 { 326 {
327 if (!node) 327 if (!m_firstNodeInserted)
328 return; 328 m_firstNodeInserted = &node;
329 329
330 if (!m_firstNodeInserted) 330 m_lastNodeInserted = &node;
331 m_firstNodeInserted = node;
332
333 m_lastNodeInserted = node;
334 } 331 }
335 332
336 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChil dren(Node* node) 333 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChil dren(Node& node)
337 { 334 {
338 if (m_firstNodeInserted == node) 335 if (m_firstNodeInserted == node)
339 m_firstNodeInserted = NodeTraversal::next(node); 336 m_firstNodeInserted = NodeTraversal::next(&node);
340 if (m_lastNodeInserted == node) 337 if (m_lastNodeInserted == node)
341 m_lastNodeInserted = node->lastChild() ? node->lastChild() : NodeTravers al::nextSkippingChildren(node); 338 m_lastNodeInserted = node.lastChild() ? node.lastChild() : NodeTraversal ::nextSkippingChildren(&node);
342 } 339 }
343 340
344 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node* node) 341 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node& node)
345 { 342 {
346 if (m_firstNodeInserted == node && m_lastNodeInserted == node) { 343 if (m_firstNodeInserted == node && m_lastNodeInserted == node) {
347 m_firstNodeInserted = 0; 344 m_firstNodeInserted = 0;
348 m_lastNodeInserted = 0; 345 m_lastNodeInserted = 0;
349 } else if (m_firstNodeInserted == node) 346 } else if (m_firstNodeInserted == node)
350 m_firstNodeInserted = NodeTraversal::nextSkippingChildren(m_firstNodeIns erted.get()); 347 m_firstNodeInserted = NodeTraversal::nextSkippingChildren(m_firstNodeIns erted.get());
351 else if (m_lastNodeInserted == node) 348 else if (m_lastNodeInserted == node)
352 m_lastNodeInserted = NodeTraversal::previousSkippingChildren(m_lastNodeI nserted.get()); 349 m_lastNodeInserted = NodeTraversal::previousSkippingChildren(m_lastNodeI nserted.get());
353 } 350 }
354 351
355 inline void ReplaceSelectionCommand::InsertedNodes::didReplaceNode(Node* node, N ode* newNode) 352 inline void ReplaceSelectionCommand::InsertedNodes::didReplaceNode(Node& node, N ode& newNode)
356 { 353 {
357 if (m_firstNodeInserted == node) 354 if (m_firstNodeInserted == node)
358 m_firstNodeInserted = newNode; 355 m_firstNodeInserted = &newNode;
359 if (m_lastNodeInserted == node) 356 if (m_lastNodeInserted == node)
360 m_lastNodeInserted = newNode; 357 m_lastNodeInserted = &newNode;
361 } 358 }
362 359
363 ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, PassRefPtr< DocumentFragment> fragment, CommandOptions options, EditAction editAction) 360 ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, PassRefPtr< DocumentFragment> fragment, CommandOptions options, EditAction editAction)
364 : CompositeEditCommand(document) 361 : CompositeEditCommand(document)
365 , m_selectReplacement(options & SelectReplacement) 362 , m_selectReplacement(options & SelectReplacement)
366 , m_smartReplace(options & SmartReplace) 363 , m_smartReplace(options & SmartReplace)
367 , m_matchStyle(options & MatchStyle) 364 , m_matchStyle(options & MatchStyle)
368 , m_documentFragment(fragment) 365 , m_documentFragment(fragment)
369 , m_preventNesting(options & PreventNesting) 366 , m_preventNesting(options & PreventNesting)
370 , m_movingParagraph(options & MovingParagraph) 367 , m_movingParagraph(options & MovingParagraph)
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 continue; 473 continue;
477 474
478 Element* element = toElement(node); 475 Element* element = toElement(node);
479 476
480 const StylePropertySet* inlineStyle = element->inlineStyle(); 477 const StylePropertySet* inlineStyle = element->inlineStyle();
481 RefPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle); 478 RefPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle);
482 if (inlineStyle) { 479 if (inlineStyle) {
483 if (element->isHTMLElement()) { 480 if (element->isHTMLElement()) {
484 Vector<QualifiedName> attributes; 481 Vector<QualifiedName> attributes;
485 HTMLElement* htmlElement = toHTMLElement(element); 482 HTMLElement* htmlElement = toHTMLElement(element);
483 ASSERT(htmlElement);
486 484
487 if (newInlineStyle->conflictsWithImplicitStyleOfElement(htmlElem ent)) { 485 if (newInlineStyle->conflictsWithImplicitStyleOfElement(htmlElem ent)) {
488 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;"> 486 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;">
489 node = replaceElementWithSpanPreservingChildrenAndAttributes (htmlElement); 487 node = replaceElementWithSpanPreservingChildrenAndAttributes (htmlElement);
490 element = toElement(node); 488 element = toElement(node);
491 insertedNodes.didReplaceNode(htmlElement, node.get()); 489 insertedNodes.didReplaceNode(*htmlElement, *node);
492 } else if (newInlineStyle->extractConflictingImplicitStyleOfAttr ibutes(htmlElement, EditingStyle::PreserveWritingDirection, 0, attributes, 490 } else if (newInlineStyle->extractConflictingImplicitStyleOfAttr ibutes(htmlElement, EditingStyle::PreserveWritingDirection, 0, attributes,
493 EditingStyle::DoNotExtractMatchingStyle)) { 491 EditingStyle::DoNotExtractMatchingStyle)) {
494 // e.g. <font size="3" style="font-size: 20px;"> is converte d to <font style="font-size: 20px;"> 492 // e.g. <font size="3" style="font-size: 20px;"> is converte d to <font style="font-size: 20px;">
495 for (size_t i = 0; i < attributes.size(); i++) 493 for (size_t i = 0; i < attributes.size(); i++)
496 removeNodeAttribute(element, attributes[i]); 494 removeNodeAttribute(element, attributes[i]);
497 } 495 }
498 } 496 }
499 497
500 ContainerNode* context = element->parentNode(); 498 ContainerNode* context = element->parentNode();
501 499
502 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region, 500 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region,
503 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. 501 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
504 Node* blockquoteNode = !context || isMailPasteAsQuotationNode(contex t) ? context : enclosingNodeOfType(firstPositionInNode(context), isMailBlockquot e, CanCrossEditingBoundary); 502 Node* blockquoteNode = !context || isMailPasteAsQuotationNode(contex t) ? context : enclosingNodeOfType(firstPositionInNode(context), isMailBlockquot e, CanCrossEditingBoundary);
505 if (blockquoteNode) 503 if (blockquoteNode)
506 newInlineStyle->removeStyleFromRulesAndContext(element, document ().documentElement()); 504 newInlineStyle->removeStyleFromRulesAndContext(element, document ().documentElement());
507 505
508 newInlineStyle->removeStyleFromRulesAndContext(element, context); 506 newInlineStyle->removeStyleFromRulesAndContext(element, context);
509 } 507 }
510 508
511 if (!inlineStyle || newInlineStyle->isEmpty()) { 509 if (!inlineStyle || newInlineStyle->isEmpty()) {
512 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element) || isEmptyFontT ag(element, AllowNonEmptyStyleAttribute)) { 510 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element) || isEmptyFontT ag(element, AllowNonEmptyStyleAttribute)) {
513 insertedNodes.willRemoveNodePreservingChildren(element); 511 insertedNodes.willRemoveNodePreservingChildren(*element);
514 removeNodePreservingChildren(element); 512 removeNodePreservingChildren(element);
515 continue; 513 continue;
516 } 514 }
517 removeNodeAttribute(element, styleAttr); 515 removeNodeAttribute(element, styleAttr);
518 } else if (newInlineStyle->style()->propertyCount() != inlineStyle->prop ertyCount()) 516 } else if (newInlineStyle->style()->propertyCount() != inlineStyle->prop ertyCount())
519 setNodeAttribute(element, styleAttr, newInlineStyle->style()->asText ()); 517 setNodeAttribute(element, styleAttr, newInlineStyle->style()->asText ());
520 518
521 // FIXME: Tolerate differences in id, class, and style attributes. 519 // FIXME: Tolerate differences in id, class, and style attributes.
522 if (isNonTableCellHTMLBlockElement(element) && areIdenticalElements(elem ent, element->parentNode()) 520 if (isNonTableCellHTMLBlockElement(element) && areIdenticalElements(elem ent, element->parentNode())
523 && VisiblePosition(firstPositionInNode(element->parentNode())) == Vi siblePosition(firstPositionInNode(element)) 521 && VisiblePosition(firstPositionInNode(element->parentNode())) == Vi siblePosition(firstPositionInNode(element))
524 && VisiblePosition(lastPositionInNode(element->parentNode())) == Vis iblePosition(lastPositionInNode(element))) { 522 && VisiblePosition(lastPositionInNode(element->parentNode())) == Vis iblePosition(lastPositionInNode(element))) {
525 insertedNodes.willRemoveNodePreservingChildren(element); 523 insertedNodes.willRemoveNodePreservingChildren(*element);
526 removeNodePreservingChildren(element); 524 removeNodePreservingChildren(element);
527 continue; 525 continue;
528 } 526 }
529 527
530 if (element->parentNode() && element->parentNode()->rendererIsRichlyEdit able()) 528 if (element->parentNode() && element->parentNode()->rendererIsRichlyEdit able())
531 removeNodeAttribute(element, contenteditableAttr); 529 removeNodeAttribute(element, contenteditableAttr);
532 530
533 // WebKit used to not add display: inline and float: none on copy. 531 // WebKit used to not add display: inline and float: none on copy.
534 // Keep this code around for backward compatibility 532 // Keep this code around for backward compatibility
535 if (isLegacyAppleStyleSpan(element)) { 533 if (isLegacyAppleStyleSpan(element)) {
536 if (!element->firstChild()) { 534 if (!element->firstChild()) {
537 insertedNodes.willRemoveNodePreservingChildren(element); 535 insertedNodes.willRemoveNodePreservingChildren(*element);
538 removeNodePreservingChildren(element); 536 removeNodePreservingChildren(element);
539 continue; 537 continue;
540 } 538 }
541 // There are other styles that style rules can give to style spans, 539 // There are other styles that style rules can give to style spans,
542 // but these are the two important ones because they'll prevent 540 // but these are the two important ones because they'll prevent
543 // inserted content from appearing in the right paragraph. 541 // inserted content from appearing in the right paragraph.
544 // FIXME: Hyatt is concerned that selectively using display:inline w ill give inconsistent 542 // FIXME: Hyatt is concerned that selectively using display:inline w ill give inconsistent
545 // results. We already know one issue because td elements ignore the ir display property 543 // results. We already know one issue because td elements ignore the ir display property
546 // in quirks mode (which Mail.app is always in). We should look for an alternative. 544 // in quirks mode (which Mail.app is always in). We should look for an alternative.
547 545
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 } 662 }
665 663
666 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins ertedNodes) 664 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins ertedNodes)
667 { 665 {
668 document().updateLayoutIgnorePendingStylesheets(); 666 document().updateLayoutIgnorePendingStylesheets();
669 667
670 Node& lastLeafInserted = insertedNodes.lastLeafInserted(); 668 Node& lastLeafInserted = insertedNodes.lastLeafInserted();
671 if (lastLeafInserted.isTextNode() && !nodeHasVisibleRenderText(toText(lastLe afInserted)) 669 if (lastLeafInserted.isTextNode() && !nodeHasVisibleRenderText(toText(lastLe afInserted))
672 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(&lastLeafInserted), selectTag) 670 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(&lastLeafInserted), selectTag)
673 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(&lastLeafInserted), scriptTag)) { 671 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(&lastLeafInserted), scriptTag)) {
674 insertedNodes.willRemoveNode(&lastLeafInserted); 672 insertedNodes.willRemoveNode(lastLeafInserted);
675 removeNode(&lastLeafInserted); 673 removeNode(&lastLeafInserted);
676 } 674 }
677 675
678 // We don't have to make sure that firstNodeInserted isn't inside a select o r script element, because 676 // We don't have to make sure that firstNodeInserted isn't inside a select o r script element, because
679 // it is a top level node in the fragment and the user can't insert into tho se elements. 677 // it is a top level node in the fragment and the user can't insert into tho se elements.
680 Node* firstNodeInserted = insertedNodes.firstNodeInserted(); 678 Node* firstNodeInserted = insertedNodes.firstNodeInserted();
681 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleR enderText(toText(*firstNodeInserted))) { 679 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleR enderText(toText(*firstNodeInserted))) {
682 insertedNodes.willRemoveNode(firstNodeInserted); 680 insertedNodes.willRemoveNode(*firstNodeInserted);
683 removeNode(firstNodeInserted); 681 removeNode(firstNodeInserted);
684 } 682 }
685 } 683 }
686 684
687 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const 685 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const
688 { 686 {
689 // FIXME: Why is this hack here? What's special about <select> tags? 687 // FIXME: Why is this hack here? What's special about <select> tags?
690 Node* enclosingSelect = enclosingNodeWithTag(m_endOfInsertedContent, selectT ag); 688 Node* enclosingSelect = enclosingNodeWithTag(m_endOfInsertedContent, selectT ag);
691 return enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endO fInsertedContent; 689 return enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endO fInsertedContent;
692 } 690 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 style->prepareToApplyAt(firstPositionInNode(context)); 778 style->prepareToApplyAt(firstPositionInNode(context));
781 779
782 // Remove block properties in the span's style. This prevents properties tha t probably have no effect 780 // Remove block properties in the span's style. This prevents properties tha t probably have no effect
783 // currently from affecting blocks later if the style is cloned for a new bl ock element during a future 781 // currently from affecting blocks later if the style is cloned for a new bl ock element during a future
784 // editing operation. 782 // editing operation.
785 // FIXME: They *can* have an effect currently if blocks beneath the style sp an aren't individually marked 783 // FIXME: They *can* have an effect currently if blocks beneath the style sp an aren't individually marked
786 // with block styles by the editing engine used to style them. WebKit doesn 't do this, but others might. 784 // with block styles by the editing engine used to style them. WebKit doesn 't do this, but others might.
787 style->removeBlockProperties(); 785 style->removeBlockProperties();
788 786
789 if (style->isEmpty() || !wrappingStyleSpan->firstChild()) { 787 if (style->isEmpty() || !wrappingStyleSpan->firstChild()) {
790 insertedNodes.willRemoveNodePreservingChildren(wrappingStyleSpan); 788 insertedNodes.willRemoveNodePreservingChildren(*wrappingStyleSpan);
791 removeNodePreservingChildren(wrappingStyleSpan); 789 removeNodePreservingChildren(wrappingStyleSpan);
792 } else 790 } else
793 setNodeAttribute(wrappingStyleSpan, styleAttr, style->style()->asText()) ; 791 setNodeAttribute(wrappingStyleSpan, styleAttr, style->style()->asText()) ;
794 } 792 }
795 793
796 void ReplaceSelectionCommand::mergeEndIfNeeded() 794 void ReplaceSelectionCommand::mergeEndIfNeeded()
797 { 795 {
798 if (!m_shouldMergeEnd) 796 if (!m_shouldMergeEnd)
799 return; 797 return;
800 798
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 // 3) Merge the start of the added content with the content before the posit ion being pasted into. 1058 // 3) Merge the start of the added content with the content before the posit ion being pasted into.
1061 // 4) Do one of the following: a) expand the last br if the fragment ends wi th one and it collapsed, 1059 // 4) Do one of the following: a) expand the last br if the fragment ends wi th one and it collapsed,
1062 // b) merge the last paragraph of the incoming fragment with the paragraph t hat contained the 1060 // b) merge the last paragraph of the incoming fragment with the paragraph t hat contained the
1063 // end of the selection that was pasted into, or c) handle an interchange ne wline at the end of the 1061 // end of the selection that was pasted into, or c) handle an interchange ne wline at the end of the
1064 // incoming fragment. 1062 // incoming fragment.
1065 // 5) Add spaces for smart replace. 1063 // 5) Add spaces for smart replace.
1066 // 6) Select the replacement if requested, and match style if requested. 1064 // 6) Select the replacement if requested, and match style if requested.
1067 1065
1068 InsertedNodes insertedNodes; 1066 InsertedNodes insertedNodes;
1069 RefPtr<Node> refNode = fragment.firstChild(); 1067 RefPtr<Node> refNode = fragment.firstChild();
1068 ASSERT(refNode);
1070 RefPtr<Node> node = refNode->nextSibling(); 1069 RefPtr<Node> node = refNode->nextSibling();
1071 1070
1072 fragment.removeNode(refNode); 1071 fragment.removeNode(refNode);
1073 1072
1074 Node* blockStart = enclosingBlock(insertionPos.deprecatedNode()); 1073 Node* blockStart = enclosingBlock(insertionPos.deprecatedNode());
1075 if ((isListElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListElement(refNode->firstChild()))) 1074 if ((isListElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListElement(refNode->firstChild())))
1076 && blockStart && blockStart->renderer()->isListItem()) 1075 && blockStart && blockStart->renderer()->isListItem())
1077 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes); 1076 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes);
1078 else { 1077 else {
1079 insertNodeAt(refNode, insertionPos); 1078 insertNodeAt(refNode, insertionPos);
1080 insertedNodes.respondToNodeInsertion(refNode.get()); 1079 insertedNodes.respondToNodeInsertion(*refNode);
1081 } 1080 }
1082 1081
1083 // Mutation events (bug 22634) may have already removed the inserted content 1082 // Mutation events (bug 22634) may have already removed the inserted content
1084 if (!refNode->inDocument()) 1083 if (!refNode->inDocument())
1085 return; 1084 return;
1086 1085
1087 bool plainTextFragment = isPlainTextMarkup(refNode.get()); 1086 bool plainTextFragment = isPlainTextMarkup(refNode.get());
1088 1087
1089 while (node) { 1088 while (node) {
1090 RefPtr<Node> next = node->nextSibling(); 1089 RefPtr<Node> next = node->nextSibling();
1091 fragment.removeNode(node.get()); 1090 fragment.removeNode(node.get());
1092 insertNodeAfter(node, refNode.get()); 1091 insertNodeAfter(node, refNode);
1093 insertedNodes.respondToNodeInsertion(node.get()); 1092 insertedNodes.respondToNodeInsertion(*node);
1094 1093
1095 // Mutation events (bug 22634) may have already removed the inserted con tent 1094 // Mutation events (bug 22634) may have already removed the inserted con tent
1096 if (!node->inDocument()) 1095 if (!node->inDocument())
1097 return; 1096 return;
1098 1097
1099 refNode = node; 1098 refNode = node;
1100 if (node && plainTextFragment) 1099 if (node && plainTextFragment)
1101 plainTextFragment = isPlainTextMarkup(node.get()); 1100 plainTextFragment = isPlainTextMarkup(node.get());
1102 node = next; 1101 node = next;
1103 } 1102 }
1104 1103
1105 removeUnrenderedTextNodesAtEnds(insertedNodes); 1104 removeUnrenderedTextNodesAtEnds(insertedNodes);
1106 1105
1107 if (!handledStyleSpans) 1106 if (!handledStyleSpans)
1108 handleStyleSpans(insertedNodes); 1107 handleStyleSpans(insertedNodes);
1109 1108
1110 // Mutation events (bug 20161) may have already removed the inserted content 1109 // Mutation events (bug 20161) may have already removed the inserted content
1111 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted() ->inDocument()) 1110 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted() ->inDocument())
1112 return; 1111 return;
1113 1112
1114 VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(inserte dNodes.firstNodeInserted()); 1113 VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(inserte dNodes.firstNodeInserted());
1115 1114
1116 // We inserted before the startBlock to prevent nesting, and the content bef ore the startBlock wasn't in its own block and 1115 // We inserted before the startBlock to prevent nesting, and the content bef ore the startBlock wasn't in its own block and
1117 // didn't have a br after it, so the inserted content ended up in the same p aragraph. 1116 // didn't have a br after it, so the inserted content ended up in the same p aragraph.
1118 if (startBlock && insertionPos.deprecatedNode() == startBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < startBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent)) 1117 if (startBlock && insertionPos.deprecatedNode() == startBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < startBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
1119 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent()); 1118 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent());
1120 1119
1121 if (endBR && (plainTextFragment || shouldRemoveEndBR(endBR, originalVisPosBe foreEndBR))) { 1120 if (endBR && (plainTextFragment || shouldRemoveEndBR(endBR, originalVisPosBe foreEndBR))) {
1122 RefPtr<Node> parent = endBR->parentNode(); 1121 RefPtr<Node> parent = endBR->parentNode();
1123 insertedNodes.willRemoveNode(endBR); 1122 insertedNodes.willRemoveNode(*endBR);
1124 removeNode(endBR); 1123 removeNode(endBR);
1125 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { 1124 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) {
1126 insertedNodes.willRemoveNode(nodeToRemove); 1125 insertedNodes.willRemoveNode(*nodeToRemove);
1127 removeNode(nodeToRemove); 1126 removeNode(nodeToRemove);
1128 } 1127 }
1129 } 1128 }
1130 1129
1131 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); 1130 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes);
1132 1131
1133 removeRedundantStylesAndKeepStyleSpanInline(insertedNodes); 1132 removeRedundantStylesAndKeepStyleSpanInline(insertedNodes);
1134 1133
1135 if (m_sanitizeFragment) 1134 if (m_sanitizeFragment)
1136 applyCommandToComposite(SimplifyMarkupCommand::create(document(), insert edNodes.firstNodeInserted(), insertedNodes.pastLastLeaf())); 1135 applyCommandToComposite(SimplifyMarkupCommand::create(document(), insert edNodes.firstNodeInserted(), insertedNodes.pastLastLeaf()));
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 int textNodeOffset = insertPos.offsetInContainerNode(); 1424 int textNodeOffset = insertPos.offsetInContainerNode();
1426 if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0) 1425 if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0)
1427 splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset); 1426 splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset);
1428 splitTreeToNode(insertPos.deprecatedNode(), lastNode, true); 1427 splitTreeToNode(insertPos.deprecatedNode(), lastNode, true);
1429 } 1428 }
1430 1429
1431 while (RefPtr<Node> listItem = listElement->firstChild()) { 1430 while (RefPtr<Node> listItem = listElement->firstChild()) {
1432 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); 1431 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION);
1433 if (isStart || isMiddle) { 1432 if (isStart || isMiddle) {
1434 insertNodeBefore(listItem, lastNode); 1433 insertNodeBefore(listItem, lastNode);
1435 insertedNodes.respondToNodeInsertion(listItem.get()); 1434 insertedNodes.respondToNodeInsertion(*listItem);
1436 } else if (isEnd) { 1435 } else if (isEnd) {
1437 insertNodeAfter(listItem, lastNode); 1436 insertNodeAfter(listItem, lastNode);
1438 insertedNodes.respondToNodeInsertion(listItem.get()); 1437 insertedNodes.respondToNodeInsertion(*listItem);
1439 lastNode = listItem.get(); 1438 lastNode = listItem.get();
1440 } else 1439 } else
1441 ASSERT_NOT_REACHED(); 1440 ASSERT_NOT_REACHED();
1442 } 1441 }
1443 if (isStart || isMiddle) 1442 if (isStart || isMiddle)
1444 lastNode = lastNode->previousSibling(); 1443 lastNode = lastNode->previousSibling();
1445 return lastNode; 1444 return lastNode;
1446 } 1445 }
1447 1446
1448 void ReplaceSelectionCommand::updateNodesInserted(Node *node) 1447 void ReplaceSelectionCommand::updateNodesInserted(Node *node)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); 1486 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get());
1488 1487
1489 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d); 1488 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d);
1490 1489
1491 setEndingSelection(selectionAfterReplace); 1490 setEndingSelection(selectionAfterReplace);
1492 1491
1493 return true; 1492 return true;
1494 } 1493 }
1495 1494
1496 } // namespace WebCore 1495 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/editing/ReplaceSelectionCommand.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698