Remove some dead code.
[WebKit-https.git] / Source / WebKit / mac / WebCoreSupport / CorrectionPanel.mm
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #import "CorrectionPanel.h"
26
27 #import "WebViewPrivate.h"
28
29 #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
30 using namespace WebCore;
31
32 static inline NSCorrectionIndicatorType correctionIndicatorType(CorrectionPanelInfo::PanelType panelType)
33 {
34     switch (panelType) {
35     case CorrectionPanelInfo::PanelTypeCorrection:
36         return NSCorrectionIndicatorTypeDefault;
37     case CorrectionPanelInfo::PanelTypeReversion:
38         return NSCorrectionIndicatorTypeReversion;
39     case CorrectionPanelInfo::PanelTypeSpellingSuggestions:
40         return NSCorrectionIndicatorTypeGuesses;
41     }
42     ASSERT_NOT_REACHED();
43     return NSCorrectionIndicatorTypeDefault;
44 }
45
46 CorrectionPanel::CorrectionPanel()
47     : m_wasDismissedExternally(false)
48     , m_reasonForDismissing(ReasonForDismissingCorrectionPanelIgnored)
49     , m_resultCondition(AdoptNS, [[NSCondition alloc] init])
50 {
51 }
52
53 CorrectionPanel::~CorrectionPanel()
54 {
55     dismissInternal(ReasonForDismissingCorrectionPanelIgnored, false);
56 }
57
58 void CorrectionPanel::show(WebView* view, CorrectionPanelInfo::PanelType type, const FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings)
59 {
60     dismissInternal(ReasonForDismissingCorrectionPanelIgnored, false);
61     
62     if (!view)
63         return;
64
65     NSString* replacedStringAsNSString = replacedString;
66     NSString* replacementStringAsNSString = replacementString;
67     m_view = view;
68     NSCorrectionIndicatorType indicatorType = correctionIndicatorType(type);
69     
70     NSMutableArray* alternativeStrings = 0;
71     if (!alternativeReplacementStrings.isEmpty()) {
72         size_t size = alternativeReplacementStrings.size();
73         alternativeStrings = [NSMutableArray arrayWithCapacity:size];
74         for (size_t i = 0; i < size; ++i)
75             [alternativeStrings addObject:(NSString*)alternativeReplacementStrings[i]];
76     }
77
78     [[NSSpellChecker sharedSpellChecker] showCorrectionIndicatorOfType:indicatorType primaryString:replacementStringAsNSString alternativeStrings:alternativeStrings forStringInRect:[view convertRect:boundingBoxOfReplacedString fromView:nil] view:m_view.get() completionHandler:^(NSString* acceptedString) {
79         handleAcceptedReplacement(acceptedString, replacedStringAsNSString, replacementStringAsNSString, indicatorType);
80     }];
81 }
82
83 void CorrectionPanel::dismiss(ReasonForDismissingCorrectionPanel reason)
84 {
85     dismissInternal(reason, true);
86 }
87
88 String CorrectionPanel::dismissSoon(ReasonForDismissingCorrectionPanel reason)
89 {
90     if (!isShowing())
91         return String();
92
93     dismissInternal(reason, true);
94     [m_resultCondition.get() lock];
95     while (!m_resultForSynchronousDismissal)
96         [m_resultCondition.get() wait];
97     [m_resultCondition.get() unlock];
98     return m_resultForSynchronousDismissal.get();
99 }
100
101 void CorrectionPanel::dismissInternal(ReasonForDismissingCorrectionPanel reason, bool dismissingExternally)
102 {
103     m_wasDismissedExternally = dismissingExternally;
104     if (!isShowing())
105         return;
106     
107     m_reasonForDismissing = reason;
108     m_resultForSynchronousDismissal.clear();
109     [[NSSpellChecker sharedSpellChecker] dismissCorrectionIndicatorForView:m_view.get()];
110     m_view.clear();
111 }
112
113 void CorrectionPanel::recordAutocorrectionResponse(WebView* view, NSCorrectionResponse response, const String& replacedString, const String& replacementString)
114 {
115     [[NSSpellChecker sharedSpellChecker] recordResponse:response toCorrection:replacementString forWord:replacedString language:nil inSpellDocumentWithTag:[view spellCheckerDocumentTag]];
116 }
117
118 void CorrectionPanel::handleAcceptedReplacement(NSString* acceptedReplacement, NSString* replaced, NSString* proposedReplacement,  NSCorrectionIndicatorType correctionIndicatorType)
119 {
120     NSSpellChecker* spellChecker = [NSSpellChecker sharedSpellChecker];
121     NSInteger documentTag = [m_view.get() spellCheckerDocumentTag];
122
123     switch (correctionIndicatorType) {
124     case NSCorrectionIndicatorTypeDefault:
125         if (acceptedReplacement)
126             [spellChecker recordResponse:NSCorrectionResponseAccepted toCorrection:acceptedReplacement forWord:replaced language:nil inSpellDocumentWithTag:documentTag];
127         else {
128             if (!m_wasDismissedExternally || m_reasonForDismissing == ReasonForDismissingCorrectionPanelCancelled)
129                 [spellChecker recordResponse:NSCorrectionResponseRejected toCorrection:proposedReplacement forWord:replaced language:nil inSpellDocumentWithTag:documentTag];
130             else
131                 [spellChecker recordResponse:NSCorrectionResponseIgnored toCorrection:proposedReplacement forWord:replaced language:nil inSpellDocumentWithTag:documentTag];
132         }
133         break;
134     case NSCorrectionIndicatorTypeReversion:
135         if (acceptedReplacement)
136             [spellChecker recordResponse:NSCorrectionResponseReverted toCorrection:replaced forWord:acceptedReplacement language:nil inSpellDocumentWithTag:documentTag];
137         break;
138     case NSCorrectionIndicatorTypeGuesses:
139         if (acceptedReplacement)
140             [spellChecker recordResponse:NSCorrectionResponseAccepted toCorrection:acceptedReplacement forWord:replaced language:nil inSpellDocumentWithTag:documentTag];
141         break;
142     }
143     
144     if (!m_wasDismissedExternally) {
145         [m_view.get() handleCorrectionPanelResult:acceptedReplacement];
146         return;
147     }
148     
149     [m_resultCondition.get() lock];
150     if (acceptedReplacement)
151         m_resultForSynchronousDismissal.adoptNS([acceptedReplacement copy]);
152     [m_resultCondition.get() signal];
153     [m_resultCondition.get() unlock];
154 }
155
156 #endif // !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
157