| 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 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 // Table cells are delimited by tabs. | 740 // Table cells are delimited by tabs. |
| 741 if (!r || !isTableCell(node)) | 741 if (!r || !isTableCell(node)) |
| 742 return false; | 742 return false; |
| 743 | 743 |
| 744 // Want a tab before every cell other than the first one | 744 // Want a tab before every cell other than the first one |
| 745 RenderTableCell* rc = toRenderTableCell(r); | 745 RenderTableCell* rc = toRenderTableCell(r); |
| 746 RenderTable* t = rc->table(); | 746 RenderTable* t = rc->table(); |
| 747 return t && (t->cellBefore(rc) || t->cellAbove(rc)); | 747 return t && (t->cellBefore(rc) || t->cellAbove(rc)); |
| 748 } | 748 } |
| 749 | 749 |
| 750 static bool shouldEmitNewlineForNode(Node* node) | 750 static bool shouldEmitNewlineForNode(Node* node, bool emitsOriginalText) |
| 751 { | 751 { |
| 752 // br elements are represented by a single newline. | 752 RenderObject* renderer = node->renderer(); |
| 753 RenderObject* r = node->renderer(); | 753 |
| 754 if (!r) | 754 if (renderer ? !renderer->isBR() : !node->hasTagName(brTag)) |
| 755 return node->hasTagName(brTag); | 755 return false; |
| 756 | 756 return emitsOriginalText || !(node->isInShadowTree() && node->shadowHost()->
toInputElement()); |
| 757 return r->isBR(); | |
| 758 } | 757 } |
| 759 | 758 |
| 760 static bool shouldEmitNewlinesBeforeAndAfterNode(Node* node) | 759 static bool shouldEmitNewlinesBeforeAndAfterNode(Node* node) |
| 761 { | 760 { |
| 762 // Block flow (versus inline flow) is represented by having | 761 // Block flow (versus inline flow) is represented by having |
| 763 // a newline both before and after the element. | 762 // a newline both before and after the element. |
| 764 RenderObject* r = node->renderer(); | 763 RenderObject* r = node->renderer(); |
| 765 if (!r) { | 764 if (!r) { |
| 766 return (node->hasTagName(blockquoteTag) | 765 return (node->hasTagName(blockquoteTag) |
| 767 || node->hasTagName(ddTag) | 766 || node->hasTagName(ddTag) |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 if (shouldRepresentNodeOffsetZero()) | 948 if (shouldRepresentNodeOffsetZero()) |
| 950 emitCharacter('\n', m_node->parentNode(), m_node, 0, 0); | 949 emitCharacter('\n', m_node->parentNode(), m_node, 0, 0); |
| 951 } else if (shouldEmitSpaceBeforeAndAfterNode(m_node)) { | 950 } else if (shouldEmitSpaceBeforeAndAfterNode(m_node)) { |
| 952 if (shouldRepresentNodeOffsetZero()) | 951 if (shouldRepresentNodeOffsetZero()) |
| 953 emitCharacter(' ', m_node->parentNode(), m_node, 0, 0); | 952 emitCharacter(' ', m_node->parentNode(), m_node, 0, 0); |
| 954 } | 953 } |
| 955 } | 954 } |
| 956 | 955 |
| 957 bool TextIterator::handleNonTextNode() | 956 bool TextIterator::handleNonTextNode() |
| 958 { | 957 { |
| 959 if (shouldEmitNewlineForNode(m_node)) | 958 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText)) |
| 960 emitCharacter('\n', m_node->parentNode(), m_node, 0, 1); | 959 emitCharacter('\n', m_node->parentNode(), m_node, 0, 1); |
| 961 else if (m_emitsCharactersBetweenAllVisiblePositions && m_node->renderer() &
& m_node->renderer()->isHR()) | 960 else if (m_emitsCharactersBetweenAllVisiblePositions && m_node->renderer() &
& m_node->renderer()->isHR()) |
| 962 emitCharacter(' ', m_node->parentNode(), m_node, 0, 1); | 961 emitCharacter(' ', m_node->parentNode(), m_node, 0, 1); |
| 963 else | 962 else |
| 964 representNodeOffsetZero(); | 963 representNodeOffsetZero(); |
| 965 | 964 |
| 966 return true; | 965 return true; |
| 967 } | 966 } |
| 968 | 967 |
| 969 void TextIterator::exitNode() | 968 void TextIterator::exitNode() |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 , m_positionEndOffset(0) | 1102 , m_positionEndOffset(0) |
| 1104 , m_textCharacters(0) | 1103 , m_textCharacters(0) |
| 1105 , m_textLength(0) | 1104 , m_textLength(0) |
| 1106 , m_lastTextNode(0) | 1105 , m_lastTextNode(0) |
| 1107 , m_lastCharacter(0) | 1106 , m_lastCharacter(0) |
| 1108 , m_singleCharacterBuffer(0) | 1107 , m_singleCharacterBuffer(0) |
| 1109 , m_havePassedStartNode(false) | 1108 , m_havePassedStartNode(false) |
| 1110 , m_shouldHandleFirstLetter(false) | 1109 , m_shouldHandleFirstLetter(false) |
| 1111 , m_stopsOnFormControls(false) | 1110 , m_stopsOnFormControls(false) |
| 1112 , m_shouldStop(false) | 1111 , m_shouldStop(false) |
| 1112 , m_emitsOriginalText(false) |
| 1113 { | 1113 { |
| 1114 } | 1114 } |
| 1115 | 1115 |
| 1116 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
TextIteratorBehavior behavior) | 1116 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
TextIteratorBehavior behavior) |
| 1117 : m_node(0) | 1117 : m_node(0) |
| 1118 , m_offset(0) | 1118 , m_offset(0) |
| 1119 , m_handledNode(false) | 1119 , m_handledNode(false) |
| 1120 , m_handledChildren(false) | 1120 , m_handledChildren(false) |
| 1121 , m_startNode(0) | 1121 , m_startNode(0) |
| 1122 , m_startOffset(0) | 1122 , m_startOffset(0) |
| 1123 , m_endNode(0) | 1123 , m_endNode(0) |
| 1124 , m_endOffset(0) | 1124 , m_endOffset(0) |
| 1125 , m_positionNode(0) | 1125 , m_positionNode(0) |
| 1126 , m_positionStartOffset(0) | 1126 , m_positionStartOffset(0) |
| 1127 , m_positionEndOffset(0) | 1127 , m_positionEndOffset(0) |
| 1128 , m_textCharacters(0) | 1128 , m_textCharacters(0) |
| 1129 , m_textLength(0) | 1129 , m_textLength(0) |
| 1130 , m_lastTextNode(0) | 1130 , m_lastTextNode(0) |
| 1131 , m_lastCharacter(0) | 1131 , m_lastCharacter(0) |
| 1132 , m_singleCharacterBuffer(0) | 1132 , m_singleCharacterBuffer(0) |
| 1133 , m_havePassedStartNode(false) | 1133 , m_havePassedStartNode(false) |
| 1134 , m_shouldHandleFirstLetter(false) | 1134 , m_shouldHandleFirstLetter(false) |
| 1135 , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls) | 1135 , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls) |
| 1136 , m_shouldStop(false) | 1136 , m_shouldStop(false) |
| 1137 , m_emitsOriginalText(false) |
| 1137 { | 1138 { |
| 1138 ASSERT(behavior == TextIteratorDefaultBehavior || behavior == TextIteratorSt
opsOnFormControls); | 1139 ASSERT(behavior == TextIteratorDefaultBehavior || behavior == TextIteratorSt
opsOnFormControls); |
| 1139 | 1140 |
| 1140 if (!r) | 1141 if (!r) |
| 1141 return; | 1142 return; |
| 1142 | 1143 |
| 1143 Node* startNode = r->startContainer(); | 1144 Node* startNode = r->startContainer(); |
| 1144 if (!startNode) | 1145 if (!startNode) |
| 1145 return; | 1146 return; |
| 1146 Node* endNode = r->endContainer(); | 1147 Node* endNode = r->endContainer(); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 // code in moveParagraphs, so we use a comma. Unconditionally emit | 1336 // code in moveParagraphs, so we use a comma. Unconditionally emit |
| 1336 // here because this iterator is only used for boundary finding. | 1337 // here because this iterator is only used for boundary finding. |
| 1337 emitCharacter(',', m_node->parentNode(), index, index + 1); | 1338 emitCharacter(',', m_node->parentNode(), index, index + 1); |
| 1338 return true; | 1339 return true; |
| 1339 } | 1340 } |
| 1340 | 1341 |
| 1341 bool SimplifiedBackwardsTextIterator::handleNonTextNode() | 1342 bool SimplifiedBackwardsTextIterator::handleNonTextNode() |
| 1342 { | 1343 { |
| 1343 // We can use a linefeed in place of a tab because this simple iterator is o
nly used to | 1344 // We can use a linefeed in place of a tab because this simple iterator is o
nly used to |
| 1344 // find boundaries, not actual content. A linefeed breaks words, sentences,
and paragraphs. | 1345 // find boundaries, not actual content. A linefeed breaks words, sentences,
and paragraphs. |
| 1345 if (shouldEmitNewlineForNode(m_node) || shouldEmitNewlineAfterNode(m_node) |
| shouldEmitTabBeforeNode(m_node)) { | 1346 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewli
neAfterNode(m_node) || shouldEmitTabBeforeNode(m_node)) { |
| 1346 unsigned index = m_node->nodeIndex(); | 1347 unsigned index = m_node->nodeIndex(); |
| 1347 // The start of this emitted range is wrong. Ensuring correctness would
require | 1348 // The start of this emitted range is wrong. Ensuring correctness would
require |
| 1348 // VisiblePositions and so would be slow. previousBoundary expects this. | 1349 // VisiblePositions and so would be slow. previousBoundary expects this. |
| 1349 emitCharacter('\n', m_node->parentNode(), index + 1, index + 1); | 1350 emitCharacter('\n', m_node->parentNode(), index + 1, index + 1); |
| 1350 } | 1351 } |
| 1351 return true; | 1352 return true; |
| 1352 } | 1353 } |
| 1353 | 1354 |
| 1354 void SimplifiedBackwardsTextIterator::exitNode() | 1355 void SimplifiedBackwardsTextIterator::exitNode() |
| 1355 { | 1356 { |
| 1356 if (shouldEmitNewlineForNode(m_node) || shouldEmitNewlineBeforeNode(m_node)
|| shouldEmitTabBeforeNode(m_node)) { | 1357 if (shouldEmitNewlineForNode(m_node, m_emitsOriginalText) || shouldEmitNewli
neBeforeNode(m_node) || shouldEmitTabBeforeNode(m_node)) { |
| 1357 // The start of this emitted range is wrong. Ensuring correctness would
require | 1358 // The start of this emitted range is wrong. Ensuring correctness would
require |
| 1358 // VisiblePositions and so would be slow. previousBoundary expects this. | 1359 // VisiblePositions and so would be slow. previousBoundary expects this. |
| 1359 emitCharacter('\n', m_node, 0, 0); | 1360 emitCharacter('\n', m_node, 0, 0); |
| 1360 } | 1361 } |
| 1361 } | 1362 } |
| 1362 | 1363 |
| 1363 void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node* node, int sta
rtOffset, int endOffset) | 1364 void SimplifiedBackwardsTextIterator::emitCharacter(UChar c, Node* node, int sta
rtOffset, int endOffset) |
| 1364 { | 1365 { |
| 1365 m_singleCharacterBuffer = c; | 1366 m_singleCharacterBuffer = c; |
| 1366 m_positionNode = node; | 1367 m_positionNode = node; |
| (...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2648 if (!matchLength) | 2649 if (!matchLength) |
| 2649 return collapsedToBoundary(range, !(options & Backwards)); | 2650 return collapsedToBoundary(range, !(options & Backwards)); |
| 2650 } | 2651 } |
| 2651 | 2652 |
| 2652 // Then, find the document position of the start and the end of the text. | 2653 // Then, find the document position of the start and the end of the text. |
| 2653 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
); | 2654 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
); |
| 2654 return characterSubrange(computeRangeIterator, matchStart, matchLength); | 2655 return characterSubrange(computeRangeIterator, matchStart, matchLength); |
| 2655 } | 2656 } |
| 2656 | 2657 |
| 2657 } | 2658 } |
| OLD | NEW |