OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
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 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1132 | 1132 |
1133 // Initialize out parameters; they will be updated if we find something to | 1133 // Initialize out parameters; they will be updated if we find something to |
1134 // return. | 1134 // return. |
1135 String first_found_item; | 1135 String first_found_item; |
1136 int first_found_offset = 0; | 1136 int first_found_offset = 0; |
1137 | 1137 |
1138 // Expand the search range to encompass entire paragraphs, since text checking | 1138 // Expand the search range to encompass entire paragraphs, since text checking |
1139 // needs that much context. Determine the character offset from the start of | 1139 // needs that much context. Determine the character offset from the start of |
1140 // the paragraph to the start of the original search range, since we will want | 1140 // the paragraph to the start of the original search range, since we will want |
1141 // to ignore results in this area. | 1141 // to ignore results in this area. |
1142 Position paragraph_start = | 1142 EphemeralRange paragraph_range = |
1143 StartOfParagraph(CreateVisiblePosition(start)).ToParentAnchoredPosition(); | 1143 ExpandToParagraphBoundary(EphemeralRange(start, start)); |
1144 Position paragraph_end = end; | 1144 Position paragraph_start = paragraph_range.StartPosition(); |
1145 int total_range_length = | 1145 Position paragraph_end = paragraph_range.EndPosition(); |
1146 TextIterator::RangeLength(paragraph_start, paragraph_end); | |
1147 paragraph_end = | |
1148 EndOfParagraph(CreateVisiblePosition(start)).ToParentAnchoredPosition(); | |
1149 | 1146 |
1150 int range_start_offset = TextIterator::RangeLength(paragraph_start, start); | 1147 const int total_range_length = |
| 1148 TextIterator::RangeLength(paragraph_start, end); |
| 1149 const int range_start_offset = |
| 1150 TextIterator::RangeLength(paragraph_start, start); |
1151 int total_length_processed = 0; | 1151 int total_length_processed = 0; |
1152 | 1152 |
1153 bool first_iteration = true; | 1153 bool first_iteration = true; |
1154 bool last_iteration = false; | 1154 bool last_iteration = false; |
1155 while (total_length_processed < total_range_length) { | 1155 while (total_length_processed < total_range_length) { |
1156 // Iterate through the search range by paragraphs, checking each one for | 1156 // Iterate through the search range by paragraphs, checking each one for |
1157 // spelling. | 1157 // spelling. |
1158 int current_length = | 1158 int current_length = |
1159 TextIterator::RangeLength(paragraph_start, paragraph_end); | 1159 TextIterator::RangeLength(paragraph_start, paragraph_end); |
1160 int current_start_offset = first_iteration ? range_start_offset : 0; | 1160 int current_start_offset = first_iteration ? range_start_offset : 0; |
1161 int current_end_offset = current_length; | 1161 int current_end_offset = current_length; |
1162 if (InSameParagraph(CreateVisiblePosition(paragraph_start), | 1162 if (InSameParagraph(CreateVisiblePosition(paragraph_start), |
1163 CreateVisiblePosition(end))) { | 1163 CreateVisiblePosition(end))) { |
1164 // Determine the character offset from the end of the original search | 1164 // Determine the character offset from the end of the original search |
1165 // range to the end of the paragraph, since we will want to ignore results | 1165 // range to the end of the paragraph, since we will want to ignore results |
1166 // in this area. | 1166 // in this area. |
1167 current_end_offset = TextIterator::RangeLength(paragraph_start, end); | 1167 current_end_offset = TextIterator::RangeLength(paragraph_start, end); |
1168 last_iteration = true; | 1168 last_iteration = true; |
1169 } | 1169 } |
1170 if (current_start_offset < current_end_offset) { | 1170 if (current_start_offset < current_end_offset) { |
1171 String paragraph_string = | 1171 String paragraph_string = PlainText(paragraph_range); |
1172 PlainText(EphemeralRange(paragraph_start, paragraph_end)); | |
1173 if (paragraph_string.length() > 0) { | 1172 if (paragraph_string.length() > 0) { |
1174 int spelling_location = 0; | 1173 int spelling_location = 0; |
1175 | 1174 |
1176 Vector<TextCheckingResult> results = FindMisspellings(paragraph_string); | 1175 Vector<TextCheckingResult> results = FindMisspellings(paragraph_string); |
1177 | 1176 |
1178 for (unsigned i = 0; i < results.size(); i++) { | 1177 for (unsigned i = 0; i < results.size(); i++) { |
1179 const TextCheckingResult* result = &results[i]; | 1178 const TextCheckingResult* result = &results[i]; |
1180 if (result->location >= current_start_offset && | 1179 if (result->location >= current_start_offset && |
1181 result->location + result->length <= current_end_offset) { | 1180 result->location + result->length <= current_end_offset) { |
1182 DCHECK_GT(result->length, 0); | 1181 DCHECK_GT(result->length, 0); |
(...skipping 13 matching lines...) Expand all Loading... |
1196 TextIterator::RangeLength(start, paragraph_start); | 1195 TextIterator::RangeLength(start, paragraph_start); |
1197 first_found_offset = spelling_offset; | 1196 first_found_offset = spelling_offset; |
1198 first_found_item = misspelled_word; | 1197 first_found_item = misspelled_word; |
1199 break; | 1198 break; |
1200 } | 1199 } |
1201 } | 1200 } |
1202 } | 1201 } |
1203 if (last_iteration || | 1202 if (last_iteration || |
1204 total_length_processed + current_length >= total_range_length) | 1203 total_length_processed + current_length >= total_range_length) |
1205 break; | 1204 break; |
1206 VisiblePosition new_paragraph_start = | 1205 Position new_paragraph_start = |
1207 StartOfNextParagraph(CreateVisiblePosition(paragraph_end)); | 1206 StartOfNextParagraph(CreateVisiblePosition(paragraph_end)) |
| 1207 .DeepEquivalent(); |
1208 if (new_paragraph_start.IsNull()) | 1208 if (new_paragraph_start.IsNull()) |
1209 break; | 1209 break; |
1210 | 1210 |
1211 paragraph_start = new_paragraph_start.ToParentAnchoredPosition(); | 1211 paragraph_range = ExpandToParagraphBoundary( |
1212 paragraph_end = | 1212 EphemeralRange(new_paragraph_start, new_paragraph_start)); |
1213 EndOfParagraph(new_paragraph_start).ToParentAnchoredPosition(); | 1213 paragraph_start = paragraph_range.StartPosition(); |
| 1214 paragraph_end = paragraph_range.EndPosition(); |
1214 first_iteration = false; | 1215 first_iteration = false; |
1215 total_length_processed += current_length; | 1216 total_length_processed += current_length; |
1216 } | 1217 } |
1217 return std::make_pair(first_found_item, first_found_offset); | 1218 return std::make_pair(first_found_item, first_found_offset); |
1218 } | 1219 } |
1219 | 1220 |
1220 // static | 1221 // static |
1221 bool SpellChecker::IsSpellCheckingEnabledAt(const Position& position) { | 1222 bool SpellChecker::IsSpellCheckingEnabledAt(const Position& position) { |
1222 if (position.IsNull()) | 1223 if (position.IsNull()) |
1223 return false; | 1224 return false; |
1224 if (TextControlElement* text_control = EnclosingTextControl(position)) { | 1225 if (TextControlElement* text_control = EnclosingTextControl(position)) { |
1225 if (isHTMLInputElement(text_control)) { | 1226 if (isHTMLInputElement(text_control)) { |
1226 HTMLInputElement& input = toHTMLInputElement(*text_control); | 1227 HTMLInputElement& input = toHTMLInputElement(*text_control); |
1227 // TODO(tkent): The following password type check should be done in | 1228 // TODO(tkent): The following password type check should be done in |
1228 // HTMLElement::spellcheck(). crbug.com/371567 | 1229 // HTMLElement::spellcheck(). crbug.com/371567 |
1229 if (input.type() == InputTypeNames::password) | 1230 if (input.type() == InputTypeNames::password) |
1230 return false; | 1231 return false; |
1231 if (!input.IsFocusedElementInDocument()) | 1232 if (!input.IsFocusedElementInDocument()) |
1232 return false; | 1233 return false; |
1233 } | 1234 } |
1234 } | 1235 } |
1235 HTMLElement* element = | 1236 HTMLElement* element = |
1236 Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode()); | 1237 Traversal<HTMLElement>::FirstAncestorOrSelf(*position.AnchorNode()); |
1237 return element && element->IsSpellCheckingEnabled(); | 1238 return element && element->IsSpellCheckingEnabled(); |
1238 } | 1239 } |
1239 | 1240 |
1240 } // namespace blink | 1241 } // namespace blink |
OLD | NEW |