Index: chrome/renderer/spellchecker/spellcheck.cc |
diff --git a/chrome/renderer/spellchecker/spellcheck.cc b/chrome/renderer/spellchecker/spellcheck.cc |
index a43c72778289b7d8e8808c1c67f5c0c8523cb263..fecb307eb1c46ced364c409041a5898c1a7510ac 100644 |
--- a/chrome/renderer/spellchecker/spellcheck.cc |
+++ b/chrome/renderer/spellchecker/spellcheck.cc |
@@ -97,6 +97,29 @@ bool DocumentMarkersRemover::Visit(content::RenderView* render_view) { |
return true; |
} |
+bool IsApostrophe(base::char16 c) { |
+ const base::char16 kApostrophe = 0x27; |
+ const base::char16 kRightSingleQuotationMark = 0x2019; |
+ return c == kApostrophe || c == kRightSingleQuotationMark; |
+} |
+ |
+// Makes sure that the apostrophes in the |spelling_suggestion| are the same |
+// type as in the |misspelled_word| and in the same order. Ignore differences in |
+// the number of apostrophes. |
+void PreserveOriginalApostropheTypes(const base::string16& misspelled_word, |
+ base::string16* spelling_suggestion) { |
+ auto it = spelling_suggestion->begin(); |
+ for (const base::char16& c : misspelled_word) { |
+ if (IsApostrophe(c)) { |
+ it = std::find_if(it, spelling_suggestion->end(), IsApostrophe); |
+ if (it == spelling_suggestion->end()) |
+ return; |
+ |
+ *it++ = c; |
+ } |
+ } |
+} |
+ |
} // namespace |
class SpellCheck::SpellcheckRequest { |
@@ -383,33 +406,44 @@ void SpellCheck::CreateTextCheckingResults( |
const base::string16& line_text, |
const std::vector<SpellCheckResult>& spellcheck_results, |
WebVector<WebTextCheckingResult>* textcheck_results) { |
- // Double-check misspelled words with our spellchecker and attach grammar |
- // markers to them if our spellchecker tells they are correct words, i.e. they |
- // are probably contextually-misspelled words. |
- const base::char16* text = line_text.c_str(); |
- std::vector<WebTextCheckingResult> list; |
- for (size_t i = 0; i < spellcheck_results.size(); ++i) { |
- SpellCheckResult::Decoration decoration = spellcheck_results[i].decoration; |
- int word_location = spellcheck_results[i].location; |
- int word_length = spellcheck_results[i].length; |
- int misspelling_start = 0; |
- int misspelling_length = 0; |
- if (decoration == SpellCheckResult::SPELLING && |
- filter == USE_NATIVE_CHECKER) { |
- if (SpellCheckWord(text + word_location, word_length, 0, |
- &misspelling_start, &misspelling_length, NULL)) { |
- decoration = SpellCheckResult::GRAMMAR; |
- } |
+ std::vector<WebTextCheckingResult> results; |
+ for (const SpellCheckResult& spellcheck_result : spellcheck_results) { |
+ const base::string16& misspelled_word = |
+ line_text.substr(spellcheck_result.location, spellcheck_result.length); |
+ |
+ // Ignore words in custom dictionary. |
+ if (custom_dictionary_.SpellCheckWord(misspelled_word, 0, |
+ misspelled_word.length())) { |
+ continue; |
} |
- if (!custom_dictionary_.SpellCheckWord( |
- line_text, word_location, word_length)) { |
- list.push_back(WebTextCheckingResult( |
- static_cast<WebTextDecorationType>(decoration), |
- word_location + line_offset, |
- word_length, |
- spellcheck_results[i].replacement, |
- spellcheck_results[i].hash)); |
+ |
+ // Use the same types of appostrophes as in the mispelled word. |
+ base::string16 replacement = spellcheck_result.replacement; |
+ PreserveOriginalApostropheTypes(misspelled_word, &replacement); |
+ |
+ // Ignore misspellings due the typographical apostrophe. |
+ if (misspelled_word == replacement) |
+ continue; |
+ |
+ // Double-check misspelled words with out spellchecker and attach grammar |
+ // markers to them if our spellchecker tells us they are correct words, |
+ // i.e. they are probably contextually-misspelled words. |
+ SpellCheckResult::Decoration decoration = spellcheck_result.decoration; |
+ int unused_misspelling_start = 0; |
+ int unused_misspelling_length = 0; |
+ if (decoration == SpellCheckResult::SPELLING && |
+ filter == USE_NATIVE_CHECKER && |
+ SpellCheckWord(misspelled_word.c_str(), misspelled_word.length(), 0, |
+ &unused_misspelling_start, &unused_misspelling_length, |
+ nullptr)) { |
+ decoration = SpellCheckResult::GRAMMAR; |
} |
+ |
+ results.push_back(WebTextCheckingResult( |
+ static_cast<WebTextDecorationType>(decoration), |
+ line_offset + spellcheck_result.location, spellcheck_result.length, |
+ replacement, spellcheck_result.hash)); |
} |
- textcheck_results->assign(list); |
+ |
+ textcheck_results->assign(results); |
} |