diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebKit2/UIProcess/mac/TextCheckerMac.mm | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebKit2/UIProcess/mac/TextCheckerMac.mm')
-rw-r--r-- | Source/WebKit2/UIProcess/mac/TextCheckerMac.mm | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/mac/TextCheckerMac.mm b/Source/WebKit2/UIProcess/mac/TextCheckerMac.mm new file mode 100644 index 0000000..c89011e --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/TextCheckerMac.mm @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2010, 2011 Apple 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 "TextChecker.h" + +#include "TextCheckerState.h" +#include <wtf/RetainPtr.h> + +#ifndef BUILDING_ON_SNOW_LEOPARD +#import <AppKit/NSTextChecker.h> +#endif + +static const NSString * const WebAutomaticSpellingCorrectionEnabled = @"WebAutomaticSpellingCorrectionEnabled"; +static const NSString * const WebContinuousSpellCheckingEnabled = @"WebContinuousSpellCheckingEnabled"; +static const NSString * const WebGrammarCheckingEnabled = @"WebGrammarCheckingEnabled"; +static const NSString * const WebSmartInsertDeleteEnabled = @"WebSmartInsertDeleteEnabled"; +static const NSString * const WebAutomaticQuoteSubstitutionEnabled = @"WebAutomaticQuoteSubstitutionEnabled"; +static const NSString * const WebAutomaticDashSubstitutionEnabled = @"WebAutomaticDashSubstitutionEnabled"; +static const NSString * const WebAutomaticLinkDetectionEnabled = @"WebAutomaticLinkDetectionEnabled"; +static const NSString * const WebAutomaticTextReplacementEnabled = @"WebAutomaticTextReplacementEnabled"; + +using namespace WebCore; + +namespace WebKit { + +TextCheckerState textCheckerState; + +static void initializeState() +{ + static bool didInitializeState; + if (didInitializeState) + return; + + textCheckerState.isContinuousSpellCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebContinuousSpellCheckingEnabled] && TextChecker::isContinuousSpellCheckingAllowed(); + textCheckerState.isGrammarCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebGrammarCheckingEnabled]; + textCheckerState.isAutomaticSpellingCorrectionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticSpellingCorrectionEnabled]; + textCheckerState.isAutomaticQuoteSubstitutionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticQuoteSubstitutionEnabled]; + textCheckerState.isAutomaticDashSubstitutionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticDashSubstitutionEnabled]; + textCheckerState.isAutomaticLinkDetectionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticLinkDetectionEnabled]; + textCheckerState.isAutomaticTextReplacementEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticTextReplacementEnabled]; + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + if (![[NSUserDefaults standardUserDefaults] objectForKey:WebAutomaticSpellingCorrectionEnabled]) + textCheckerState.isAutomaticSpellingCorrectionEnabled = [NSSpellChecker isAutomaticSpellingCorrectionEnabled]; +#endif + + didInitializeState = true; +} + +const TextCheckerState& TextChecker::state() +{ + initializeState(); + return textCheckerState; +} + +bool TextChecker::isContinuousSpellCheckingAllowed() +{ + static bool allowContinuousSpellChecking = true; + static bool readAllowContinuousSpellCheckingDefault = false; + + if (!readAllowContinuousSpellCheckingDefault) { + if ([[NSUserDefaults standardUserDefaults] objectForKey:@"NSAllowContinuousSpellChecking"]) + allowContinuousSpellChecking = [[NSUserDefaults standardUserDefaults] boolForKey:@"NSAllowContinuousSpellChecking"]; + + readAllowContinuousSpellCheckingDefault = true; + } + + return allowContinuousSpellChecking; +} + +void TextChecker::setContinuousSpellCheckingEnabled(bool isContinuousSpellCheckingEnabled) +{ + if (state().isContinuousSpellCheckingEnabled == isContinuousSpellCheckingEnabled) + return; + + textCheckerState.isContinuousSpellCheckingEnabled = isContinuousSpellCheckingEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isContinuousSpellCheckingEnabled forKey:WebContinuousSpellCheckingEnabled]; + + // FIXME: preflight the spell checker. +} + +void TextChecker::setGrammarCheckingEnabled(bool isGrammarCheckingEnabled) +{ + if (state().isGrammarCheckingEnabled == isGrammarCheckingEnabled) + return; + + textCheckerState.isGrammarCheckingEnabled = isGrammarCheckingEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isGrammarCheckingEnabled forKey:WebGrammarCheckingEnabled]; + [[NSSpellChecker sharedSpellChecker] updatePanels]; + + // We call preflightSpellChecker() when turning continuous spell checking on, but we don't need to do that here + // because grammar checking only occurs on code paths that already preflight spell checking appropriately. +} + +void TextChecker::setAutomaticSpellingCorrectionEnabled(bool isAutomaticSpellingCorrectionEnabled) +{ + if (state().isAutomaticSpellingCorrectionEnabled == isAutomaticSpellingCorrectionEnabled) + return; + + textCheckerState.isAutomaticSpellingCorrectionEnabled = isAutomaticSpellingCorrectionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticSpellingCorrectionEnabled forKey:WebAutomaticSpellingCorrectionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticQuoteSubstitutionEnabled(bool isAutomaticQuoteSubstitutionEnabled) +{ + if (state().isAutomaticQuoteSubstitutionEnabled == isAutomaticQuoteSubstitutionEnabled) + return; + + textCheckerState.isAutomaticQuoteSubstitutionEnabled = isAutomaticQuoteSubstitutionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticQuoteSubstitutionEnabled forKey:WebAutomaticQuoteSubstitutionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticDashSubstitutionEnabled(bool isAutomaticDashSubstitutionEnabled) +{ + if (state().isAutomaticDashSubstitutionEnabled == isAutomaticDashSubstitutionEnabled) + return; + + textCheckerState.isAutomaticDashSubstitutionEnabled = isAutomaticDashSubstitutionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticDashSubstitutionEnabled forKey:WebAutomaticDashSubstitutionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticLinkDetectionEnabled(bool isAutomaticLinkDetectionEnabled) +{ + if (state().isAutomaticLinkDetectionEnabled == isAutomaticLinkDetectionEnabled) + return; + + textCheckerState.isAutomaticLinkDetectionEnabled = isAutomaticLinkDetectionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticLinkDetectionEnabled forKey:WebAutomaticLinkDetectionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticTextReplacementEnabled(bool isAutomaticTextReplacementEnabled) +{ + if (state().isAutomaticTextReplacementEnabled == isAutomaticTextReplacementEnabled) + return; + + textCheckerState.isAutomaticTextReplacementEnabled = isAutomaticTextReplacementEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticTextReplacementEnabled forKey:WebAutomaticTextReplacementEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +static bool smartInsertDeleteEnabled; + +bool TextChecker::isSmartInsertDeleteEnabled() +{ + static bool readSmartInsertDeleteEnabledDefault; + + if (!readSmartInsertDeleteEnabledDefault) { + smartInsertDeleteEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebSmartInsertDeleteEnabled]; + + readSmartInsertDeleteEnabledDefault = true; + } + + return smartInsertDeleteEnabled; +} + +void TextChecker::setSmartInsertDeleteEnabled(bool flag) +{ + if (flag == isSmartInsertDeleteEnabled()) + return; + + smartInsertDeleteEnabled = flag; + + [[NSUserDefaults standardUserDefaults] setBool:flag forKey:WebSmartInsertDeleteEnabled]; +} + +int64_t TextChecker::uniqueSpellDocumentTag() +{ + return [NSSpellChecker uniqueSpellDocumentTag]; +} + +void TextChecker::closeSpellDocumentWithTag(int64_t tag) +{ + [[NSSpellChecker sharedSpellChecker] closeSpellDocumentWithTag:tag]; +} + +Vector<TextCheckingResult> TextChecker::checkTextOfParagraph(int64_t spellDocumentTag, const UChar* text, int length, uint64_t checkingTypes) +{ + Vector<TextCheckingResult> results; + + RetainPtr<NSString> textString(AdoptNS, [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(text) length:length freeWhenDone:NO]); + NSArray *incomingResults = [[NSSpellChecker sharedSpellChecker] checkString:textString .get() + range:NSMakeRange(0, length) + types:checkingTypes | NSTextCheckingTypeOrthography + options:nil + inSpellDocumentWithTag:spellDocumentTag + orthography:NULL + wordCount:NULL]; + for (NSTextCheckingResult *incomingResult in incomingResults) { + NSRange resultRange = [incomingResult range]; + NSTextCheckingType resultType = [incomingResult resultType]; + ASSERT(resultRange.location != NSNotFound); + ASSERT(resultRange.length > 0); + if (resultType == NSTextCheckingTypeSpelling && (checkingTypes & NSTextCheckingTypeSpelling)) { + TextCheckingResult result; + result.type = TextCheckingTypeSpelling; + result.location = resultRange.location; + result.length = resultRange.length; + results.append(result); + } else if (resultType == NSTextCheckingTypeGrammar && (checkingTypes & NSTextCheckingTypeGrammar)) { + TextCheckingResult result; + NSArray *details = [incomingResult grammarDetails]; + result.type = TextCheckingTypeGrammar; + result.location = resultRange.location; + result.length = resultRange.length; + for (NSDictionary *incomingDetail in details) { + ASSERT(incomingDetail); + GrammarDetail detail; + NSValue *detailRangeAsNSValue = [incomingDetail objectForKey:NSGrammarRange]; + ASSERT(detailRangeAsNSValue); + NSRange detailNSRange = [detailRangeAsNSValue rangeValue]; + ASSERT(detailNSRange.location != NSNotFound); + ASSERT(detailNSRange.length > 0); + detail.location = detailNSRange.location; + detail.length = detailNSRange.length; + detail.userDescription = [incomingDetail objectForKey:NSGrammarUserDescription]; + NSArray *guesses = [incomingDetail objectForKey:NSGrammarCorrections]; + for (NSString *guess in guesses) + detail.guesses.append(String(guess)); + result.details.append(detail); + } + results.append(result); + } else if (resultType == NSTextCheckingTypeLink && (checkingTypes & NSTextCheckingTypeLink)) { + TextCheckingResult result; + result.type = TextCheckingTypeLink; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [[incomingResult URL] absoluteString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeQuote && (checkingTypes & NSTextCheckingTypeQuote)) { + TextCheckingResult result; + result.type = TextCheckingTypeQuote; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeDash && (checkingTypes & NSTextCheckingTypeDash)) { + TextCheckingResult result; + result.type = TextCheckingTypeDash; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeReplacement && (checkingTypes & NSTextCheckingTypeReplacement)) { + TextCheckingResult result; + result.type = TextCheckingTypeReplacement; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeCorrection && (checkingTypes & NSTextCheckingTypeCorrection)) { + TextCheckingResult result; + result.type = TextCheckingTypeCorrection; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } + } + + return results; +} + +void TextChecker::updateSpellingUIWithMisspelledWord(const String& misspelledWord) +{ + [[NSSpellChecker sharedSpellChecker] updateSpellingPanelWithMisspelledWord:misspelledWord]; +} + +void TextChecker::getGuessesForWord(int64_t spellDocumentTag, const String& word, const String& context, Vector<String>& guesses) +{ +#if !defined(BUILDING_ON_SNOW_LEOPARD) + NSString* language = nil; + NSOrthography* orthography = nil; + NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker]; + if (context.length()) { + [checker checkString:context range:NSMakeRange(0, context.length()) types:NSTextCheckingTypeOrthography options:0 inSpellDocumentWithTag:spellDocumentTag orthography:&orthography wordCount:0]; + language = [checker languageForWordRange:NSMakeRange(0, context.length()) inString:context orthography:orthography]; + } + NSArray* stringsArray = [checker guessesForWordRange:NSMakeRange(0, word.length()) inString:word language:language inSpellDocumentWithTag:spellDocumentTag]; +#else + NSArray* stringsArray = [[NSSpellChecker sharedSpellChecker] guessesForWord:word]; +#endif + + for (NSString *guess in stringsArray) + guesses.append(guess); +} + +void TextChecker::learnWord(const String& word) +{ + [[NSSpellChecker sharedSpellChecker] learnWord:word]; +} + +void TextChecker::ignoreWord(int64_t spellDocumentTag, const String& word) +{ + [[NSSpellChecker sharedSpellChecker] ignoreWord:word inSpellDocumentWithTag:spellDocumentTag]; +} + +} // namespace WebKit |