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

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: 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 if (!node->isStyledElement()) 472 if (!node->isStyledElement())
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);
adamk 2013/10/31 20:10:41 This doesn't look like much of a win to me, especi
Inactive 2013/10/31 20:33:26 Done.
486 483
487 if (newInlineStyle->conflictsWithImplicitStyleOfElement(htmlElem ent)) { 484 if (newInlineStyle->conflictsWithImplicitStyleOfElement(&htmlEle ment)) {
488 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;"> 485 // e.g. <b style="font-weight: normal;"> is converted to <sp an style="font-weight: normal;">
489 node = replaceElementWithSpanPreservingChildrenAndAttributes (htmlElement); 486 node = replaceElementWithSpanPreservingChildrenAndAttributes (PassRefPtr<HTMLElement>(htmlElement));
adamk 2013/10/31 20:10:41 ...this line
490 element = toElement(node); 487 element = toElement(node);
491 insertedNodes.didReplaceNode(htmlElement, node.get()); 488 insertedNodes.didReplaceNode(htmlElement, *node);
Inactive 2013/10/31 20:16:24 Ok, then I guess I will have to dereference here i
492 } else if (newInlineStyle->extractConflictingImplicitStyleOfAttr ibutes(htmlElement, EditingStyle::PreserveWritingDirection, 0, attributes, 489 } else if (newInlineStyle->extractConflictingImplicitStyleOfAttr ibutes(&htmlElement, EditingStyle::PreserveWritingDirection, 0, attributes,
493 EditingStyle::DoNotExtractMatchingStyle)) { 490 EditingStyle::DoNotExtractMatchingStyle)) {
494 // e.g. <font size="3" style="font-size: 20px;"> is converte d to <font style="font-size: 20px;"> 491 // 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++) 492 for (size_t i = 0; i < attributes.size(); i++)
496 removeNodeAttribute(element, attributes[i]); 493 removeNodeAttribute(element, attributes[i]);
497 } 494 }
498 } 495 }
499 496
500 ContainerNode* context = element->parentNode(); 497 ContainerNode* context = element->parentNode();
501 498
502 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region, 499 // 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>. 500 // 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); 501 Node* blockquoteNode = !context || isMailPasteAsQuotationNode(contex t) ? context : enclosingNodeOfType(firstPositionInNode(context), isMailBlockquot e, CanCrossEditingBoundary);
505 if (blockquoteNode) 502 if (blockquoteNode)
506 newInlineStyle->removeStyleFromRulesAndContext(element, document ().documentElement()); 503 newInlineStyle->removeStyleFromRulesAndContext(element, document ().documentElement());
507 504
508 newInlineStyle->removeStyleFromRulesAndContext(element, context); 505 newInlineStyle->removeStyleFromRulesAndContext(element, context);
509 } 506 }
510 507
511 if (!inlineStyle || newInlineStyle->isEmpty()) { 508 if (!inlineStyle || newInlineStyle->isEmpty()) {
512 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element) || isEmptyFontT ag(element, AllowNonEmptyStyleAttribute)) { 509 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element) || isEmptyFontT ag(element, AllowNonEmptyStyleAttribute)) {
513 insertedNodes.willRemoveNodePreservingChildren(element); 510 insertedNodes.willRemoveNodePreservingChildren(*element);
514 removeNodePreservingChildren(element); 511 removeNodePreservingChildren(element);
515 continue; 512 continue;
516 } 513 }
517 removeNodeAttribute(element, styleAttr); 514 removeNodeAttribute(element, styleAttr);
518 } else if (newInlineStyle->style()->propertyCount() != inlineStyle->prop ertyCount()) 515 } else if (newInlineStyle->style()->propertyCount() != inlineStyle->prop ertyCount())
519 setNodeAttribute(element, styleAttr, newInlineStyle->style()->asText ()); 516 setNodeAttribute(element, styleAttr, newInlineStyle->style()->asText ());
520 517
521 // FIXME: Tolerate differences in id, class, and style attributes. 518 // FIXME: Tolerate differences in id, class, and style attributes.
522 if (isNonTableCellHTMLBlockElement(element) && areIdenticalElements(elem ent, element->parentNode()) 519 if (isNonTableCellHTMLBlockElement(element) && areIdenticalElements(elem ent, element->parentNode())
523 && VisiblePosition(firstPositionInNode(element->parentNode())) == Vi siblePosition(firstPositionInNode(element)) 520 && VisiblePosition(firstPositionInNode(element->parentNode())) == Vi siblePosition(firstPositionInNode(element))
524 && VisiblePosition(lastPositionInNode(element->parentNode())) == Vis iblePosition(lastPositionInNode(element))) { 521 && VisiblePosition(lastPositionInNode(element->parentNode())) == Vis iblePosition(lastPositionInNode(element))) {
525 insertedNodes.willRemoveNodePreservingChildren(element); 522 insertedNodes.willRemoveNodePreservingChildren(*element);
526 removeNodePreservingChildren(element); 523 removeNodePreservingChildren(element);
527 continue; 524 continue;
528 } 525 }
529 526
530 if (element->parentNode() && element->parentNode()->rendererIsRichlyEdit able()) 527 if (element->parentNode() && element->parentNode()->rendererIsRichlyEdit able())
531 removeNodeAttribute(element, contenteditableAttr); 528 removeNodeAttribute(element, contenteditableAttr);
532 529
533 // WebKit used to not add display: inline and float: none on copy. 530 // WebKit used to not add display: inline and float: none on copy.
534 // Keep this code around for backward compatibility 531 // Keep this code around for backward compatibility
535 if (isLegacyAppleStyleSpan(element)) { 532 if (isLegacyAppleStyleSpan(element)) {
536 if (!element->firstChild()) { 533 if (!element->firstChild()) {
537 insertedNodes.willRemoveNodePreservingChildren(element); 534 insertedNodes.willRemoveNodePreservingChildren(*element);
538 removeNodePreservingChildren(element); 535 removeNodePreservingChildren(element);
539 continue; 536 continue;
540 } 537 }
541 // There are other styles that style rules can give to style spans, 538 // There are other styles that style rules can give to style spans,
542 // but these are the two important ones because they'll prevent 539 // but these are the two important ones because they'll prevent
543 // inserted content from appearing in the right paragraph. 540 // inserted content from appearing in the right paragraph.
544 // FIXME: Hyatt is concerned that selectively using display:inline w ill give inconsistent 541 // 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 542 // 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. 543 // in quirks mode (which Mail.app is always in). We should look for an alternative.
547 544
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 } 661 }
665 662
666 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins ertedNodes) 663 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins ertedNodes)
667 { 664 {
668 document().updateLayoutIgnorePendingStylesheets(); 665 document().updateLayoutIgnorePendingStylesheets();
669 666
670 Node* lastLeafInserted = insertedNodes.lastLeafInserted(); 667 Node* lastLeafInserted = insertedNodes.lastLeafInserted();
671 if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleRen derText(toText(lastLeafInserted)) 668 if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleRen derText(toText(lastLeafInserted))
672 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag) 669 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag)
673 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) { 670 && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) {
674 insertedNodes.willRemoveNode(lastLeafInserted); 671 insertedNodes.willRemoveNode(*lastLeafInserted);
675 removeNode(lastLeafInserted); 672 removeNode(lastLeafInserted);
676 } 673 }
677 674
678 // We don't have to make sure that firstNodeInserted isn't inside a select o r script element, because 675 // 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. 676 // it is a top level node in the fragment and the user can't insert into tho se elements.
680 Node* firstNodeInserted = insertedNodes.firstNodeInserted(); 677 Node* firstNodeInserted = insertedNodes.firstNodeInserted();
681 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleR enderText(toText(firstNodeInserted))) { 678 if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleR enderText(toText(firstNodeInserted))) {
682 insertedNodes.willRemoveNode(firstNodeInserted); 679 insertedNodes.willRemoveNode(*firstNodeInserted);
683 removeNode(firstNodeInserted); 680 removeNode(firstNodeInserted);
684 } 681 }
685 } 682 }
686 683
687 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const 684 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const
688 { 685 {
689 // FIXME: Why is this hack here? What's special about <select> tags? 686 // FIXME: Why is this hack here? What's special about <select> tags?
690 Node* enclosingSelect = enclosingNodeWithTag(m_endOfInsertedContent, selectT ag); 687 Node* enclosingSelect = enclosingNodeWithTag(m_endOfInsertedContent, selectT ag);
691 return enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endO fInsertedContent; 688 return enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endO fInsertedContent;
692 } 689 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 style->prepareToApplyAt(firstPositionInNode(context)); 777 style->prepareToApplyAt(firstPositionInNode(context));
781 778
782 // Remove block properties in the span's style. This prevents properties tha t probably have no effect 779 // 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 780 // currently from affecting blocks later if the style is cloned for a new bl ock element during a future
784 // editing operation. 781 // editing operation.
785 // FIXME: They *can* have an effect currently if blocks beneath the style sp an aren't individually marked 782 // 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. 783 // with block styles by the editing engine used to style them. WebKit doesn 't do this, but others might.
787 style->removeBlockProperties(); 784 style->removeBlockProperties();
788 785
789 if (style->isEmpty() || !wrappingStyleSpan->firstChild()) { 786 if (style->isEmpty() || !wrappingStyleSpan->firstChild()) {
790 insertedNodes.willRemoveNodePreservingChildren(wrappingStyleSpan); 787 insertedNodes.willRemoveNodePreservingChildren(*wrappingStyleSpan);
791 removeNodePreservingChildren(wrappingStyleSpan); 788 removeNodePreservingChildren(wrappingStyleSpan);
792 } else 789 } else
793 setNodeAttribute(wrappingStyleSpan, styleAttr, style->style()->asText()) ; 790 setNodeAttribute(wrappingStyleSpan, styleAttr, style->style()->asText()) ;
794 } 791 }
795 792
796 void ReplaceSelectionCommand::mergeEndIfNeeded() 793 void ReplaceSelectionCommand::mergeEndIfNeeded()
797 { 794 {
798 if (!m_shouldMergeEnd) 795 if (!m_shouldMergeEnd)
799 return; 796 return;
800 797
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 // position forward without changing the visible position so we're still at the same visible location, but 1016 // position forward without changing the visible position so we're still at the same visible location, but
1020 // outside of preceding tags. 1017 // outside of preceding tags.
1021 insertionPos = positionAvoidingPrecedingNodes(insertionPos); 1018 insertionPos = positionAvoidingPrecedingNodes(insertionPos);
1022 1019
1023 // Paste into run of tabs splits the tab span. 1020 // Paste into run of tabs splits the tab span.
1024 insertionPos = positionOutsideTabSpan(insertionPos); 1021 insertionPos = positionOutsideTabSpan(insertionPos);
1025 1022
1026 bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertion Pos); 1023 bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertion Pos);
1027 1024
1028 // We're finished if there is nothing to add. 1025 // We're finished if there is nothing to add.
1029 if (fragment.isEmpty() || !fragment.firstChild()) 1026 if (fragment.isEmpty() || !fragment.firstChild())
Inactive 2013/10/31 20:16:24 If fragment.firstChild() was null, we would have r
1030 return; 1027 return;
1031 1028
1032 // If we are not trying to match the destination style we prefer a position 1029 // If we are not trying to match the destination style we prefer a position
1033 // that is outside inline elements that provide style. 1030 // that is outside inline elements that provide style.
1034 // This way we can produce a less verbose markup. 1031 // This way we can produce a less verbose markup.
1035 // We can skip this optimization for fragments not wrapped in one of 1032 // We can skip this optimization for fragments not wrapped in one of
1036 // our style spans and for positions inside list items 1033 // our style spans and for positions inside list items
1037 // since insertAsListItems already does the right thing. 1034 // since insertAsListItems already does the right thing.
1038 if (!m_matchStyle && !enclosingList(insertionPos.containerNode())) { 1035 if (!m_matchStyle && !enclosingList(insertionPos.containerNode())) {
1039 if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInC ontainerNode() && !insertionPos.atLastEditingPositionForNode()) { 1036 if (insertionPos.containerNode()->isTextNode() && insertionPos.offsetInC ontainerNode() && !insertionPos.atLastEditingPositionForNode()) {
(...skipping 20 matching lines...) Expand all
1060 // 3) Merge the start of the added content with the content before the posit ion being pasted into. 1057 // 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, 1058 // 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 1059 // 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 1060 // end of the selection that was pasted into, or c) handle an interchange ne wline at the end of the
1064 // incoming fragment. 1061 // incoming fragment.
1065 // 5) Add spaces for smart replace. 1062 // 5) Add spaces for smart replace.
1066 // 6) Select the replacement if requested, and match style if requested. 1063 // 6) Select the replacement if requested, and match style if requested.
1067 1064
1068 InsertedNodes insertedNodes; 1065 InsertedNodes insertedNodes;
1069 RefPtr<Node> refNode = fragment.firstChild(); 1066 RefPtr<Node> refNode = fragment.firstChild();
1067 ASSERT(refNode);
adamk 2013/10/31 20:10:41 Huh, I wonder why we know this here. The editing c
1070 RefPtr<Node> node = refNode->nextSibling(); 1068 RefPtr<Node> node = refNode->nextSibling();
1071 1069
1072 fragment.removeNode(refNode); 1070 fragment.removeNode(refNode);
1073 1071
1074 Node* blockStart = enclosingBlock(insertionPos.deprecatedNode()); 1072 Node* blockStart = enclosingBlock(insertionPos.deprecatedNode());
1075 if ((isListElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListElement(refNode->firstChild()))) 1073 if ((isListElement(refNode.get()) || (isLegacyAppleStyleSpan(refNode.get()) && isListElement(refNode->firstChild())))
1076 && blockStart && blockStart->renderer()->isListItem()) 1074 && blockStart && blockStart->renderer()->isListItem())
1077 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes); 1075 refNode = insertAsListItems(toHTMLElement(refNode), blockStart, insertio nPos, insertedNodes);
1078 else { 1076 else {
1079 insertNodeAt(refNode, insertionPos); 1077 insertNodeAt(refNode, insertionPos);
1080 insertedNodes.respondToNodeInsertion(refNode.get()); 1078 insertedNodes.respondToNodeInsertion(*refNode);
1081 } 1079 }
1082 1080
1083 // Mutation events (bug 22634) may have already removed the inserted content 1081 // Mutation events (bug 22634) may have already removed the inserted content
1084 if (!refNode->inDocument()) 1082 if (!refNode->inDocument())
1085 return; 1083 return;
1086 1084
1087 bool plainTextFragment = isPlainTextMarkup(refNode.get()); 1085 bool plainTextFragment = isPlainTextMarkup(refNode.get());
1088 1086
1089 while (node) { 1087 while (node) {
1090 RefPtr<Node> next = node->nextSibling(); 1088 RefPtr<Node> next = node->nextSibling();
1091 fragment.removeNode(node.get()); 1089 fragment.removeNode(node.get());
1092 insertNodeAfter(node, refNode.get()); 1090 insertNodeAfter(node, refNode);
1093 insertedNodes.respondToNodeInsertion(node.get()); 1091 insertedNodes.respondToNodeInsertion(*node);
1094 1092
1095 // Mutation events (bug 22634) may have already removed the inserted con tent 1093 // Mutation events (bug 22634) may have already removed the inserted con tent
1096 if (!node->inDocument()) 1094 if (!node->inDocument())
1097 return; 1095 return;
1098 1096
1099 refNode = node; 1097 refNode = node;
1100 if (node && plainTextFragment) 1098 if (node && plainTextFragment)
1101 plainTextFragment = isPlainTextMarkup(node.get()); 1099 plainTextFragment = isPlainTextMarkup(node.get());
1102 node = next; 1100 node = next;
1103 } 1101 }
1104 1102
1105 removeUnrenderedTextNodesAtEnds(insertedNodes); 1103 removeUnrenderedTextNodesAtEnds(insertedNodes);
1106 1104
1107 if (!handledStyleSpans) 1105 if (!handledStyleSpans)
1108 handleStyleSpans(insertedNodes); 1106 handleStyleSpans(insertedNodes);
1109 1107
1110 // Mutation events (bug 20161) may have already removed the inserted content 1108 // Mutation events (bug 20161) may have already removed the inserted content
1111 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted() ->inDocument()) 1109 if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted() ->inDocument())
1112 return; 1110 return;
1113 1111
1114 VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(inserte dNodes.firstNodeInserted()); 1112 VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(inserte dNodes.firstNodeInserted());
1115 1113
1116 // We inserted before the startBlock to prevent nesting, and the content bef ore the startBlock wasn't in its own block and 1114 // 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. 1115 // 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)) 1116 if (startBlock && insertionPos.deprecatedNode() == startBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < startBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
1119 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent()); 1117 insertNodeAt(createBreakElement(document()).get(), startOfInsertedConten t.deepEquivalent());
1120 1118
1121 if (endBR && (plainTextFragment || shouldRemoveEndBR(endBR, originalVisPosBe foreEndBR))) { 1119 if (endBR && (plainTextFragment || shouldRemoveEndBR(endBR, originalVisPosBe foreEndBR))) {
1122 RefPtr<Node> parent = endBR->parentNode(); 1120 RefPtr<Node> parent = endBR->parentNode();
1123 insertedNodes.willRemoveNode(endBR); 1121 insertedNodes.willRemoveNode(*endBR);
1124 removeNode(endBR); 1122 removeNode(endBR);
1125 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) { 1123 if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) {
1126 insertedNodes.willRemoveNode(nodeToRemove); 1124 insertedNodes.willRemoveNode(*nodeToRemove);
1127 removeNode(nodeToRemove); 1125 removeNode(nodeToRemove);
1128 } 1126 }
1129 } 1127 }
1130 1128
1131 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); 1129 makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes);
1132 1130
1133 removeRedundantStylesAndKeepStyleSpanInline(insertedNodes); 1131 removeRedundantStylesAndKeepStyleSpanInline(insertedNodes);
1134 1132
1135 if (m_sanitizeFragment) 1133 if (m_sanitizeFragment)
1136 applyCommandToComposite(SimplifyMarkupCommand::create(document(), insert edNodes.firstNodeInserted(), insertedNodes.pastLastLeaf())); 1134 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(); 1423 int textNodeOffset = insertPos.offsetInContainerNode();
1426 if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0) 1424 if (insertPos.deprecatedNode()->isTextNode() && textNodeOffset > 0)
1427 splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset); 1425 splitTextNode(toText(insertPos.deprecatedNode()), textNodeOffset);
1428 splitTreeToNode(insertPos.deprecatedNode(), lastNode, true); 1426 splitTreeToNode(insertPos.deprecatedNode(), lastNode, true);
1429 } 1427 }
1430 1428
1431 while (RefPtr<Node> listItem = listElement->firstChild()) { 1429 while (RefPtr<Node> listItem = listElement->firstChild()) {
1432 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION); 1430 listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION);
1433 if (isStart || isMiddle) { 1431 if (isStart || isMiddle) {
1434 insertNodeBefore(listItem, lastNode); 1432 insertNodeBefore(listItem, lastNode);
1435 insertedNodes.respondToNodeInsertion(listItem.get()); 1433 insertedNodes.respondToNodeInsertion(*listItem);
1436 } else if (isEnd) { 1434 } else if (isEnd) {
1437 insertNodeAfter(listItem, lastNode); 1435 insertNodeAfter(listItem, lastNode);
1438 insertedNodes.respondToNodeInsertion(listItem.get()); 1436 insertedNodes.respondToNodeInsertion(*listItem);
1439 lastNode = listItem.get(); 1437 lastNode = listItem.get();
1440 } else 1438 } else
1441 ASSERT_NOT_REACHED(); 1439 ASSERT_NOT_REACHED();
1442 } 1440 }
1443 if (isStart || isMiddle) 1441 if (isStart || isMiddle)
1444 lastNode = lastNode->previousSibling(); 1442 lastNode = lastNode->previousSibling();
1445 return lastNode; 1443 return lastNode;
1446 } 1444 }
1447 1445
1448 void ReplaceSelectionCommand::updateNodesInserted(Node *node) 1446 void ReplaceSelectionCommand::updateNodesInserted(Node *node)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1487 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get()); 1485 removeNodeAndPruneAncestors(nodeAfterInsertionPos.get());
1488 1486
1489 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d); 1487 VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, en d);
1490 1488
1491 setEndingSelection(selectionAfterReplace); 1489 setEndingSelection(selectionAfterReplace);
1492 1490
1493 return true; 1491 return true;
1494 } 1492 }
1495 1493
1496 } // namespace WebCore 1494 } // 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