| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h" | 5 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/files/important_file_writer.h" | 12 #include "base/files/important_file_writer.h" |
| 13 #include "base/md5.h" | 13 #include "base/md5.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_split.h" | 15 #include "base/strings/string_split.h" |
| 16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 17 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h" | 17 #include "components/spellcheck/browser/spellcheck_host_metrics.h" |
| 18 #include "chrome/common/chrome_constants.h" | 18 #include "components/spellcheck/common/spellcheck_common.h" |
| 19 #include "chrome/common/spellcheck_common.h" | |
| 20 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 21 #include "sync/api/sync_change.h" | 20 #include "sync/api/sync_change.h" |
| 22 #include "sync/api/sync_error_factory.h" | 21 #include "sync/api/sync_error_factory.h" |
| 23 #include "sync/protocol/sync.pb.h" | 22 #include "sync/protocol/sync.pb.h" |
| 24 | 23 |
| 25 using content::BrowserThread; | 24 using content::BrowserThread; |
| 26 | 25 |
| 27 namespace { | 26 namespace { |
| 28 | 27 |
| 29 // Filename extension for backup dictionary file. | 28 // Filename extension for backup dictionary file. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 75 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 77 words->insert(word_list.begin(), word_list.end()); | 76 words->insert(word_list.begin(), word_list.end()); |
| 78 return VALID_CHECKSUM; | 77 return VALID_CHECKSUM; |
| 79 } | 78 } |
| 80 | 79 |
| 81 // Returns true for valid custom dictionary words. | 80 // Returns true for valid custom dictionary words. |
| 82 bool IsValidWord(const std::string& word) { | 81 bool IsValidWord(const std::string& word) { |
| 83 std::string tmp; | 82 std::string tmp; |
| 84 return !word.empty() && | 83 return !word.empty() && |
| 85 word.size() <= | 84 word.size() <= |
| 86 chrome::spellcheck_common::MAX_CUSTOM_DICTIONARY_WORD_BYTES && | 85 spellcheck_common::MAX_CUSTOM_DICTIONARY_WORD_BYTES && |
| 87 base::IsStringUTF8(word) && | 86 base::IsStringUTF8(word) && |
| 88 base::TRIM_NONE == | 87 base::TRIM_NONE == |
| 89 base::TrimWhitespaceASCII(word, base::TRIM_ALL, &tmp); | 88 base::TrimWhitespaceASCII(word, base::TRIM_ALL, &tmp); |
| 90 } | 89 } |
| 91 | 90 |
| 92 // Removes duplicate and invalid words from |to_add| word list. Looks for | 91 // Removes duplicate and invalid words from |to_add| word list. Looks for |
| 93 // duplicates in both |to_add| and |existing| word lists. Returns a bitmap of | 92 // duplicates in both |to_add| and |existing| word lists. Returns a bitmap of |
| 94 // |ChangeSanitationResult| values. | 93 // |ChangeSanitationResult| values. |
| 95 int SanitizeWordsToAdd(const std::set<std::string>& existing, | 94 int SanitizeWordsToAdd(const std::set<std::string>& existing, |
| 96 std::set<std::string>* to_add) { | 95 std::set<std::string>* to_add) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 int result = VALID_CHANGE; | 170 int result = VALID_CHANGE; |
| 172 if (to_remove->size() > found_words.size()) | 171 if (to_remove->size() > found_words.size()) |
| 173 result |= DETECTED_MISSING_WORDS; | 172 result |= DETECTED_MISSING_WORDS; |
| 174 // Save the sanitized words to be removed. | 173 // Save the sanitized words to be removed. |
| 175 std::swap(*to_remove, found_words); | 174 std::swap(*to_remove, found_words); |
| 176 return result; | 175 return result; |
| 177 } | 176 } |
| 178 | 177 |
| 179 } // namespace | 178 } // namespace |
| 180 | 179 |
| 180 const base::FilePath::CharType SpellcheckCustomDictionary::kCustomDictionaryFile
Name[] = |
| 181 FILE_PATH_LITERAL("Custom Dictionary.txt"); |
| 182 |
| 181 SpellcheckCustomDictionary::Change::Change() { | 183 SpellcheckCustomDictionary::Change::Change() { |
| 182 } | 184 } |
| 183 | 185 |
| 184 SpellcheckCustomDictionary::Change::~Change() { | 186 SpellcheckCustomDictionary::Change::~Change() { |
| 185 } | 187 } |
| 186 | 188 |
| 187 void SpellcheckCustomDictionary::Change::AddWord(const std::string& word) { | 189 void SpellcheckCustomDictionary::Change::AddWord(const std::string& word) { |
| 188 to_add_.insert(word); | 190 to_add_.insert(word); |
| 189 } | 191 } |
| 190 | 192 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 203 if (!to_add_.empty()) | 205 if (!to_add_.empty()) |
| 204 result |= SanitizeWordsToAdd(words, &to_add_); | 206 result |= SanitizeWordsToAdd(words, &to_add_); |
| 205 if (!to_remove_.empty()) | 207 if (!to_remove_.empty()) |
| 206 result |= SanitizeWordsToRemove(words, &to_remove_); | 208 result |= SanitizeWordsToRemove(words, &to_remove_); |
| 207 return result; | 209 return result; |
| 208 } | 210 } |
| 209 | 211 |
| 210 SpellcheckCustomDictionary::SpellcheckCustomDictionary( | 212 SpellcheckCustomDictionary::SpellcheckCustomDictionary( |
| 211 const base::FilePath& dictionary_directory_name) | 213 const base::FilePath& dictionary_directory_name) |
| 212 : custom_dictionary_path_( | 214 : custom_dictionary_path_( |
| 213 dictionary_directory_name.Append(chrome::kCustomDictionaryFileName)), | 215 dictionary_directory_name.Append(kCustomDictionaryFileName)), |
| 214 is_loaded_(false), | 216 is_loaded_(false), |
| 215 weak_ptr_factory_(this) { | 217 weak_ptr_factory_(this) { |
| 216 } | 218 } |
| 217 | 219 |
| 218 SpellcheckCustomDictionary::~SpellcheckCustomDictionary() { | 220 SpellcheckCustomDictionary::~SpellcheckCustomDictionary() { |
| 219 } | 221 } |
| 220 | 222 |
| 221 const std::set<std::string>& SpellcheckCustomDictionary::GetWords() const { | 223 const std::set<std::string>& SpellcheckCustomDictionary::GetWords() const { |
| 222 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 224 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 223 return words_; | 225 return words_; |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 sync_error_handler_.reset(); | 331 sync_error_handler_.reset(); |
| 330 } | 332 } |
| 331 | 333 |
| 332 syncer::SyncDataList SpellcheckCustomDictionary::GetAllSyncData( | 334 syncer::SyncDataList SpellcheckCustomDictionary::GetAllSyncData( |
| 333 syncer::ModelType type) const { | 335 syncer::ModelType type) const { |
| 334 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 336 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 335 DCHECK_EQ(syncer::DICTIONARY, type); | 337 DCHECK_EQ(syncer::DICTIONARY, type); |
| 336 syncer::SyncDataList data; | 338 syncer::SyncDataList data; |
| 337 size_t i = 0; | 339 size_t i = 0; |
| 338 for (const auto& word : words_) { | 340 for (const auto& word : words_) { |
| 339 if (i++ >= chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) | 341 if (i++ >= spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) |
| 340 break; | 342 break; |
| 341 sync_pb::EntitySpecifics specifics; | 343 sync_pb::EntitySpecifics specifics; |
| 342 specifics.mutable_dictionary()->set_word(word); | 344 specifics.mutable_dictionary()->set_word(word); |
| 343 data.push_back(syncer::SyncData::CreateLocalData(word, word, specifics)); | 345 data.push_back(syncer::SyncData::CreateLocalData(word, word, specifics)); |
| 344 } | 346 } |
| 345 return data; | 347 return data; |
| 346 } | 348 } |
| 347 | 349 |
| 348 syncer::SyncError SpellcheckCustomDictionary::ProcessSyncChanges( | 350 syncer::SyncError SpellcheckCustomDictionary::ProcessSyncChanges( |
| 349 const tracked_objects::Location& from_here, | 351 const tracked_objects::Location& from_here, |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 syncer::SyncError error; | 474 syncer::SyncError error; |
| 473 if (!IsSyncing() || dictionary_change.empty()) | 475 if (!IsSyncing() || dictionary_change.empty()) |
| 474 return error; | 476 return error; |
| 475 | 477 |
| 476 // The number of words on the sync server should not exceed the limits. | 478 // The number of words on the sync server should not exceed the limits. |
| 477 int server_size = static_cast<int>(words_.size()) - | 479 int server_size = static_cast<int>(words_.size()) - |
| 478 static_cast<int>(dictionary_change.to_add().size()); | 480 static_cast<int>(dictionary_change.to_add().size()); |
| 479 int max_upload_size = std::max( | 481 int max_upload_size = std::max( |
| 480 0, | 482 0, |
| 481 static_cast<int>( | 483 static_cast<int>( |
| 482 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) - | 484 spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) - |
| 483 server_size); | 485 server_size); |
| 484 int upload_size = std::min( | 486 int upload_size = std::min( |
| 485 static_cast<int>(dictionary_change.to_add().size()), | 487 static_cast<int>(dictionary_change.to_add().size()), |
| 486 max_upload_size); | 488 max_upload_size); |
| 487 | 489 |
| 488 syncer::SyncChangeList sync_change_list; | 490 syncer::SyncChangeList sync_change_list; |
| 489 int i = 0; | 491 int i = 0; |
| 490 | 492 |
| 491 for (const auto& word : dictionary_change.to_add()) { | 493 for (const auto& word : dictionary_change.to_add()) { |
| 492 if (i++ >= upload_size) | 494 if (i++ >= upload_size) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 507 syncer::SyncData::CreateLocalData(word, word, specifics))); | 509 syncer::SyncData::CreateLocalData(word, word, specifics))); |
| 508 } | 510 } |
| 509 | 511 |
| 510 // Send the changes to the sync processor. | 512 // Send the changes to the sync processor. |
| 511 error = sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list); | 513 error = sync_processor_->ProcessSyncChanges(FROM_HERE, sync_change_list); |
| 512 if (error.IsSet()) | 514 if (error.IsSet()) |
| 513 return error; | 515 return error; |
| 514 | 516 |
| 515 // Turn off syncing of this dictionary if the server already has the maximum | 517 // Turn off syncing of this dictionary if the server already has the maximum |
| 516 // number of words. | 518 // number of words. |
| 517 if (words_.size() > chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) | 519 if (words_.size() > spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS) |
| 518 StopSyncing(syncer::DICTIONARY); | 520 StopSyncing(syncer::DICTIONARY); |
| 519 | 521 |
| 520 return error; | 522 return error; |
| 521 } | 523 } |
| 522 | 524 |
| 523 void SpellcheckCustomDictionary::Notify(const Change& dictionary_change) { | 525 void SpellcheckCustomDictionary::Notify(const Change& dictionary_change) { |
| 524 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 526 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 525 if (!IsLoaded() || dictionary_change.empty()) | 527 if (!IsLoaded() || dictionary_change.empty()) |
| 526 return; | 528 return; |
| 527 FOR_EACH_OBSERVER(Observer, | 529 FOR_EACH_OBSERVER(Observer, |
| 528 observers_, | 530 observers_, |
| 529 OnCustomDictionaryChanged(dictionary_change)); | 531 OnCustomDictionaryChanged(dictionary_change)); |
| 530 } | 532 } |
| OLD | NEW |