OLD | NEW |
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 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 Text* textNode = toText(m_node); | 608 Text* textNode = toText(m_node); |
609 RenderText* renderer = textNode->renderer(); | 609 RenderText* renderer = textNode->renderer(); |
610 | 610 |
611 m_lastTextNode = textNode; | 611 m_lastTextNode = textNode; |
612 String str = renderer->text(); | 612 String str = renderer->text(); |
613 | 613 |
614 // handle pre-formatted text | 614 // handle pre-formatted text |
615 if (!renderer->style()->collapseWhiteSpace()) { | 615 if (!renderer->style()->collapseWhiteSpace()) { |
616 int runStart = m_offset; | 616 int runStart = m_offset; |
617 if (m_lastTextNodeEndedWithCollapsedSpace && hasVisibleTextNode(renderer
)) { | 617 if (m_lastTextNodeEndedWithCollapsedSpace && hasVisibleTextNode(renderer
)) { |
618 emitCharacter(' ', textNode, 0, runStart, runStart); | 618 emitCharacter(space, textNode, 0, runStart, runStart); |
619 return false; | 619 return false; |
620 } | 620 } |
621 if (!m_handledFirstLetter && renderer->isTextFragment() && !m_offset) { | 621 if (!m_handledFirstLetter && renderer->isTextFragment() && !m_offset) { |
622 handleTextNodeFirstLetter(toRenderTextFragment(renderer)); | 622 handleTextNodeFirstLetter(toRenderTextFragment(renderer)); |
623 if (m_firstLetterText) { | 623 if (m_firstLetterText) { |
624 String firstLetter = m_firstLetterText->text(); | 624 String firstLetter = m_firstLetterText->text(); |
625 emitText(textNode, m_firstLetterText, m_offset, m_offset + first
Letter.length()); | 625 emitText(textNode, m_firstLetterText, m_offset, m_offset + first
Letter.length()); |
626 m_firstLetterText = nullptr; | 626 m_firstLetterText = nullptr; |
627 m_textBox = 0; | 627 m_textBox = 0; |
628 return false; | 628 return false; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 InlineTextBox* firstTextBox = renderer->containsReversedText() ? (m_sort
edTextBoxes.isEmpty() ? 0 : m_sortedTextBoxes[0]) : renderer->firstTextBox(); | 691 InlineTextBox* firstTextBox = renderer->containsReversedText() ? (m_sort
edTextBoxes.isEmpty() ? 0 : m_sortedTextBoxes[0]) : renderer->firstTextBox(); |
692 bool needSpace = m_lastTextNodeEndedWithCollapsedSpace | 692 bool needSpace = m_lastTextNodeEndedWithCollapsedSpace |
693 || (m_textBox == firstTextBox && textBoxStart == runStart && runStar
t > 0); | 693 || (m_textBox == firstTextBox && textBoxStart == runStart && runStar
t > 0); |
694 if (needSpace && !renderer->style()->isCollapsibleWhiteSpace(m_lastChara
cter) && m_lastCharacter) { | 694 if (needSpace && !renderer->style()->isCollapsibleWhiteSpace(m_lastChara
cter) && m_lastCharacter) { |
695 if (m_lastTextNode == m_node && runStart > 0 && str[runStart - 1] ==
' ') { | 695 if (m_lastTextNode == m_node && runStart > 0 && str[runStart - 1] ==
' ') { |
696 unsigned spaceRunStart = runStart - 1; | 696 unsigned spaceRunStart = runStart - 1; |
697 while (spaceRunStart > 0 && str[spaceRunStart - 1] == ' ') | 697 while (spaceRunStart > 0 && str[spaceRunStart - 1] == ' ') |
698 --spaceRunStart; | 698 --spaceRunStart; |
699 emitText(m_node, renderer, spaceRunStart, spaceRunStart + 1); | 699 emitText(m_node, renderer, spaceRunStart, spaceRunStart + 1); |
700 } else { | 700 } else { |
701 emitCharacter(' ', m_node, 0, runStart, runStart); | 701 emitCharacter(space, m_node, 0, runStart, runStart); |
702 } | 702 } |
703 return; | 703 return; |
704 } | 704 } |
705 unsigned textBoxEnd = textBoxStart + m_textBox->len(); | 705 unsigned textBoxEnd = textBoxStart + m_textBox->len(); |
706 unsigned runEnd = std::min(textBoxEnd, end); | 706 unsigned runEnd = std::min(textBoxEnd, end); |
707 | 707 |
708 // Determine what the next text box will be, but don't advance yet | 708 // Determine what the next text box will be, but don't advance yet |
709 InlineTextBox* nextTextBox = 0; | 709 InlineTextBox* nextTextBox = 0; |
710 if (renderer->containsReversedText()) { | 710 if (renderer->containsReversedText()) { |
711 if (m_sortedTextBoxesPosition + 1 < m_sortedTextBoxes.size()) | 711 if (m_sortedTextBoxesPosition + 1 < m_sortedTextBoxes.size()) |
712 nextTextBox = m_sortedTextBoxes[m_sortedTextBoxesPosition + 1]; | 712 nextTextBox = m_sortedTextBoxes[m_sortedTextBoxesPosition + 1]; |
713 } else { | 713 } else { |
714 nextTextBox = m_textBox->nextTextBox(); | 714 nextTextBox = m_textBox->nextTextBox(); |
715 } | 715 } |
716 ASSERT(!nextTextBox || nextTextBox->renderer() == renderer); | 716 ASSERT(!nextTextBox || nextTextBox->renderer() == renderer); |
717 | 717 |
718 if (runStart < runEnd) { | 718 if (runStart < runEnd) { |
719 // Handle either a single newline character (which becomes a space), | 719 // Handle either a single newline character (which becomes a space), |
720 // or a run of characters that does not include a newline. | 720 // or a run of characters that does not include a newline. |
721 // This effectively translates newlines to spaces without copying th
e text. | 721 // This effectively translates newlines to spaces without copying th
e text. |
722 if (str[runStart] == '\n') { | 722 if (str[runStart] == '\n') { |
723 emitCharacter(' ', m_node, 0, runStart, runStart + 1); | 723 emitCharacter(space, m_node, 0, runStart, runStart + 1); |
724 m_offset = runStart + 1; | 724 m_offset = runStart + 1; |
725 } else { | 725 } else { |
726 size_t subrunEnd = str.find('\n', runStart); | 726 size_t subrunEnd = str.find('\n', runStart); |
727 if (subrunEnd == kNotFound || subrunEnd > runEnd) | 727 if (subrunEnd == kNotFound || subrunEnd > runEnd) |
728 subrunEnd = runEnd; | 728 subrunEnd = runEnd; |
729 | 729 |
730 m_offset = subrunEnd; | 730 m_offset = subrunEnd; |
731 emitText(m_node, renderer, runStart, subrunEnd); | 731 emitText(m_node, renderer, runStart, subrunEnd); |
732 } | 732 } |
733 | 733 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
797 RenderObject* renderer = m_node->renderer(); | 797 RenderObject* renderer = m_node->renderer(); |
798 if (renderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) | 798 if (renderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) |
799 return false; | 799 return false; |
800 | 800 |
801 if (m_emitsObjectReplacementCharacter) { | 801 if (m_emitsObjectReplacementCharacter) { |
802 emitCharacter(objectReplacementCharacter, m_node->parentNode(), m_node,
0, 1); | 802 emitCharacter(objectReplacementCharacter, m_node->parentNode(), m_node,
0, 1); |
803 return true; | 803 return true; |
804 } | 804 } |
805 | 805 |
806 if (m_lastTextNodeEndedWithCollapsedSpace) { | 806 if (m_lastTextNodeEndedWithCollapsedSpace) { |
807 emitCharacter(' ', m_lastTextNode->parentNode(), m_lastTextNode, 1, 1); | 807 emitCharacter(space, m_lastTextNode->parentNode(), m_lastTextNode, 1, 1)
; |
808 return false; | 808 return false; |
809 } | 809 } |
810 | 810 |
811 if (m_entersTextControls && renderer->isTextControl()) { | 811 if (m_entersTextControls && renderer->isTextControl()) { |
812 // The shadow tree should be already visited. | 812 // The shadow tree should be already visited. |
813 return true; | 813 return true; |
814 } | 814 } |
815 | 815 |
816 m_hasEmitted = true; | 816 m_hasEmitted = true; |
817 | 817 |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 // on m_node to see if it necessitates emitting a character first and will e
arly return | 1073 // on m_node to see if it necessitates emitting a character first and will e
arly return |
1074 // before encountering shouldRepresentNodeOffsetZero()s worse case behavior. | 1074 // before encountering shouldRepresentNodeOffsetZero()s worse case behavior. |
1075 if (shouldEmitTabBeforeNode(m_node)) { | 1075 if (shouldEmitTabBeforeNode(m_node)) { |
1076 if (shouldRepresentNodeOffsetZero()) | 1076 if (shouldRepresentNodeOffsetZero()) |
1077 emitCharacter('\t', m_node->parentNode(), m_node, 0, 0); | 1077 emitCharacter('\t', m_node->parentNode(), m_node, 0, 0); |
1078 } else if (shouldEmitNewlineBeforeNode(*m_node)) { | 1078 } else if (shouldEmitNewlineBeforeNode(*m_node)) { |
1079 if (shouldRepresentNodeOffsetZero()) | 1079 if (shouldRepresentNodeOffsetZero()) |
1080 emitCharacter('\n', m_node->parentNode(), m_node, 0, 0); | 1080 emitCharacter('\n', m_node->parentNode(), m_node, 0, 0); |
1081 } else if (shouldEmitSpaceBeforeAndAfterNode(m_node)) { | 1081 } else if (shouldEmitSpaceBeforeAndAfterNode(m_node)) { |
1082 if (shouldRepresentNodeOffsetZero()) | 1082 if (shouldRepresentNodeOffsetZero()) |
1083 emitCharacter(' ', m_node->parentNode(), m_node, 0, 0); | 1083 emitCharacter(space, m_node->parentNode(), m_node, 0, 0); |
1084 } | 1084 } |
1085 } | 1085 } |
1086 | 1086 |
1087 bool TextIterator::handleNonTextNode() | 1087 bool TextIterator::handleNonTextNode() |
1088 { | 1088 { |
1089 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText)) | 1089 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText)) |
1090 emitCharacter('\n', m_node->parentNode(), m_node, 0, 1); | 1090 emitCharacter('\n', m_node->parentNode(), m_node, 0, 1); |
1091 else if (m_emitsCharactersBetweenAllVisiblePositions && m_node->renderer() &
& m_node->renderer()->isHR()) | 1091 else if (m_emitsCharactersBetweenAllVisiblePositions && m_node->renderer() &
& m_node->renderer()->isHR()) |
1092 emitCharacter(' ', m_node->parentNode(), m_node, 0, 1); | 1092 emitCharacter(space, m_node->parentNode(), m_node, 0, 1); |
1093 else | 1093 else |
1094 representNodeOffsetZero(); | 1094 representNodeOffsetZero(); |
1095 | 1095 |
1096 return true; | 1096 return true; |
1097 } | 1097 } |
1098 | 1098 |
1099 void TextIterator::exitNode() | 1099 void TextIterator::exitNode() |
1100 { | 1100 { |
1101 // prevent emitting a newline when exiting a collapsed block at beginning of
the range | 1101 // prevent emitting a newline when exiting a collapsed block at beginning of
the range |
1102 // FIXME: !m_hasEmitted does not necessarily mean there was a collapsed bloc
k... it could | 1102 // FIXME: !m_hasEmitted does not necessarily mean there was a collapsed bloc
k... it could |
(...skipping 23 matching lines...) Expand all Loading... |
1126 ASSERT(!m_needsAnotherNewline); | 1126 ASSERT(!m_needsAnotherNewline); |
1127 m_needsAnotherNewline = addNewline; | 1127 m_needsAnotherNewline = addNewline; |
1128 } else if (addNewline) { | 1128 } else if (addNewline) { |
1129 // insert a newline with a position following this block's contents. | 1129 // insert a newline with a position following this block's contents. |
1130 emitCharacter('\n', baseNode->parentNode(), baseNode, 1, 1); | 1130 emitCharacter('\n', baseNode->parentNode(), baseNode, 1, 1); |
1131 } | 1131 } |
1132 } | 1132 } |
1133 | 1133 |
1134 // If nothing was emitted, see if we need to emit a space. | 1134 // If nothing was emitted, see if we need to emit a space. |
1135 if (!m_positionNode && shouldEmitSpaceBeforeAndAfterNode(m_node)) | 1135 if (!m_positionNode && shouldEmitSpaceBeforeAndAfterNode(m_node)) |
1136 emitCharacter(' ', baseNode->parentNode(), baseNode, 1, 1); | 1136 emitCharacter(space, baseNode->parentNode(), baseNode, 1, 1); |
1137 } | 1137 } |
1138 | 1138 |
1139 void TextIterator::emitCharacter(UChar c, Node* textNode, Node* offsetBaseNode,
int textStartOffset, int textEndOffset) | 1139 void TextIterator::emitCharacter(UChar c, Node* textNode, Node* offsetBaseNode,
int textStartOffset, int textEndOffset) |
1140 { | 1140 { |
1141 m_hasEmitted = true; | 1141 m_hasEmitted = true; |
1142 | 1142 |
1143 // remember information with which to construct the TextIterator::range() | 1143 // remember information with which to construct the TextIterator::range() |
1144 // NOTE: textNode is often not a text node, so the range will specify child
nodes of positionNode | 1144 // NOTE: textNode is often not a text node, so the range will specify child
nodes of positionNode |
1145 m_positionNode = textNode; | 1145 m_positionNode = textNode; |
1146 m_positionOffsetBaseNode = offsetBaseNode; | 1146 m_positionOffsetBaseNode = offsetBaseNode; |
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2215 resultEnd = collapseTo; | 2215 resultEnd = collapseTo; |
2216 return; | 2216 return; |
2217 } | 2217 } |
2218 } | 2218 } |
2219 | 2219 |
2220 CharacterIterator computeRangeIterator(inputStart, inputEnd, iteratorFlagsFo
rFindPlainText); | 2220 CharacterIterator computeRangeIterator(inputStart, inputEnd, iteratorFlagsFo
rFindPlainText); |
2221 calculateCharacterSubrange(computeRangeIterator, matchStart, matchLength, re
sultStart, resultEnd); | 2221 calculateCharacterSubrange(computeRangeIterator, matchStart, matchLength, re
sultStart, resultEnd); |
2222 } | 2222 } |
2223 | 2223 |
2224 } | 2224 } |
OLD | NEW |