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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 if (spellingSearchStart == spellingSearchEnd) | 219 if (spellingSearchStart == spellingSearchEnd) |
220 return; // nothing to search in | 220 return; // nothing to search in |
221 | 221 |
222 // We go to the end of our first range instead of the start of it, just to b
e sure | 222 // We go to the end of our first range instead of the start of it, just to b
e sure |
223 // we don't get foiled by any word boundary problems at the start. It means
we might | 223 // we don't get foiled by any word boundary problems at the start. It means
we might |
224 // do a tiny bit more searching. | 224 // do a tiny bit more searching. |
225 Node* searchEndNodeAfterWrap = spellingSearchEnd.computeContainerNode(); | 225 Node* searchEndNodeAfterWrap = spellingSearchEnd.computeContainerNode(); |
226 int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode(); | 226 int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode(); |
227 | 227 |
228 int misspellingOffset = 0; | 228 int misspellingOffset = 0; |
229 GrammarDetail grammarDetail; | |
230 int grammarPhraseOffset = 0; | |
231 Position grammarSearchStart, grammarSearchEnd; | |
232 String badGrammarPhrase; | |
233 String misspelledWord; | 229 String misspelledWord; |
234 | 230 |
235 bool isSpelling = true; | |
236 int foundOffset = 0; | |
237 String foundItem; | |
238 if (unifiedTextCheckerEnabled()) { | 231 if (unifiedTextCheckerEnabled()) { |
239 grammarSearchStart = spellingSearchStart; | 232 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch
Start, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset); |
240 grammarSearchEnd = spellingSearchEnd; | |
241 foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart
, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, g
rammarDetail); | |
242 if (isSpelling) { | |
243 misspelledWord = foundItem; | |
244 misspellingOffset = foundOffset; | |
245 } else { | |
246 badGrammarPhrase = foundItem; | |
247 grammarPhraseOffset = foundOffset; | |
248 } | |
249 } else { | 233 } else { |
250 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch
Start, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); | 234 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch
Start, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); |
251 grammarSearchStart = spellingSearchStart; | |
252 grammarSearchEnd = spellingSearchEnd; | |
253 if (!misspelledWord.isEmpty()) { | |
254 // Stop looking at start of next misspelled word | |
255 CharacterIterator chars(grammarSearchStart, grammarSearchEnd); | |
256 chars.advance(misspellingOffset); | |
257 grammarSearchEnd = chars.startPosition(); | |
258 } | |
259 | |
260 badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearc
hStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset
, false); | |
261 } | 235 } |
262 | 236 |
263 // If we found neither bad grammar nor a misspelled word, wrap and try again
(but don't bother if we started at the beginning of the | 237 // If we did not find a misspelled word, wrap and try again (but don't bothe
r if we started at the beginning of the |
264 // block rather than at a selection). | 238 // block rather than at a selection). |
265 if (startedWithSelection && !misspelledWord && !badGrammarPhrase) { | 239 if (startedWithSelection && !misspelledWord) { |
266 spellingSearchStart = Position::editingPositionOf(topNode, 0); | 240 spellingSearchStart = Position::editingPositionOf(topNode, 0); |
267 // going until the end of the very first chunk we tested is far enough | 241 // going until the end of the very first chunk we tested is far enough |
268 spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap,
searchEndOffsetAfterWrap); | 242 spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap,
searchEndOffsetAfterWrap); |
269 | 243 |
270 if (unifiedTextCheckerEnabled()) { | 244 if (unifiedTextCheckerEnabled()) { |
271 grammarSearchStart = spellingSearchStart; | 245 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSe
archStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset
); |
272 grammarSearchEnd = spellingSearchEnd; | |
273 foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchS
tart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffse
t, grammarDetail); | |
274 if (isSpelling) { | |
275 misspelledWord = foundItem; | |
276 misspellingOffset = foundOffset; | |
277 } else { | |
278 badGrammarPhrase = foundItem; | |
279 grammarPhraseOffset = foundOffset; | |
280 } | |
281 } else { | 246 } else { |
282 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSe
archStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); | 247 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSe
archStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); |
283 grammarSearchStart = spellingSearchStart; | |
284 grammarSearchEnd = spellingSearchEnd; | |
285 if (!misspelledWord.isEmpty()) { | |
286 // Stop looking at start of next misspelled word | |
287 CharacterIterator chars(grammarSearchStart, grammarSearchEnd); | |
288 chars.advance(misspellingOffset); | |
289 grammarSearchEnd = chars.startPosition(); | |
290 } | |
291 | |
292 badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarS
earchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOf
fset, false); | |
293 } | 248 } |
294 } | 249 } |
295 | 250 |
296 if (!badGrammarPhrase.isEmpty()) { | 251 if (!misspelledWord.isEmpty()) { |
297 // We found bad grammar. Since we only searched for bad grammar up to th
e first misspelled word, the bad grammar | 252 // We found a misspelling. Select the misspelling, update the spelling p
anel, and store |
298 // takes precedence and we ignore any potential misspelled word. Select
the grammar detail, update the spelling | |
299 // panel, and store a marker so we draw the green squiggle later. | |
300 | |
301 DCHECK_GT(badGrammarPhrase.length(), 0u); | |
302 DCHECK_NE(grammarDetail.location, -1); | |
303 DCHECK_GT(grammarDetail.length, 0); | |
304 | |
305 // FIXME 4859190: This gets confused with doubled punctuation at the end
of a paragraph | |
306 const EphemeralRange badGrammarRange = calculateCharacterSubrange(Epheme
ralRange(grammarSearchStart, grammarSearchEnd), grammarPhraseOffset + grammarDet
ail.location, grammarDetail.length); | |
307 frame().selection().setSelection(VisibleSelection(badGrammarRange)); | |
308 frame().selection().revealSelection(); | |
309 frame().document()->markers().addMarker(badGrammarRange.startPosition(),
badGrammarRange.endPosition(), DocumentMarker::Grammar, grammarDetail.userDescr
iption); | |
310 } else if (!misspelledWord.isEmpty()) { | |
311 // We found a misspelling, but not any earlier bad grammar. Select the m
isspelling, update the spelling panel, and store | |
312 // a marker so we draw the red squiggle later. | 253 // a marker so we draw the red squiggle later. |
313 | 254 |
314 const EphemeralRange misspellingRange = calculateCharacterSubrange(Ephem
eralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelled
Word.length()); | 255 const EphemeralRange misspellingRange = calculateCharacterSubrange(Ephem
eralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelled
Word.length()); |
315 frame().selection().setSelection(VisibleSelection(misspellingRange)); | 256 frame().selection().setSelection(VisibleSelection(misspellingRange)); |
316 frame().selection().revealSelection(); | 257 frame().selection().revealSelection(); |
317 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord); | 258 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord); |
318 frame().document()->markers().addMarker(misspellingRange.startPosition()
, misspellingRange.endPosition(), DocumentMarker::Spelling); | 259 frame().document()->markers().addMarker(misspellingRange.startPosition()
, misspellingRange.endPosition(), DocumentMarker::Spelling); |
319 } | 260 } |
320 } | 261 } |
321 | 262 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 if (!editableNode || !hasEditableStyle(*editableNode)) | 345 if (!editableNode || !hasEditableStyle(*editableNode)) |
405 return false; | 346 return false; |
406 | 347 |
407 if (!isSpellCheckingEnabledFor(editableNode)) | 348 if (!isSpellCheckingEnabledFor(editableNode)) |
408 return false; | 349 return false; |
409 | 350 |
410 TextCheckingHelper checker(spellCheckerClient(), range.startPosition(), rang
e.endPosition()); | 351 TextCheckingHelper checker(spellCheckerClient(), range.startPosition(), rang
e.endPosition()); |
411 if (checkSpelling) | 352 if (checkSpelling) |
412 return checker.markAllMisspellings(); | 353 return checker.markAllMisspellings(); |
413 | 354 |
414 checker.markAllBadGrammar(); | |
415 return false; | 355 return false; |
416 } | 356 } |
417 | 357 |
418 bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const | 358 bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const |
419 { | 359 { |
420 if (!node) | 360 if (!node) |
421 return false; | 361 return false; |
422 const Element* focusedElement = node->isElementNode() ? toElement(node) : no
de->parentElement(); | 362 const Element* focusedElement = node->isElementNode() ? toElement(node) : no
de->parentElement(); |
423 if (!focusedElement) | 363 if (!focusedElement) |
424 return false; | 364 return false; |
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 visitor->trace(m_frame); | 875 visitor->trace(m_frame); |
936 visitor->trace(m_spellCheckRequester); | 876 visitor->trace(m_spellCheckRequester); |
937 } | 877 } |
938 | 878 |
939 void SpellChecker::prepareForLeakDetection() | 879 void SpellChecker::prepareForLeakDetection() |
940 { | 880 { |
941 m_spellCheckRequester->prepareForLeakDetection(); | 881 m_spellCheckRequester->prepareForLeakDetection(); |
942 } | 882 } |
943 | 883 |
944 } // namespace blink | 884 } // namespace blink |
OLD | NEW |