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

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

Issue 69543007: Have NodeTraversal::nextSkippingChildren() take a reference (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/dom/TreeWalker.cpp ('k') | Source/core/editing/CompositeEditCommand.cpp » ('j') | 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, 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2008, 2009 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 splitTextAtEnd(start, end); 344 splitTextAtEnd(start, end);
345 start = startPosition(); 345 start = startPosition();
346 end = endPosition(); 346 end = endPosition();
347 } 347 }
348 348
349 // Calculate loop end point. 349 // Calculate loop end point.
350 // If the end node is before the start node (can only happen if the end node is 350 // If the end node is before the start node (can only happen if the end node is
351 // an ancestor of the start node), we gather nodes up to the next sibling of the end node 351 // an ancestor of the start node), we gather nodes up to the next sibling of the end node
352 Node *beyondEnd; 352 Node *beyondEnd;
353 if (start.deprecatedNode()->isDescendantOf(end.deprecatedNode())) 353 if (start.deprecatedNode()->isDescendantOf(end.deprecatedNode()))
354 beyondEnd = NodeTraversal::nextSkippingChildren(end.deprecatedNode()); 354 beyondEnd = NodeTraversal::nextSkippingChildren(*end.deprecatedNode());
355 else 355 else
356 beyondEnd = NodeTraversal::next(*end.deprecatedNode()); 356 beyondEnd = NodeTraversal::next(*end.deprecatedNode());
357 357
358 start = start.upstream(); // Move upstream to ensure we do not add redundant spans. 358 start = start.upstream(); // Move upstream to ensure we do not add redundant spans.
359 Node* startNode = start.deprecatedNode(); 359 Node* startNode = start.deprecatedNode();
360 ASSERT(startNode); 360 ASSERT(startNode);
361 if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOf fset(startNode)) // Move out of text node if range does not include its characte rs. 361 if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOf fset(startNode)) // Move out of text node if range does not include its characte rs.
362 startNode = NodeTraversal::next(*startNode); 362 startNode = NodeTraversal::next(*startNode);
363 363
364 // Store away font size before making any changes to the document. 364 // Store away font size before making any changes to the document.
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 ASSERT(startNode); 676 ASSERT(startNode);
677 677
678 if (start.deprecatedEditingOffset() >= caretMaxOffset(start.deprecatedNode() )) { 678 if (start.deprecatedEditingOffset() >= caretMaxOffset(start.deprecatedNode() )) {
679 startNode = NodeTraversal::next(*startNode); 679 startNode = NodeTraversal::next(*startNode);
680 if (!startNode || comparePositions(end, firstPositionInOrBeforeNode(star tNode)) < 0) 680 if (!startNode || comparePositions(end, firstPositionInOrBeforeNode(star tNode)) < 0)
681 return; 681 return;
682 } 682 }
683 683
684 Node* pastEndNode = end.deprecatedNode(); 684 Node* pastEndNode = end.deprecatedNode();
685 if (end.deprecatedEditingOffset() >= caretMaxOffset(end.deprecatedNode())) 685 if (end.deprecatedEditingOffset() >= caretMaxOffset(end.deprecatedNode()))
686 pastEndNode = NodeTraversal::nextSkippingChildren(end.deprecatedNode()); 686 pastEndNode = NodeTraversal::nextSkippingChildren(*end.deprecatedNode()) ;
687 687
688 // FIXME: Callers should perform this operation on a Range that includes the br 688 // FIXME: Callers should perform this operation on a Range that includes the br
689 // if they want style applied to the empty line. 689 // if they want style applied to the empty line.
690 if (start == end && start.deprecatedNode()->hasTagName(brTag)) 690 if (start == end && start.deprecatedNode()->hasTagName(brTag))
691 pastEndNode = NodeTraversal::next(*start.deprecatedNode()); 691 pastEndNode = NodeTraversal::next(*start.deprecatedNode());
692 692
693 // Start from the highest fully selected ancestor so that we can modify the fully selected node. 693 // Start from the highest fully selected ancestor so that we can modify the fully selected node.
694 // e.g. When applying font-size: large on <font color="blue">hello</font>, w e need to include the font element in our run 694 // e.g. When applying font-size: large on <font color="blue">hello</font>, w e need to include the font element in our run
695 // to generate <font color="blue" size="4">hello</font> instead of <font col or="blue"><font size="4">hello</font></font> 695 // to generate <font color="blue" size="4">hello</font> instead of <font col or="blue"><font size="4">hello</font></font>
696 RefPtr<Range> range = Range::create(startNode->document(), start, end); 696 RefPtr<Range> range = Range::create(startNode->document(), start, end);
697 Element* editableRoot = startNode->rootEditableElement(); 697 Element* editableRoot = startNode->rootEditableElement();
698 if (startNode != editableRoot) { 698 if (startNode != editableRoot) {
699 while (editableRoot && startNode->parentNode() != editableRoot && isNode VisiblyContainedWithin(startNode->parentNode(), range.get())) 699 while (editableRoot && startNode->parentNode() != editableRoot && isNode VisiblyContainedWithin(startNode->parentNode(), range.get()))
700 startNode = startNode->parentNode(); 700 startNode = startNode->parentNode();
701 } 701 }
702 702
703 applyInlineStyleToNodeRange(style, startNode, pastEndNode); 703 applyInlineStyleToNodeRange(style, startNode, pastEndNode);
704 } 704 }
705 705
706 static bool containsNonEditableRegion(Node* node) 706 static bool containsNonEditableRegion(Node& node)
707 { 707 {
708 if (!node->rendererIsEditable()) 708 if (!node.rendererIsEditable())
709 return true; 709 return true;
710 710
711 Node* sibling = NodeTraversal::nextSkippingChildren(node); 711 Node* sibling = NodeTraversal::nextSkippingChildren(node);
712 for (Node* descendent = node->firstChild(); descendent && descendent != sibl ing; descendent = NodeTraversal::next(*descendent)) { 712 for (Node* descendent = node.firstChild(); descendent && descendent != sibli ng; descendent = NodeTraversal::next(*descendent)) {
713 if (!descendent->rendererIsEditable()) 713 if (!descendent->rendererIsEditable())
714 return true; 714 return true;
715 } 715 }
716 716
717 return false; 717 return false;
718 } 718 }
719 719
720 struct InlineRunToApplyStyle { 720 struct InlineRunToApplyStyle {
721 InlineRunToApplyStyle(Node* start, Node* end, Node* pastEndNode) 721 InlineRunToApplyStyle(Node* start, Node* end, Node* pastEndNode)
722 : start(start) 722 : start(start)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 continue; 755 continue;
756 756
757 if (!node->rendererIsRichlyEditable() && node->isHTMLElement()) { 757 if (!node->rendererIsRichlyEditable() && node->isHTMLElement()) {
758 // This is a plaintext-only region. Only proceed if it's fully selec ted. 758 // This is a plaintext-only region. Only proceed if it's fully selec ted.
759 // pastEndNode is the node after the last fully selected node, so if it's inside node then 759 // pastEndNode is the node after the last fully selected node, so if it's inside node then
760 // node isn't fully selected. 760 // node isn't fully selected.
761 if (pastEndNode && pastEndNode->isDescendantOf(node.get())) 761 if (pastEndNode && pastEndNode->isDescendantOf(node.get()))
762 break; 762 break;
763 // Add to this element's inline style and skip over its contents. 763 // Add to this element's inline style and skip over its contents.
764 HTMLElement* element = toHTMLElement(node); 764 HTMLElement* element = toHTMLElement(node);
765 next = NodeTraversal::nextSkippingChildren(node.get()); 765 next = NodeTraversal::nextSkippingChildren(*node);
766 if (!style->style()) 766 if (!style->style())
767 continue; 767 continue;
768 RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty (element->inlineStyle()); 768 RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty (element->inlineStyle());
769 inlineStyle->mergeAndOverrideOnConflict(style->style()); 769 inlineStyle->mergeAndOverrideOnConflict(style->style());
770 setNodeAttribute(element, styleAttr, inlineStyle->asText()); 770 setNodeAttribute(element, styleAttr, inlineStyle->asText());
771 continue; 771 continue;
772 } 772 }
773 773
774 if (isBlock(node.get())) 774 if (isBlock(node.get()))
775 continue; 775 continue;
776 776
777 if (node->childNodeCount()) { 777 if (node->childNodeCount()) {
778 if (node->contains(pastEndNode.get()) || containsNonEditableRegion(n ode.get()) || !node->parentNode()->rendererIsEditable()) 778 if (node->contains(pastEndNode.get()) || containsNonEditableRegion(* node) || !node->parentNode()->rendererIsEditable())
779 continue; 779 continue;
780 if (editingIgnoresContent(node.get())) { 780 if (editingIgnoresContent(node.get())) {
781 next = NodeTraversal::nextSkippingChildren(node.get()); 781 next = NodeTraversal::nextSkippingChildren(*node);
782 continue; 782 continue;
783 } 783 }
784 } 784 }
785 785
786 Node* runStart = node.get(); 786 Node* runStart = node.get();
787 Node* runEnd = node.get(); 787 Node* runEnd = node.get();
788 Node* sibling = node->nextSibling(); 788 Node* sibling = node->nextSibling();
789 while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNo de.get()) 789 while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNo de.get())
790 && (!isBlock(sibling) || sibling->hasTagName(brTag)) 790 && (!isBlock(sibling) || sibling->hasTagName(brTag))
791 && !containsNonEditableRegion(sibling)) { 791 && !containsNonEditableRegion(*sibling)) {
792 runEnd = sibling; 792 runEnd = sibling;
793 sibling = runEnd->nextSibling(); 793 sibling = runEnd->nextSibling();
794 } 794 }
795 next = NodeTraversal::nextSkippingChildren(runEnd); 795 ASSERT(runEnd);
796 next = NodeTraversal::nextSkippingChildren(*runEnd);
796 797
797 Node* pastEndNode = NodeTraversal::nextSkippingChildren(runEnd); 798 Node* pastEndNode = NodeTraversal::nextSkippingChildren(*runEnd);
798 if (!shouldApplyInlineStyleToRun(style, runStart, pastEndNode)) 799 if (!shouldApplyInlineStyleToRun(style, runStart, pastEndNode))
799 continue; 800 continue;
800 801
801 runs.append(InlineRunToApplyStyle(runStart, runEnd, pastEndNode)); 802 runs.append(InlineRunToApplyStyle(runStart, runEnd, pastEndNode));
802 } 803 }
803 804
804 for (size_t i = 0; i < runs.size(); i++) { 805 for (size_t i = 0; i < runs.size(); i++) {
805 removeConflictingInlineStyleFromRun(style, runs[i].start, runs[i].end, r uns[i].pastEndNode); 806 removeConflictingInlineStyleFromRun(style, runs[i].start, runs[i].end, r uns[i].pastEndNode);
806 runs[i].positionForStyleComputation = positionToComputeInlineStyleChange (runs[i].start, runs[i].dummyElement); 807 runs[i].positionForStyleComputation = positionToComputeInlineStyleChange (runs[i].start, runs[i].dummyElement);
807 } 808 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 return false; 843 return false;
843 } 844 }
844 845
845 void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style, RefPtr<Node>& runStart, RefPtr<Node>& runEnd, PassRefPtr<Node> pastEndNode) 846 void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style, RefPtr<Node>& runStart, RefPtr<Node>& runEnd, PassRefPtr<Node> pastEndNode)
846 { 847 {
847 ASSERT(runStart && runEnd); 848 ASSERT(runStart && runEnd);
848 RefPtr<Node> next = runStart; 849 RefPtr<Node> next = runStart;
849 for (RefPtr<Node> node = next; node && node->inDocument() && node != pastEnd Node; node = next) { 850 for (RefPtr<Node> node = next; node && node->inDocument() && node != pastEnd Node; node = next) {
850 if (editingIgnoresContent(node.get())) { 851 if (editingIgnoresContent(node.get())) {
851 ASSERT(!node->contains(pastEndNode.get())); 852 ASSERT(!node->contains(pastEndNode.get()));
852 next = NodeTraversal::nextSkippingChildren(node.get()); 853 next = NodeTraversal::nextSkippingChildren(*node);
853 } else { 854 } else {
854 next = NodeTraversal::next(*node); 855 next = NodeTraversal::next(*node);
855 } 856 }
856 if (!node->isHTMLElement()) 857 if (!node->isHTMLElement())
857 continue; 858 continue;
858 859
859 RefPtr<Node> previousSibling = node->previousSibling(); 860 RefPtr<Node> previousSibling = node->previousSibling();
860 RefPtr<Node> nextSibling = node->nextSibling(); 861 RefPtr<Node> nextSibling = node->nextSibling();
861 RefPtr<ContainerNode> parent = node->parentNode(); 862 RefPtr<ContainerNode> parent = node->parentNode();
862 removeInlineStyleFromElement(style, toHTMLElement(node), RemoveAlways); 863 removeInlineStyleFromElement(style, toHTMLElement(node), RemoveAlways);
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 // If pushDownInlineStyleAroundNode has pruned start.deprecatedNode() or end .deprecatedNode(), 1103 // If pushDownInlineStyleAroundNode has pruned start.deprecatedNode() or end .deprecatedNode(),
1103 // use pushDownStart or pushDownEnd instead, which pushDownInlineStyleAround Node won't prune. 1104 // use pushDownStart or pushDownEnd instead, which pushDownInlineStyleAround Node won't prune.
1104 Position s = start.isNull() || start.isOrphan() ? pushDownStart : start; 1105 Position s = start.isNull() || start.isOrphan() ? pushDownStart : start;
1105 Position e = end.isNull() || end.isOrphan() ? pushDownEnd : end; 1106 Position e = end.isNull() || end.isOrphan() ? pushDownEnd : end;
1106 1107
1107 RefPtr<Node> node = start.deprecatedNode(); 1108 RefPtr<Node> node = start.deprecatedNode();
1108 while (node) { 1109 while (node) {
1109 RefPtr<Node> next; 1110 RefPtr<Node> next;
1110 if (editingIgnoresContent(node.get())) { 1111 if (editingIgnoresContent(node.get())) {
1111 ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecate dNode())); 1112 ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecate dNode()));
1112 next = NodeTraversal::nextSkippingChildren(node.get()); 1113 next = NodeTraversal::nextSkippingChildren(*node);
1113 } else { 1114 } else {
1114 next = NodeTraversal::next(*node); 1115 next = NodeTraversal::next(*node);
1115 } 1116 }
1116 if (node->isHTMLElement() && nodeFullySelected(node.get(), start, end)) { 1117 if (node->isHTMLElement() && nodeFullySelected(node.get(), start, end)) {
1117 RefPtr<HTMLElement> elem = toHTMLElement(node); 1118 RefPtr<HTMLElement> elem = toHTMLElement(node);
1118 RefPtr<Node> prev = NodeTraversal::previousPostOrder(*elem); 1119 RefPtr<Node> prev = NodeTraversal::previousPostOrder(*elem);
1119 RefPtr<Node> next = NodeTraversal::next(*elem); 1120 RefPtr<Node> next = NodeTraversal::next(*elem);
1120 RefPtr<EditingStyle> styleToPushDown; 1121 RefPtr<EditingStyle> styleToPushDown;
1121 RefPtr<Node> childNode; 1122 RefPtr<Node> childNode;
1122 if (isStyledInlineElementToRemove(elem.get())) { 1123 if (isStyledInlineElementToRemove(elem.get())) {
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 String textToMove = nextText->data(); 1547 String textToMove = nextText->data();
1547 insertTextIntoNode(childText, childText->length(), textToMove); 1548 insertTextIntoNode(childText, childText->length(), textToMove);
1548 removeNode(next); 1549 removeNode(next);
1549 // don't move child node pointer. it may want to merge with more text no des. 1550 // don't move child node pointer. it may want to merge with more text no des.
1550 } 1551 }
1551 1552
1552 updateStartEnd(newStart, newEnd); 1553 updateStartEnd(newStart, newEnd);
1553 } 1554 }
1554 1555
1555 } 1556 }
OLDNEW
« no previous file with comments | « Source/core/dom/TreeWalker.cpp ('k') | Source/core/editing/CompositeEditCommand.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698