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

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

Issue 69543007: Have NodeTraversal::nextSkippingChildren() take a reference (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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r ights reserved. 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All r ights reserved.
3 * Copyright (C) 2005 Alexey Proskuryakov. 3 * Copyright (C) 2005 Alexey Proskuryakov.
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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 740
741 static bool shouldEmitNewlineForNode(Node* node, bool emitsOriginalText) 741 static bool shouldEmitNewlineForNode(Node* node, bool emitsOriginalText)
742 { 742 {
743 RenderObject* renderer = node->renderer(); 743 RenderObject* renderer = node->renderer();
744 744
745 if (renderer ? !renderer->isBR() : !node->hasTagName(brTag)) 745 if (renderer ? !renderer->isBR() : !node->hasTagName(brTag))
746 return false; 746 return false;
747 return emitsOriginalText || !(node->isInShadowTree() && node->shadowHost()-> hasTagName(inputTag)); 747 return emitsOriginalText || !(node->isInShadowTree() && node->shadowHost()-> hasTagName(inputTag));
748 } 748 }
749 749
750 static bool shouldEmitNewlinesBeforeAndAfterNode(Node* node) 750 static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node)
751 { 751 {
752 // Block flow (versus inline flow) is represented by having 752 // Block flow (versus inline flow) is represented by having
753 // a newline both before and after the element. 753 // a newline both before and after the element.
754 RenderObject* r = node->renderer(); 754 RenderObject* r = node.renderer();
755 if (!r) { 755 if (!r) {
756 return (node->hasTagName(blockquoteTag) 756 return (node.hasTagName(blockquoteTag)
757 || node->hasTagName(ddTag) 757 || node.hasTagName(ddTag)
758 || node->hasTagName(divTag) 758 || node.hasTagName(divTag)
759 || node->hasTagName(dlTag) 759 || node.hasTagName(dlTag)
760 || node->hasTagName(dtTag) 760 || node.hasTagName(dtTag)
761 || node->hasTagName(h1Tag) 761 || node.hasTagName(h1Tag)
762 || node->hasTagName(h2Tag) 762 || node.hasTagName(h2Tag)
763 || node->hasTagName(h3Tag) 763 || node.hasTagName(h3Tag)
764 || node->hasTagName(h4Tag) 764 || node.hasTagName(h4Tag)
765 || node->hasTagName(h5Tag) 765 || node.hasTagName(h5Tag)
766 || node->hasTagName(h6Tag) 766 || node.hasTagName(h6Tag)
767 || node->hasTagName(hrTag) 767 || node.hasTagName(hrTag)
768 || node->hasTagName(liTag) 768 || node.hasTagName(liTag)
769 || node->hasTagName(listingTag) 769 || node.hasTagName(listingTag)
770 || node->hasTagName(olTag) 770 || node.hasTagName(olTag)
771 || node->hasTagName(pTag) 771 || node.hasTagName(pTag)
772 || node->hasTagName(preTag) 772 || node.hasTagName(preTag)
773 || node->hasTagName(trTag) 773 || node.hasTagName(trTag)
774 || node->hasTagName(ulTag)); 774 || node.hasTagName(ulTag));
775 } 775 }
776 776
777 // Need to make an exception for table cells, because they are blocks, but w e 777 // Need to make an exception for table cells, because they are blocks, but w e
778 // want them tab-delimited rather than having newlines before and after. 778 // want them tab-delimited rather than having newlines before and after.
779 if (isTableCell(node)) 779 if (isTableCell(&node))
780 return false; 780 return false;
781 781
782 // Need to make an exception for table row elements, because they are neithe r 782 // Need to make an exception for table row elements, because they are neithe r
783 // "inline" or "RenderBlock", but we want newlines for them. 783 // "inline" or "RenderBlock", but we want newlines for them.
784 if (r->isTableRow()) { 784 if (r->isTableRow()) {
785 RenderTable* t = toRenderTableRow(r)->table(); 785 RenderTable* t = toRenderTableRow(r)->table();
786 if (t && !t->isInline()) 786 if (t && !t->isInline())
787 return true; 787 return true;
788 } 788 }
789 789
790 return !r->isInline() && r->isRenderBlock() 790 return !r->isInline() && r->isRenderBlock()
791 && !r->isFloatingOrOutOfFlowPositioned() && !r->isBody() && !r->isRubyTe xt(); 791 && !r->isFloatingOrOutOfFlowPositioned() && !r->isBody() && !r->isRubyTe xt();
792 } 792 }
793 793
794 static bool shouldEmitNewlineAfterNode(Node* node) 794 static bool shouldEmitNewlineAfterNode(Node& node)
795 { 795 {
796 // FIXME: It should be better but slower to create a VisiblePosition here. 796 // FIXME: It should be better but slower to create a VisiblePosition here.
797 if (!shouldEmitNewlinesBeforeAndAfterNode(node)) 797 if (!shouldEmitNewlinesBeforeAndAfterNode(node))
798 return false; 798 return false;
799 // Check if this is the very last renderer in the document. 799 // Check if this is the very last renderer in the document.
800 // If so, then we should not emit a newline. 800 // If so, then we should not emit a newline.
801 while ((node = NodeTraversal::nextSkippingChildren(node))) { 801 Node* next = &node;
802 if (node->renderer()) 802 while ((next = NodeTraversal::nextSkippingChildren(*next))) {
adamk 2013/11/12 21:07:43 Nit: can you remove the extra parentheses while yo
Inactive 2013/11/12 21:19:16 I would but I cannot :) ../../third_party/WebKit/
adamk 2013/11/12 22:21:36 Sigh. Oh well, lgtm anyway
803 if (next->renderer())
803 return true; 804 return true;
804 } 805 }
805 return false; 806 return false;
806 } 807 }
807 808
808 static bool shouldEmitNewlineBeforeNode(Node* node) 809 static bool shouldEmitNewlineBeforeNode(Node& node)
809 { 810 {
810 return shouldEmitNewlinesBeforeAndAfterNode(node); 811 return shouldEmitNewlinesBeforeAndAfterNode(node);
811 } 812 }
812 813
813 static bool shouldEmitExtraNewlineForNode(Node* node) 814 static bool shouldEmitExtraNewlineForNode(Node* node)
814 { 815 {
815 // When there is a significant collapsed bottom margin, emit an extra 816 // When there is a significant collapsed bottom margin, emit an extra
816 // newline for a more realistic result. We end up getting the right 817 // newline for a more realistic result. We end up getting the right
817 // result even without margin collapsing. For example: <div><p>text</p></div > 818 // result even without margin collapsing. For example: <div><p>text</p></div >
818 // will work right even if both the <div> and the <p> have bottom margins. 819 // will work right even if both the <div> and the <p> have bottom margins.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 { 930 {
930 // Emit a character to show the positioning of m_node. 931 // Emit a character to show the positioning of m_node.
931 932
932 // When we haven't been emitting any characters, shouldRepresentNodeOffsetZe ro() can 933 // When we haven't been emitting any characters, shouldRepresentNodeOffsetZe ro() can
933 // create VisiblePositions, which is expensive. So, we perform the inexpensi ve checks 934 // create VisiblePositions, which is expensive. So, we perform the inexpensi ve checks
934 // on m_node to see if it necessitates emitting a character first and will e arly return 935 // on m_node to see if it necessitates emitting a character first and will e arly return
935 // before encountering shouldRepresentNodeOffsetZero()s worse case behavior. 936 // before encountering shouldRepresentNodeOffsetZero()s worse case behavior.
936 if (shouldEmitTabBeforeNode(m_node)) { 937 if (shouldEmitTabBeforeNode(m_node)) {
937 if (shouldRepresentNodeOffsetZero()) 938 if (shouldRepresentNodeOffsetZero())
938 emitCharacter('\t', m_node->parentNode(), m_node, 0, 0); 939 emitCharacter('\t', m_node->parentNode(), m_node, 0, 0);
939 } else if (shouldEmitNewlineBeforeNode(m_node)) { 940 } else if (shouldEmitNewlineBeforeNode(*m_node)) {
940 if (shouldRepresentNodeOffsetZero()) 941 if (shouldRepresentNodeOffsetZero())
941 emitCharacter('\n', m_node->parentNode(), m_node, 0, 0); 942 emitCharacter('\n', m_node->parentNode(), m_node, 0, 0);
942 } else if (shouldEmitSpaceBeforeAndAfterNode(m_node)) { 943 } else if (shouldEmitSpaceBeforeAndAfterNode(m_node)) {
943 if (shouldRepresentNodeOffsetZero()) 944 if (shouldRepresentNodeOffsetZero())
944 emitCharacter(' ', m_node->parentNode(), m_node, 0, 0); 945 emitCharacter(' ', m_node->parentNode(), m_node, 0, 0);
945 } 946 }
946 } 947 }
947 948
948 bool TextIterator::handleNonTextNode() 949 bool TextIterator::handleNonTextNode()
949 { 950 {
(...skipping 17 matching lines...) Expand all
967 return; 968 return;
968 969
969 // Emit with a position *inside* m_node, after m_node's contents, in 970 // Emit with a position *inside* m_node, after m_node's contents, in
970 // case it is a block, because the run should start where the 971 // case it is a block, because the run should start where the
971 // emitted character is positioned visually. 972 // emitted character is positioned visually.
972 Node* baseNode = m_node->lastChild() ? m_node->lastChild() : m_node; 973 Node* baseNode = m_node->lastChild() ? m_node->lastChild() : m_node;
973 // FIXME: This shouldn't require the m_lastTextNode to be true, but we can't change that without making 974 // FIXME: This shouldn't require the m_lastTextNode to be true, but we can't change that without making
974 // the logic in _web_attributedStringFromRange match. We'll get that for fre e when we switch to use 975 // the logic in _web_attributedStringFromRange match. We'll get that for fre e when we switch to use
975 // TextIterator in _web_attributedStringFromRange. 976 // TextIterator in _web_attributedStringFromRange.
976 // See <rdar://problem/5428427> for an example of how this mismatch will cau se problems. 977 // See <rdar://problem/5428427> for an example of how this mismatch will cau se problems.
977 if (m_lastTextNode && shouldEmitNewlineAfterNode(m_node)) { 978 if (m_lastTextNode && shouldEmitNewlineAfterNode(*m_node)) {
978 // use extra newline to represent margin bottom, as needed 979 // use extra newline to represent margin bottom, as needed
979 bool addNewline = shouldEmitExtraNewlineForNode(m_node); 980 bool addNewline = shouldEmitExtraNewlineForNode(m_node);
980 981
981 // FIXME: We need to emit a '\n' as we leave an empty block(s) that 982 // FIXME: We need to emit a '\n' as we leave an empty block(s) that
982 // contain a VisiblePosition when doing selection preservation. 983 // contain a VisiblePosition when doing selection preservation.
983 if (m_lastCharacter != '\n') { 984 if (m_lastCharacter != '\n') {
984 // insert a newline with a position following this block's contents. 985 // insert a newline with a position following this block's contents.
985 emitCharacter('\n', baseNode->parentNode(), baseNode, 1, 1); 986 emitCharacter('\n', baseNode->parentNode(), baseNode, 1, 1);
986 // remember whether to later add a newline for the current node 987 // remember whether to later add a newline for the current node
987 ASSERT(!m_needsAnotherNewline); 988 ASSERT(!m_needsAnotherNewline);
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 // code in moveParagraphs, so we use a comma. Unconditionally emit 1307 // code in moveParagraphs, so we use a comma. Unconditionally emit
1307 // here because this iterator is only used for boundary finding. 1308 // here because this iterator is only used for boundary finding.
1308 emitCharacter(',', m_node->parentNode(), index, index + 1); 1309 emitCharacter(',', m_node->parentNode(), index, index + 1);
1309 return true; 1310 return true;
1310 } 1311 }
1311 1312
1312 bool SimplifiedBackwardsTextIterator::handleNonTextNode() 1313 bool SimplifiedBackwardsTextIterator::handleNonTextNode()
1313 { 1314 {
1314 // We can use a linefeed in place of a tab because this simple iterator is o nly used to 1315 // We can use a linefeed in place of a tab because this simple iterator is o nly used to
1315 // find boundaries, not actual content. A linefeed breaks words, sentences, and paragraphs. 1316 // find boundaries, not actual content. A linefeed breaks words, sentences, and paragraphs.
1316 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewli neAfterNode(m_node) || shouldEmitTabBeforeNode(m_node)) { 1317 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewli neAfterNode(*m_node) || shouldEmitTabBeforeNode(m_node)) {
1317 unsigned index = m_node->nodeIndex(); 1318 unsigned index = m_node->nodeIndex();
1318 // The start of this emitted range is wrong. Ensuring correctness would require 1319 // The start of this emitted range is wrong. Ensuring correctness would require
1319 // VisiblePositions and so would be slow. previousBoundary expects this. 1320 // VisiblePositions and so would be slow. previousBoundary expects this.
1320 emitCharacter('\n', m_node->parentNode(), index + 1, index + 1); 1321 emitCharacter('\n', m_node->parentNode(), index + 1, index + 1);
1321 } 1322 }
1322 return true; 1323 return true;
1323 } 1324 }
1324 1325
1325 void SimplifiedBackwardsTextIterator::exitNode() 1326 void SimplifiedBackwardsTextIterator::exitNode()
1326 { 1327 {
1327 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewli neBeforeNode(m_node) || shouldEmitTabBeforeNode(m_node)) { 1328 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewli neBeforeNode(*m_node) || shouldEmitTabBeforeNode(m_node)) {
1328 // The start of this emitted range is wrong. Ensuring correctness would require 1329 // The start of this emitted range is wrong. Ensuring correctness would require
1329 // VisiblePositions and so would be slow. previousBoundary expects this. 1330 // VisiblePositions and so would be slow. previousBoundary expects this.
1330 emitCharacter('\n', m_node, 0, 0); 1331 emitCharacter('\n', m_node, 0, 0);
1331 } 1332 }
1332 } 1333 }
1333 1334
1334 void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node* node, int sta rtOffset, int endOffset) 1335 void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node* node, int sta rtOffset, int endOffset)
1335 { 1336 {
1336 m_singleCharacterBuffer = c; 1337 m_singleCharacterBuffer = c;
1337 m_positionNode = node; 1338 m_positionNode = node;
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
2325 if (!matchLength) 2326 if (!matchLength)
2326 return collapsedToBoundary(range, !(options & Backwards)); 2327 return collapsedToBoundary(range, !(options & Backwards));
2327 } 2328 }
2328 2329
2329 // Then, find the document position of the start and the end of the text. 2330 // Then, find the document position of the start and the end of the text.
2330 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls ); 2331 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls );
2331 return characterSubrange(computeRangeIterator, matchStart, matchLength); 2332 return characterSubrange(computeRangeIterator, matchStart, matchLength);
2332 } 2333 }
2333 2334
2334 } 2335 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698