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

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

Issue 417113011: Cast highestEnclosingNodeOfType() return value to tighter type (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase Created 6 years, 4 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 | Annotate | Revision Log
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 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 , m_editAction(editAction) 377 , m_editAction(editAction)
378 , m_sanitizeFragment(options & SanitizeFragment) 378 , m_sanitizeFragment(options & SanitizeFragment)
379 , m_shouldMergeEnd(false) 379 , m_shouldMergeEnd(false)
380 { 380 {
381 } 381 }
382 382
383 static bool hasMatchingQuoteLevel(VisiblePosition endOfExistingContent, VisibleP osition endOfInsertedContent) 383 static bool hasMatchingQuoteLevel(VisiblePosition endOfExistingContent, VisibleP osition endOfInsertedContent)
384 { 384 {
385 Position existing = endOfExistingContent.deepEquivalent(); 385 Position existing = endOfExistingContent.deepEquivalent();
386 Position inserted = endOfInsertedContent.deepEquivalent(); 386 Position inserted = endOfInsertedContent.deepEquivalent();
387 bool isInsideMailBlockquote = enclosingNodeOfType(inserted, isMailBlockquote , CanCrossEditingBoundary); 387 bool isInsideMailBlockquote = enclosingNodeOfType(inserted, isMailHTMLBlockq uoteElement, CanCrossEditingBoundary);
388 return isInsideMailBlockquote && (numEnclosingMailBlockquotes(existing) == n umEnclosingMailBlockquotes(inserted)); 388 return isInsideMailBlockquote && (numEnclosingMailBlockquotes(existing) == n umEnclosingMailBlockquotes(inserted));
389 } 389 }
390 390
391 bool ReplaceSelectionCommand::shouldMergeStart(bool selectionStartWasStartOfPara graph, bool fragmentHasInterchangeNewlineAtStart, bool selectionStartWasInsideMa ilBlockquote) 391 bool ReplaceSelectionCommand::shouldMergeStart(bool selectionStartWasStartOfPara graph, bool fragmentHasInterchangeNewlineAtStart, bool selectionStartWasInsideMa ilBlockquote)
392 { 392 {
393 if (m_movingParagraph) 393 if (m_movingParagraph)
394 return false; 394 return false;
395 395
396 VisiblePosition startOfInsertedContent(positionAtStartOfInsertedContent()); 396 VisiblePosition startOfInsertedContent(positionAtStartOfInsertedContent());
397 VisiblePosition prev = startOfInsertedContent.previous(CannotCrossEditingBou ndary); 397 VisiblePosition prev = startOfInsertedContent.previous(CannotCrossEditingBou ndary);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 455
456 bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const V isiblePosition& destination) 456 bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const V isiblePosition& destination)
457 { 457 {
458 if (source.isNull() || destination.isNull()) 458 if (source.isNull() || destination.isNull())
459 return false; 459 return false;
460 460
461 Node* sourceNode = source.deepEquivalent().deprecatedNode(); 461 Node* sourceNode = source.deepEquivalent().deprecatedNode();
462 Node* destinationNode = destination.deepEquivalent().deprecatedNode(); 462 Node* destinationNode = destination.deepEquivalent().deprecatedNode();
463 Element* sourceBlock = enclosingBlock(sourceNode); 463 Element* sourceBlock = enclosingBlock(sourceNode);
464 Element* destinationBlock = enclosingBlock(destinationNode); 464 Element* destinationBlock = enclosingBlock(destinationNode);
465 return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotation Node) && 465 return !enclosingNodeOfType(source.deepEquivalent(), &isMailPasteAsQuotation Node)
466 sourceBlock && (!sourceBlock->hasTagName(blockquoteTag) || isMailBloc kquote(sourceBlock)) && 466 && sourceBlock && (!sourceBlock->hasTagName(blockquoteTag) || isMailHTML BlockquoteElement(sourceBlock))
467 enclosingListChild(sourceBlock) == enclosingListChild(destinationNode ) && 467 && enclosingListChild(sourceBlock) == enclosingListChild(destinationNode )
468 enclosingTableCell(source.deepEquivalent()) == enclosingTableCell(des tination.deepEquivalent()) && 468 && enclosingTableCell(source.deepEquivalent()) == enclosingTableCell(des tination.deepEquivalent())
469 (!isHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destin ationBlock)) && 469 && (!isHeaderElement(sourceBlock) || haveSameTagName(sourceBlock, destin ationBlock))
470 // Don't merge to or from a position before or after a block because it would 470 // Don't merge to or from a position before or after a block because it would
471 // be a no-op and cause infinite recursion. 471 // be a no-op and cause infinite recursion.
472 !isBlock(sourceNode) && !isBlock(destinationNode); 472 && !isBlock(sourceNode) && !isBlock(destinationNode);
473 } 473 }
474 474
475 // Style rules that match just inserted elements could change their appearance, like 475 // Style rules that match just inserted elements could change their appearance, like
476 // a div inserted into a document with div { display:inline; }. 476 // a div inserted into a document with div { display:inline; }.
477 void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert edNodes& insertedNodes) 477 void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert edNodes& insertedNodes)
478 { 478 {
479 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf(); 479 RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
480 RefPtrWillBeRawPtr<Node> next = nullptr; 480 RefPtrWillBeRawPtr<Node> next = nullptr;
481 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) { 481 for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
482 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance 482 // FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
(...skipping 23 matching lines...) Expand all
506 // e.g. <font size="3" style="font-size: 20px;"> is converte d to <font style="font-size: 20px;"> 506 // e.g. <font size="3" style="font-size: 20px;"> is converte d to <font style="font-size: 20px;">
507 for (size_t i = 0; i < attributes.size(); i++) 507 for (size_t i = 0; i < attributes.size(); i++)
508 removeNodeAttribute(element, attributes[i]); 508 removeNodeAttribute(element, attributes[i]);
509 } 509 }
510 } 510 }
511 511
512 ContainerNode* context = element->parentNode(); 512 ContainerNode* context = element->parentNode();
513 513
514 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region, 514 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region,
515 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. 515 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
516 Node* blockquoteNode = !context || isMailPasteAsQuotationNode(contex t) ? context : enclosingNodeOfType(firstPositionInNode(context), isMailBlockquot e, CanCrossEditingBoundary); 516 Node* blockquoteNode = !context || isMailPasteAsQuotationNode(contex t) ? context : enclosingNodeOfType(firstPositionInNode(context), isMailHTMLBlock quoteElement, CanCrossEditingBoundary);
517 if (blockquoteNode) 517 if (blockquoteNode)
518 newInlineStyle->removeStyleFromRulesAndContext(element, document ().documentElement()); 518 newInlineStyle->removeStyleFromRulesAndContext(element, document ().documentElement());
519 519
520 newInlineStyle->removeStyleFromRulesAndContext(element, context); 520 newInlineStyle->removeStyleFromRulesAndContext(element, context);
521 } 521 }
522 522
523 if (!inlineStyle || newInlineStyle->isEmpty()) { 523 if (!inlineStyle || newInlineStyle->isEmpty()) {
524 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element) || isEmptyFontT ag(element, AllowNonEmptyStyleAttribute)) { 524 if (isStyleSpanOrSpanWithOnlyStyleAttribute(element) || isEmptyFontT ag(element, AllowNonEmptyStyleAttribute)) {
525 insertedNodes.willRemoveNodePreservingChildren(*element); 525 insertedNodes.willRemoveNodePreservingChildren(*element);
526 removeNodePreservingChildren(element); 526 removeNodePreservingChildren(element);
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 } 727 }
728 728
729 // Remove style spans before insertion if they are unnecessary. It's faster bec ause we'll 729 // Remove style spans before insertion if they are unnecessary. It's faster bec ause we'll
730 // avoid doing a layout. 730 // avoid doing a layout.
731 static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const Position& insertionPos) 731 static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const Position& insertionPos)
732 { 732 {
733 Node* topNode = fragment.firstChild(); 733 Node* topNode = fragment.firstChild();
734 734
735 // Handling the case where we are doing Paste as Quotation or pasting into q uoted content is more complicated (see handleStyleSpans) 735 // Handling the case where we are doing Paste as Quotation or pasting into q uoted content is more complicated (see handleStyleSpans)
736 // and doesn't receive the optimization. 736 // and doesn't receive the optimization.
737 if (isMailPasteAsQuotationNode(topNode) || enclosingNodeOfType(firstPosition InOrBeforeNode(topNode), isMailBlockquote, CanCrossEditingBoundary)) 737 if (isMailPasteAsQuotationNode(topNode) || enclosingNodeOfType(firstPosition InOrBeforeNode(topNode), isMailHTMLBlockquoteElement, CanCrossEditingBoundary))
738 return false; 738 return false;
739 739
740 // Either there are no style spans in the fragment or a WebKit client has ad ded content to the fragment 740 // Either there are no style spans in the fragment or a WebKit client has ad ded content to the fragment
741 // before inserting it. Look for and handle style spans after insertion. 741 // before inserting it. Look for and handle style spans after insertion.
742 if (!isLegacyAppleStyleSpan(topNode)) 742 if (!isLegacyAppleStyleSpan(topNode))
743 return false; 743 return false;
744 744
745 Node* wrappingStyleSpan = topNode; 745 Node* wrappingStyleSpan = topNode;
746 RefPtrWillBeRawPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create( insertionPos.parentAnchoredEquivalent()); 746 RefPtrWillBeRawPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create( insertionPos.parentAnchoredEquivalent());
747 String styleText = styleAtInsertionPos->style()->asText(); 747 String styleText = styleAtInsertionPos->style()->asText();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 // There might not be any style spans if we're pasting from another applicat ion or if 779 // There might not be any style spans if we're pasting from another applicat ion or if
780 // we are here because of a document.execCommand("InsertHTML", ...) call. 780 // we are here because of a document.execCommand("InsertHTML", ...) call.
781 if (!wrappingStyleSpan) 781 if (!wrappingStyleSpan)
782 return; 782 return;
783 783
784 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(wrappingStyleS pan->inlineStyle()); 784 RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(wrappingStyleS pan->inlineStyle());
785 ContainerNode* context = wrappingStyleSpan->parentNode(); 785 ContainerNode* context = wrappingStyleSpan->parentNode();
786 786
787 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if yo u're pasting into a quoted region, 787 // If Mail wraps the fragment with a Paste as Quotation blockquote, or if yo u're pasting into a quoted region,
788 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>. 788 // styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
789 Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : enclo singNodeOfType(firstPositionInNode(context), isMailBlockquote, CanCrossEditingBo undary); 789 Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : enclo singNodeOfType(firstPositionInNode(context), isMailHTMLBlockquoteElement, CanCro ssEditingBoundary);
790 if (blockquoteNode) 790 if (blockquoteNode)
791 context = document().documentElement(); 791 context = document().documentElement();
792 792
793 // This operation requires that only editing styles to be removed from sourc eDocumentStyle. 793 // This operation requires that only editing styles to be removed from sourc eDocumentStyle.
794 style->prepareToApplyAt(firstPositionInNode(context)); 794 style->prepareToApplyAt(firstPositionInNode(context));
795 795
796 // Remove block properties in the span's style. This prevents properties tha t probably have no effect 796 // Remove block properties in the span's style. This prevents properties tha t probably have no effect
797 // currently from affecting blocks later if the style is cloned for a new bl ock element during a future 797 // currently from affecting blocks later if the style is cloned for a new bl ock element during a future
798 // editing operation. 798 // editing operation.
799 // FIXME: They *can* have an effect currently if blocks beneath the style sp an aren't individually marked 799 // FIXME: They *can* have an effect currently if blocks beneath the style sp an aren't individually marked
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 929
930 VisiblePosition visibleStart = selection.visibleStart(); 930 VisiblePosition visibleStart = selection.visibleStart();
931 VisiblePosition visibleEnd = selection.visibleEnd(); 931 VisiblePosition visibleEnd = selection.visibleEnd();
932 932
933 bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd); 933 bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd);
934 bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart); 934 bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart);
935 935
936 Node* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEquival ent().deprecatedNode()); 936 Node* enclosingBlockOfVisibleStart = enclosingBlock(visibleStart.deepEquival ent().deprecatedNode());
937 937
938 Position insertionPos = selection.start(); 938 Position insertionPos = selection.start();
939 bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailB lockquote, CanCrossEditingBoundary); 939 bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailH TMLBlockquoteElement, CanCrossEditingBoundary);
940 bool selectionIsPlainText = !selection.isContentRichlyEditable(); 940 bool selectionIsPlainText = !selection.isContentRichlyEditable();
941 Element* currentRoot = selection.rootEditableElement(); 941 Element* currentRoot = selection.rootEditableElement();
942 942
943 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && ! startIsInsideMailBlockquote) || 943 if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && ! startIsInsideMailBlockquote) ||
944 enclosingBlockOfVisibleStart == currentRoot || isListItem(enclosingBlock OfVisibleStart) || selectionIsPlainText) 944 enclosingBlockOfVisibleStart == currentRoot || isListItem(enclosingBlock OfVisibleStart) || selectionIsPlainText)
945 m_preventNesting = false; 945 m_preventNesting = false;
946 946
947 if (selection.isRange()) { 947 if (selection.isRange()) {
948 // When the end of the selection being pasted into is at the end of a pa ragraph, and that selection 948 // When the end of the selection being pasted into is at the end of a pa ragraph, and that selection
949 // spans multiple blocks, not merging may leave an empty line. 949 // spans multiple blocks, not merging may leave an empty line.
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 setEndingSelection(endOfInsertedContent); 1215 setEndingSelection(endOfInsertedContent);
1216 Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEq uivalent().deprecatedNode()); 1216 Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEq uivalent().deprecatedNode());
1217 if (isListItem(enclosingNode)) { 1217 if (isListItem(enclosingNode)) {
1218 RefPtrWillBeRawPtr<Node> newListItem = createListItemElement (document()); 1218 RefPtrWillBeRawPtr<Node> newListItem = createListItemElement (document());
1219 insertNodeAfter(newListItem, enclosingNode); 1219 insertNodeAfter(newListItem, enclosingNode);
1220 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get()))); 1220 setEndingSelection(VisiblePosition(firstPositionInNode(newLi stItem.get())));
1221 } else { 1221 } else {
1222 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph 1222 // Use a default paragraph element (a plain div) for the emp ty paragraph, using the last paragraph
1223 // block's style seems to annoy users. 1223 // block's style seems to annoy users.
1224 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(), 1224 insertParagraphSeparator(true, !startIsInsideMailBlockquote && highestEnclosingNodeOfType(endOfInsertedContent.deepEquivalent(),
1225 isMailBlockquote, CannotCrossEditingBoundary, insertedNo des.firstNodeInserted()->parentNode())); 1225 isMailHTMLBlockquoteElement, CannotCrossEditingBoundary, insertedNodes.firstNodeInserted()->parentNode()));
1226 } 1226 }
1227 1227
1228 // Select up to the paragraph separator that was added. 1228 // Select up to the paragraph separator that was added.
1229 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent(); 1229 lastPositionToSelect = endingSelection().visibleStart().deepEqui valent();
1230 updateNodesInserted(lastPositionToSelect.deprecatedNode()); 1230 updateNodesInserted(lastPositionToSelect.deprecatedNode());
1231 } 1231 }
1232 } else { 1232 } else {
1233 // Select up to the beginning of the next paragraph. 1233 // Select up to the beginning of the next paragraph.
1234 lastPositionToSelect = next.deepEquivalent().downstream(); 1234 lastPositionToSelect = next.deepEquivalent().downstream();
1235 } 1235 }
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 void ReplaceSelectionCommand::trace(Visitor* visitor) 1528 void ReplaceSelectionCommand::trace(Visitor* visitor)
1529 { 1529 {
1530 visitor->trace(m_startOfInsertedContent); 1530 visitor->trace(m_startOfInsertedContent);
1531 visitor->trace(m_endOfInsertedContent); 1531 visitor->trace(m_endOfInsertedContent);
1532 visitor->trace(m_insertionStyle); 1532 visitor->trace(m_insertionStyle);
1533 visitor->trace(m_documentFragment); 1533 visitor->trace(m_documentFragment);
1534 CompositeEditCommand::trace(visitor); 1534 CompositeEditCommand::trace(visitor);
1535 } 1535 }
1536 1536
1537 } // namespace blink 1537 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/editing/InsertParagraphSeparatorCommand.cpp ('k') | Source/core/editing/htmlediting.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698