| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007 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 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 : m_client(&client) | 225 : m_client(&client) |
| 226 , m_start(start) | 226 , m_start(start) |
| 227 , m_end(end) | 227 , m_end(end) |
| 228 { | 228 { |
| 229 } | 229 } |
| 230 | 230 |
| 231 TextCheckingHelper::~TextCheckingHelper() | 231 TextCheckingHelper::~TextCheckingHelper() |
| 232 { | 232 { |
| 233 } | 233 } |
| 234 | 234 |
| 235 String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, boo
l markAll) | |
| 236 { | |
| 237 // TODO(dglazkov): The use of updateStyleAndLayoutIgnorePendingStylesheets n
eeds to be audited. | |
| 238 // see http://crbug.com/590369 for more details. | |
| 239 m_start.document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
| 240 | |
| 241 WordAwareIterator it(m_start, m_end); | |
| 242 firstMisspellingOffset = 0; | |
| 243 | |
| 244 String firstMisspelling; | |
| 245 int currentChunkOffset = 0; | |
| 246 | |
| 247 while (!it.atEnd()) { | |
| 248 int length = it.length(); | |
| 249 | |
| 250 // Skip some work for one-space-char hunks | |
| 251 if (!(length == 1 && it.characterAt(0) == ' ')) { | |
| 252 | |
| 253 int misspellingLocation = -1; | |
| 254 int misspellingLength = 0; | |
| 255 m_client->textChecker().checkSpellingOfString(it.substring(0, length
), &misspellingLocation, &misspellingLength); | |
| 256 | |
| 257 // 5490627 shows that there was some code path here where the String
constructor below crashes. | |
| 258 // We don't know exactly what combination of bad input caused this,
so we're making this much | |
| 259 // more robust against bad input on release builds. | |
| 260 DCHECK_GE(misspellingLength, 0); | |
| 261 DCHECK_GE(misspellingLocation, -1); | |
| 262 DCHECK(!misspellingLength || misspellingLocation >= 0); | |
| 263 DCHECK_LT(misspellingLocation, length); | |
| 264 DCHECK_LE(misspellingLength, length); | |
| 265 DCHECK_LE(misspellingLocation + misspellingLength, length); | |
| 266 | |
| 267 if (misspellingLocation >= 0 && misspellingLength > 0 && misspelling
Location < length && misspellingLength <= length && misspellingLocation + misspe
llingLength <= length) { | |
| 268 | |
| 269 // Compute range of misspelled word | |
| 270 const EphemeralRange misspellingRange = calculateCharacterSubran
ge(EphemeralRange(m_start, m_end), currentChunkOffset + misspellingLocation, mis
spellingLength); | |
| 271 | |
| 272 // Remember first-encountered misspelling and its offset. | |
| 273 if (!firstMisspelling) { | |
| 274 firstMisspellingOffset = currentChunkOffset + misspellingLoc
ation; | |
| 275 firstMisspelling = it.substring(misspellingLocation, misspel
lingLength); | |
| 276 } | |
| 277 | |
| 278 // Store marker for misspelled word. | |
| 279 misspellingRange.document().markers().addMarker(misspellingRange
.startPosition(), misspellingRange.endPosition(), DocumentMarker::Spelling); | |
| 280 | |
| 281 // Bail out if we're marking only the first misspelling, and not
all instances. | |
| 282 if (!markAll) | |
| 283 break; | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 currentChunkOffset += length; | |
| 288 it.advance(); | |
| 289 } | |
| 290 | |
| 291 return firstMisspelling; | |
| 292 } | |
| 293 | |
| 294 String TextCheckingHelper::findFirstMisspellingOrBadGrammar(int& outFirstFoundOf
fset) | 235 String TextCheckingHelper::findFirstMisspellingOrBadGrammar(int& outFirstFoundOf
fset) |
| 295 { | 236 { |
| 296 if (!unifiedTextCheckerEnabled()) | |
| 297 return ""; | |
| 298 | |
| 299 String firstFoundItem; | 237 String firstFoundItem; |
| 300 String misspelledWord; | 238 String misspelledWord; |
| 301 | 239 |
| 302 // Initialize out parameter; it will be updated if we find something to retu
rn. | 240 // Initialize out parameter; it will be updated if we find something to retu
rn. |
| 303 outFirstFoundOffset = 0; | 241 outFirstFoundOffset = 0; |
| 304 | 242 |
| 305 // Expand the search range to encompass entire paragraphs, since text checki
ng needs that much context. | 243 // Expand the search range to encompass entire paragraphs, since text checki
ng needs that much context. |
| 306 // Determine the character offset from the start of the paragraph to the sta
rt of the original search range, | 244 // Determine the character offset from the start of the paragraph to the sta
rt of the original search range, |
| 307 // since we will want to ignore results in this area. | 245 // since we will want to ignore results in this area. |
| 308 Position paragraphStart = startOfParagraph(createVisiblePosition(m_start)).t
oParentAnchoredPosition(); | 246 Position paragraphStart = startOfParagraph(createVisiblePosition(m_start)).t
oParentAnchoredPosition(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 break; | 298 break; |
| 361 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo
sition(paragraphEnd)); | 299 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo
sition(paragraphEnd)); |
| 362 paragraphStart = newParagraphStart.toParentAnchoredPosition(); | 300 paragraphStart = newParagraphStart.toParentAnchoredPosition(); |
| 363 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio
n(); | 301 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio
n(); |
| 364 firstIteration = false; | 302 firstIteration = false; |
| 365 totalLengthProcessed += currentLength; | 303 totalLengthProcessed += currentLength; |
| 366 } | 304 } |
| 367 return firstFoundItem; | 305 return firstFoundItem; |
| 368 } | 306 } |
| 369 | 307 |
| 370 bool TextCheckingHelper::markAllMisspellings() | |
| 371 { | |
| 372 // Use the "markAll" feature of findFirstMisspelling. Ignore the return valu
e and the "out parameter"; | |
| 373 // all we need to do is mark every instance. | |
| 374 int ignoredOffset; | |
| 375 return findFirstMisspelling(ignoredOffset, true).isEmpty(); | |
| 376 } | |
| 377 | |
| 378 bool TextCheckingHelper::unifiedTextCheckerEnabled() const | |
| 379 { | |
| 380 DCHECK(m_start.isNotNull()); | |
| 381 Document& doc = m_start.computeContainerNode()->document(); | |
| 382 return blink::unifiedTextCheckerEnabled(doc.frame()); | |
| 383 } | |
| 384 | |
| 385 bool unifiedTextCheckerEnabled(const LocalFrame* frame) | |
| 386 { | |
| 387 if (!frame) | |
| 388 return false; | |
| 389 | |
| 390 const Settings* settings = frame->settings(); | |
| 391 if (!settings) | |
| 392 return false; | |
| 393 | |
| 394 return settings->unifiedTextCheckerEnabled(); | |
| 395 } | |
| 396 | |
| 397 } // namespace blink | 308 } // namespace blink |
| OLD | NEW |