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 |