| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights
reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights
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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 } | 596 } |
| 597 if (!m_textBox && m_remainingTextBox) { | 597 if (!m_textBox && m_remainingTextBox) { |
| 598 m_textBox = m_remainingTextBox; | 598 m_textBox = m_remainingTextBox; |
| 599 m_remainingTextBox = 0; | 599 m_remainingTextBox = 0; |
| 600 m_firstLetterText = 0; | 600 m_firstLetterText = 0; |
| 601 m_offset = 0; | 601 m_offset = 0; |
| 602 handleTextBox(); | 602 handleTextBox(); |
| 603 } | 603 } |
| 604 } | 604 } |
| 605 | 605 |
| 606 static inline RenderText* firstRenderTextInFirstLetter(RenderObject* firstLetter
) |
| 607 { |
| 608 if (!firstLetter) |
| 609 return 0; |
| 610 |
| 611 // FIXME: Should this check descendent objects? |
| 612 for (RenderObject* current = firstLetter->firstChild(); current; current = c
urrent->nextSibling()) { |
| 613 if (current->isText()) |
| 614 return toRenderText(current); |
| 615 } |
| 616 return 0; |
| 617 } |
| 618 |
| 606 void TextIterator::handleTextNodeFirstLetter(RenderTextFragment* renderer) | 619 void TextIterator::handleTextNodeFirstLetter(RenderTextFragment* renderer) |
| 607 { | 620 { |
| 608 if (renderer->firstLetter()) { | 621 if (renderer->firstLetter()) { |
| 609 RenderObject* r = renderer->firstLetter(); | 622 RenderObject* r = renderer->firstLetter(); |
| 610 if (r->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) | 623 if (r->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility) |
| 611 return; | 624 return; |
| 612 for (RenderObject *currChild = r->firstChild(); currChild; currChild->ne
xtSibling()) { | 625 if (RenderText* firstLetter = firstRenderTextInFirstLetter(r)) { |
| 613 if (currChild->isText()) { | 626 m_handledFirstLetter = true; |
| 614 RenderText* firstLetter = toRenderText(currChild); | 627 m_remainingTextBox = m_textBox; |
| 615 m_handledFirstLetter = true; | 628 m_textBox = firstLetter->firstTextBox(); |
| 616 m_remainingTextBox = m_textBox; | 629 m_firstLetterText = firstLetter; |
| 617 m_textBox = firstLetter->firstTextBox(); | |
| 618 m_firstLetterText = firstLetter; | |
| 619 return; | |
| 620 } | |
| 621 } | 630 } |
| 622 } | 631 } |
| 623 m_handledFirstLetter = true; | 632 m_handledFirstLetter = true; |
| 624 } | 633 } |
| 625 | 634 |
| 626 bool TextIterator::handleReplacedElement() | 635 bool TextIterator::handleReplacedElement() |
| 627 { | 636 { |
| 628 if (m_fullyClippedStack.top()) | 637 if (m_fullyClippedStack.top()) |
| 629 return false; | 638 return false; |
| 630 | 639 |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 return node; | 1045 return node; |
| 1037 | 1046 |
| 1038 return node->childNode(textRange->startOffset()); | 1047 return node->childNode(textRange->startOffset()); |
| 1039 } | 1048 } |
| 1040 | 1049 |
| 1041 // -------- | 1050 // -------- |
| 1042 | 1051 |
| 1043 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator() | 1052 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator() |
| 1044 : m_behavior(TextIteratorDefaultBehavior) | 1053 : m_behavior(TextIteratorDefaultBehavior) |
| 1045 , m_node(0) | 1054 , m_node(0) |
| 1055 , m_offset(0) |
| 1056 , m_handledNode(false) |
| 1057 , m_handledChildren(false) |
| 1058 , m_startNode(0) |
| 1059 , m_startOffset(0) |
| 1060 , m_endNode(0) |
| 1061 , m_endOffset(0) |
| 1046 , m_positionNode(0) | 1062 , m_positionNode(0) |
| 1063 , m_positionStartOffset(0) |
| 1064 , m_positionEndOffset(0) |
| 1065 , m_textCharacters(0) |
| 1066 , m_textLength(0) |
| 1067 , m_lastTextNode(0) |
| 1068 , m_lastCharacter(0) |
| 1069 , m_singleCharacterBuffer(0) |
| 1070 , m_havePassedStartNode(false) |
| 1071 , m_shouldHandleFirstLetter(false) |
| 1047 { | 1072 { |
| 1048 } | 1073 } |
| 1049 | 1074 |
| 1050 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
TextIteratorBehavior behavior) | 1075 SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
TextIteratorBehavior behavior) |
| 1051 : m_behavior(behavior) | 1076 : m_behavior(behavior) |
| 1052 , m_node(0) | 1077 , m_node(0) |
| 1078 , m_offset(0) |
| 1079 , m_handledNode(false) |
| 1080 , m_handledChildren(false) |
| 1081 , m_startNode(0) |
| 1082 , m_startOffset(0) |
| 1083 , m_endNode(0) |
| 1084 , m_endOffset(0) |
| 1053 , m_positionNode(0) | 1085 , m_positionNode(0) |
| 1086 , m_positionStartOffset(0) |
| 1087 , m_positionEndOffset(0) |
| 1088 , m_textCharacters(0) |
| 1089 , m_textLength(0) |
| 1090 , m_lastTextNode(0) |
| 1091 , m_lastCharacter(0) |
| 1092 , m_singleCharacterBuffer(0) |
| 1093 , m_havePassedStartNode(false) |
| 1094 , m_shouldHandleFirstLetter(false) |
| 1054 { | 1095 { |
| 1055 ASSERT(m_behavior == TextIteratorDefaultBehavior); | 1096 ASSERT(m_behavior == TextIteratorDefaultBehavior); |
| 1056 | 1097 |
| 1057 if (!r) | 1098 if (!r) |
| 1058 return; | 1099 return; |
| 1059 | 1100 |
| 1060 Node* startNode = r->startContainer(); | 1101 Node* startNode = r->startContainer(); |
| 1061 if (!startNode) | 1102 if (!startNode) |
| 1062 return; | 1103 return; |
| 1063 Node* endNode = r->endContainer(); | 1104 Node* endNode = r->endContainer(); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 | 1212 |
| 1172 if (m_positionNode) | 1213 if (m_positionNode) |
| 1173 return; | 1214 return; |
| 1174 } | 1215 } |
| 1175 } | 1216 } |
| 1176 | 1217 |
| 1177 bool SimplifiedBackwardsTextIterator::handleTextNode() | 1218 bool SimplifiedBackwardsTextIterator::handleTextNode() |
| 1178 { | 1219 { |
| 1179 m_lastTextNode = m_node; | 1220 m_lastTextNode = m_node; |
| 1180 | 1221 |
| 1181 RenderText* renderer = toRenderText(m_node->renderer()); | 1222 int startOffset; |
| 1182 String str = renderer->text(); | 1223 int offsetInNode; |
| 1224 RenderText* renderer = handleFirstLetter(startOffset, offsetInNode); |
| 1225 if (!renderer) |
| 1226 return true; |
| 1183 | 1227 |
| 1184 if (!renderer->firstTextBox() && str.length() > 0) | 1228 String text = renderer->text(); |
| 1229 if (!renderer->firstTextBox() && text.length() > 0) |
| 1185 return true; | 1230 return true; |
| 1186 | 1231 |
| 1187 m_positionEndOffset = m_offset; | 1232 m_positionEndOffset = m_offset; |
| 1188 | 1233 m_offset = startOffset + offsetInNode; |
| 1189 m_offset = (m_node == m_startNode) ? m_startOffset : 0; | |
| 1190 m_positionNode = m_node; | 1234 m_positionNode = m_node; |
| 1191 m_positionStartOffset = m_offset; | 1235 m_positionStartOffset = m_offset; |
| 1236 |
| 1237 ASSERT(0 <= m_positionStartOffset - offsetInNode && m_positionStartOffset -
offsetInNode <= static_cast<int>(text.length())); |
| 1238 ASSERT(1 <= m_positionEndOffset - offsetInNode && m_positionEndOffset - offs
etInNode <= static_cast<int>(text.length())); |
| 1239 ASSERT(m_positionStartOffset <= m_positionEndOffset); |
| 1240 |
| 1192 m_textLength = m_positionEndOffset - m_positionStartOffset; | 1241 m_textLength = m_positionEndOffset - m_positionStartOffset; |
| 1193 m_textCharacters = str.characters() + m_positionStartOffset; | 1242 m_textCharacters = text.characters() + (m_positionStartOffset - offsetInNode
); |
| 1243 ASSERT(m_textCharacters >= text.characters()); |
| 1244 ASSERT(m_textCharacters + m_textLength <= text.characters() + static_cast<in
t>(text.length())); |
| 1194 | 1245 |
| 1195 m_lastCharacter = str[m_positionEndOffset - 1]; | 1246 m_lastCharacter = text[m_positionEndOffset - 1]; |
| 1196 | 1247 |
| 1197 return true; | 1248 return !m_shouldHandleFirstLetter; |
| 1249 } |
| 1250 |
| 1251 RenderText* SimplifiedBackwardsTextIterator::handleFirstLetter(int& startOffset,
int& offsetInNode) |
| 1252 { |
| 1253 RenderText* renderer = toRenderText(m_node->renderer()); |
| 1254 startOffset = (m_node == m_startNode) ? m_startOffset : 0; |
| 1255 |
| 1256 if (!renderer->isTextFragment()) { |
| 1257 offsetInNode = 0; |
| 1258 return renderer; |
| 1259 } |
| 1260 |
| 1261 RenderTextFragment* fragment = toRenderTextFragment(renderer); |
| 1262 int offsetAfterFirstLetter = fragment->start(); |
| 1263 if (startOffset >= offsetAfterFirstLetter) { |
| 1264 ASSERT(!m_shouldHandleFirstLetter); |
| 1265 offsetInNode = offsetAfterFirstLetter; |
| 1266 return renderer; |
| 1267 } |
| 1268 |
| 1269 if (!m_shouldHandleFirstLetter && offsetAfterFirstLetter < m_offset) { |
| 1270 m_shouldHandleFirstLetter = true; |
| 1271 offsetInNode = offsetAfterFirstLetter; |
| 1272 return renderer; |
| 1273 } |
| 1274 |
| 1275 m_shouldHandleFirstLetter = false; |
| 1276 offsetInNode = 0; |
| 1277 return firstRenderTextInFirstLetter(fragment->firstLetter()); |
| 1198 } | 1278 } |
| 1199 | 1279 |
| 1200 bool SimplifiedBackwardsTextIterator::handleReplacedElement() | 1280 bool SimplifiedBackwardsTextIterator::handleReplacedElement() |
| 1201 { | 1281 { |
| 1202 unsigned index = m_node->nodeIndex(); | 1282 unsigned index = m_node->nodeIndex(); |
| 1203 // We want replaced elements to behave like punctuation for boundary | 1283 // We want replaced elements to behave like punctuation for boundary |
| 1204 // finding, and to simply take up space for the selection preservation | 1284 // finding, and to simply take up space for the selection preservation |
| 1205 // code in moveParagraphs, so we use a comma. Unconditionally emit | 1285 // code in moveParagraphs, so we use a comma. Unconditionally emit |
| 1206 // here because this iterator is only used for boundary finding. | 1286 // here because this iterator is only used for boundary finding. |
| 1207 emitCharacter(',', m_node->parentNode(), index, index + 1); | 1287 emitCharacter(',', m_node->parentNode(), index, index + 1); |
| (...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2583 if (!matchLength) | 2663 if (!matchLength) |
| 2584 return collapsedToBoundary(range, !(options & Backwards)); | 2664 return collapsedToBoundary(range, !(options & Backwards)); |
| 2585 } | 2665 } |
| 2586 | 2666 |
| 2587 // Then, find the document position of the start and the end of the text. | 2667 // Then, find the document position of the start and the end of the text. |
| 2588 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
); | 2668 CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls
); |
| 2589 return characterSubrange(computeRangeIterator, matchStart, matchLength); | 2669 return characterSubrange(computeRangeIterator, matchStart, matchLength); |
| 2590 } | 2670 } |
| 2591 | 2671 |
| 2592 } | 2672 } |
| OLD | NEW |