| /* |
| * Copyright (C) 2010 Google Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following disclaimer |
| * in the documentation and/or other materials provided with the |
| * distribution. |
| * * Neither the name of Google Inc. nor the names of its |
| * contributors may be used to endorse or promote products derived from |
| * this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "MockSpellCheck.h" |
| |
| #include "TestCommon.h" |
| #include "public/platform/WebCString.h" |
| |
| using namespace blink; |
| using namespace std; |
| |
| namespace WebTestRunner { |
| |
| namespace { |
| |
| void append(WebVector<WebString>* data, const WebString& item) |
| { |
| WebVector<WebString> result(data->size() + 1); |
| for (size_t i = 0; i < data->size(); ++i) |
| result[i] = (*data)[i]; |
| result[data->size()] = item; |
| data->swap(result); |
| } |
| |
| } |
| |
| MockSpellCheck::MockSpellCheck() |
| : m_initialized(false) { } |
| |
| MockSpellCheck::~MockSpellCheck() { } |
| |
| bool MockSpellCheck::spellCheckWord(const WebString& text, int* misspelledOffset, int* misspelledLength) |
| { |
| BLINK_ASSERT(misspelledOffset); |
| BLINK_ASSERT(misspelledLength); |
| |
| // Initialize this spellchecker. |
| initializeIfNeeded(); |
| |
| // Reset the result values as our spellchecker does. |
| *misspelledOffset = 0; |
| *misspelledLength = 0; |
| |
| // Convert to a string16 because we store string16 instances in |
| // m_misspelledWords and WebString has no find(). |
| string16 stringText = text; |
| int skippedLength = 0; |
| |
| while (!stringText.empty()) { |
| // Extract the first possible English word from the given string. |
| // The given string may include non-ASCII characters or numbers. So, we |
| // should filter out such characters before start looking up our |
| // misspelled-word table. |
| // (This is a simple version of our SpellCheckWordIterator class.) |
| // If the given string doesn't include any ASCII characters, we can treat the |
| // string as valid one. |
| string16::iterator firstChar = find_if(stringText.begin(), stringText.end(), isASCIIAlpha); |
| if (firstChar == stringText.end()) |
| return true; |
| int wordOffset = distance(stringText.begin(), firstChar); |
| int maxWordLength = static_cast<int>(stringText.length()) - wordOffset; |
| int wordLength; |
| string16 word; |
| |
| // Look up our misspelled-word table to check if the extracted word is a |
| // known misspelled word, and return the offset and the length of the |
| // extracted word if this word is a known misspelled word. |
| // (See the comment in MockSpellCheck::initializeIfNeeded() why we use a |
| // misspelled-word table.) |
| for (size_t i = 0; i < m_misspelledWords.size(); ++i) { |
| wordLength = static_cast<int>(m_misspelledWords.at(i).length()) > maxWordLength ? maxWordLength : static_cast<int>(m_misspelledWords.at(i).length()); |
| word = stringText.substr(wordOffset, wordLength); |
| if (word == m_misspelledWords.at(i) && (static_cast<int>(stringText.length()) == wordOffset + wordLength || isNotASCIIAlpha(stringText[wordOffset + wordLength]))) { |
| *misspelledOffset = wordOffset + skippedLength; |
| *misspelledLength = wordLength; |
| break; |
| } |
| } |
| |
| if (*misspelledLength > 0) |
| break; |
| |
| string16::iterator lastChar = find_if(stringText.begin() + wordOffset, stringText.end(), isNotASCIIAlpha); |
| if (lastChar == stringText.end()) |
| wordLength = static_cast<int>(stringText.length()) - wordOffset; |
| else |
| wordLength = distance(firstChar, lastChar); |
| |
| BLINK_ASSERT(0 < wordOffset + wordLength); |
| stringText = stringText.substr(wordOffset + wordLength); |
| skippedLength += wordOffset + wordLength; |
| } |
| |
| return false; |
| } |
| |
| bool MockSpellCheck::hasInCache(const WebString& word) |
| { |
| return word == WebString::fromUTF8("Spell wellcome. Is it broken?") || word == WebString::fromUTF8("Spell wellcome.\x007F"); |
| } |
| |
| void MockSpellCheck::fillSuggestionList(const WebString& word, WebVector<WebString>* suggestions) |
| { |
| if (word == WebString::fromUTF8("wellcome")) |
| append(suggestions, WebString::fromUTF8("welcome")); |
| else if (word == WebString::fromUTF8("upper case")) |
| append(suggestions, WebString::fromUTF8("uppercase")); |
| } |
| |
| bool MockSpellCheck::initializeIfNeeded() |
| { |
| // Exit if we have already initialized this object. |
| if (m_initialized) |
| return false; |
| |
| // Create a table that consists of misspelled words used in WebKit layout |
| // tests. |
| // Since WebKit layout tests don't have so many misspelled words as |
| // well-spelled words, it is easier to compare the given word with misspelled |
| // ones than to compare with well-spelled ones. |
| static const char* misspelledWords[] = { |
| // These words are known misspelled words in webkit tests. |
| // If there are other misspelled words in webkit tests, please add them in |
| // this array. |
| "foo", |
| "Foo", |
| "baz", |
| "fo", |
| "LibertyF", |
| "chello", |
| "xxxtestxxx", |
| "XXxxx", |
| "Textx", |
| "blockquoted", |
| "asd", |
| "Lorem", |
| "Nunc", |
| "Curabitur", |
| "eu", |
| "adlj", |
| "adaasj", |
| "sdklj", |
| "jlkds", |
| "jsaada", |
| "jlda", |
| "zz", |
| "contentEditable", |
| // The following words are used by unit tests. |
| "ifmmp", |
| "qwertyuiopasd", |
| "qwertyuiopasdf", |
| "upper case", |
| "wellcome" |
| }; |
| |
| m_misspelledWords.clear(); |
| for (size_t i = 0; i < arraysize(misspelledWords); ++i) |
| m_misspelledWords.push_back(string16(misspelledWords[i], misspelledWords[i] + strlen(misspelledWords[i]))); |
| |
| // Mark as initialized to prevent this object from being initialized twice |
| // or more. |
| m_initialized = true; |
| |
| // Since this MockSpellCheck class doesn't download dictionaries, this |
| // function always returns false. |
| return false; |
| } |
| |
| } |