2 * Copyright (C) 2006, 2010, 2011 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #import "WebEditorClient.h"
33 #import "WebCoreArgumentCoders.h"
36 #import "WebPageProxyMessages.h"
37 #import "WebProcess.h"
38 #import <WebCore/ArchiveResource.h>
39 #import <WebCore/DocumentFragment.h>
40 #import <WebCore/DOMDocumentFragmentInternal.h>
41 #import <WebCore/DOMDocumentInternal.h>
42 #import <WebCore/FocusController.h>
43 #import <WebCore/Frame.h>
44 #import <WebCore/KeyboardEvent.h>
45 #import <WebCore/NotImplemented.h>
46 #import <WebCore/Page.h>
47 #import <WebKit/WebResource.h>
48 #import <WebKit/WebNSURLExtras.h>
50 using namespace WebCore;
52 @interface NSAttributedString (WebNSAttributedStringDetails)
53 - (DOMDocumentFragment*)_documentFromRange:(NSRange)range document:(DOMDocument*)document documentAttributes:(NSDictionary *)dict subresources:(NSArray **)subresources;
56 @interface WebResource (WebResourceInternal)
57 - (WebCore::ArchiveResource*)_coreResource;
62 void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event)
64 if (m_page->handleEditingKeyboardEvent(event, false))
65 event->setDefaultHandled();
68 void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event)
70 if (m_page->handleEditingKeyboardEvent(event, true))
71 event->setDefaultHandled();
74 NSString *WebEditorClient::userVisibleString(NSURL *url)
76 return [url _web_userVisibleString];
79 NSURL *WebEditorClient::canonicalizeURL(NSURL *url)
81 return [url _webkit_canonicalize];
84 NSURL *WebEditorClient::canonicalizeURLString(NSString *URLString)
87 if ([URLString _webkit_looksLikeAbsoluteURL])
88 URL = [[NSURL _web_URLWithUserTypedString:URLString] _webkit_canonicalize];
92 static NSArray *createExcludedElementsForAttributedStringConversion()
94 NSArray *elements = [[NSArray alloc] initWithObjects:
95 // Omit style since we want style to be inline so the fragment can be easily inserted.
97 // Omit xml so the result is not XHTML.
99 // Omit tags that will get stripped when converted to a fragment anyway.
100 @"doctype", @"html", @"head", @"body",
101 // Omit deprecated tags.
102 @"applet", @"basefont", @"center", @"dir", @"font", @"isindex", @"menu", @"s", @"strike", @"u",
103 // Omit object so no file attachments are part of the fragment.
109 DocumentFragment* WebEditorClient::documentFragmentFromAttributedString(NSAttributedString *string, Vector<RefPtr<ArchiveResource> >& resources)
111 static NSArray *excludedElements = createExcludedElementsForAttributedStringConversion();
113 NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: excludedElements,
114 NSExcludedElementsDocumentAttribute, nil, @"WebResourceHandler", nil];
116 NSArray *subResources;
117 DOMDocumentFragment* fragment = [string _documentFromRange:NSMakeRange(0, [string length])
118 document:kit(m_page->mainFrame()->coreFrame()->document())
119 documentAttributes:dictionary
120 subresources:&subResources];
121 for (WebResource* resource in subResources)
122 resources.append([resource _coreResource]);
124 [dictionary release];
125 return core(fragment);
128 void WebEditorClient::setInsertionPasteboard(NSPasteboard *)
130 // This is used only by Mail, no need to implement it now.
135 static void changeWordCase(WebPage* page, SEL selector)
137 Frame* frame = page->corePage()->focusController()->focusedOrMainFrame();
138 if (!frame->editor()->canEdit())
141 frame->editor()->command("selectWord").execute();
143 NSString *selectedString = frame->displayStringModifiedByEncoding(frame->editor()->selectedText());
144 page->replaceSelectionWithText(frame, [selectedString performSelector:selector]);
147 void WebEditorClient::uppercaseWord()
149 changeWordCase(m_page, @selector(uppercaseString));
152 void WebEditorClient::lowercaseWord()
154 changeWordCase(m_page, @selector(lowercaseString));
157 void WebEditorClient::capitalizeWord()
159 changeWordCase(m_page, @selector(capitalizedString));
162 void WebEditorClient::showSubstitutionsPanel(bool)
167 bool WebEditorClient::substitutionsPanelIsShowing()
170 m_page->sendSync(Messages::WebPageProxy::SubstitutionsPanelIsShowing(), Messages::WebPageProxy::SubstitutionsPanelIsShowing::Reply(isShowing));
174 void WebEditorClient::toggleSmartInsertDelete()
176 // This is handled in the UI process.
177 ASSERT_NOT_REACHED();
180 bool WebEditorClient::isAutomaticQuoteSubstitutionEnabled()
182 return WebProcess::shared().textCheckerState().isAutomaticQuoteSubstitutionEnabled;
185 void WebEditorClient::toggleAutomaticQuoteSubstitution()
187 // This is handled in the UI process.
188 ASSERT_NOT_REACHED();
191 bool WebEditorClient::isAutomaticLinkDetectionEnabled()
193 return WebProcess::shared().textCheckerState().isAutomaticLinkDetectionEnabled;
196 void WebEditorClient::toggleAutomaticLinkDetection()
198 // This is handled in the UI process.
199 ASSERT_NOT_REACHED();
202 bool WebEditorClient::isAutomaticDashSubstitutionEnabled()
204 return WebProcess::shared().textCheckerState().isAutomaticDashSubstitutionEnabled;
207 void WebEditorClient::toggleAutomaticDashSubstitution()
209 // This is handled in the UI process.
210 ASSERT_NOT_REACHED();
213 bool WebEditorClient::isAutomaticTextReplacementEnabled()
215 return WebProcess::shared().textCheckerState().isAutomaticTextReplacementEnabled;
218 void WebEditorClient::toggleAutomaticTextReplacement()
220 // This is handled in the UI process.
221 ASSERT_NOT_REACHED();
224 bool WebEditorClient::isAutomaticSpellingCorrectionEnabled()
226 return WebProcess::shared().textCheckerState().isAutomaticSpellingCorrectionEnabled;
229 void WebEditorClient::toggleAutomaticSpellingCorrection()
234 void WebEditorClient::checkTextOfParagraph(const UChar* text, int length, WebCore::TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results)
236 // FIXME: It would be nice if we wouldn't have to copy the text here.
237 m_page->sendSync(Messages::WebPageProxy::CheckTextOfParagraph(String(text, length), checkingTypes), Messages::WebPageProxy::CheckTextOfParagraph::Reply(results));
240 #if !defined(BUILDING_ON_SNOW_LEOPARD)
241 void WebEditorClient::showCorrectionPanel(WebCore::CorrectionPanelInfo::PanelType type, const WebCore::FloatRect& boundingBoxOfReplacedString, const String& replacedString, const String& replacementString, const Vector<String>& alternativeReplacementStrings)
243 m_page->send(Messages::WebPageProxy::ShowCorrectionPanel(type, boundingBoxOfReplacedString, replacedString, replacementString, alternativeReplacementStrings));
246 void WebEditorClient::dismissCorrectionPanel(WebCore::ReasonForDismissingCorrectionPanel reason)
248 m_page->send(Messages::WebPageProxy::DismissCorrectionPanel(reason));
251 String WebEditorClient::dismissCorrectionPanelSoon(WebCore::ReasonForDismissingCorrectionPanel reason)
254 m_page->sendSync(Messages::WebPageProxy::DismissCorrectionPanelSoon(reason), Messages::WebPageProxy::DismissCorrectionPanelSoon::Reply(result));
258 void WebEditorClient::recordAutocorrectionResponse(EditorClient::AutocorrectionResponseType responseType, const String& replacedString, const String& replacementString)
260 m_page->send(Messages::WebPageProxy::RecordAutocorrectionResponse(responseType, replacedString, replacementString));
264 } // namespace WebKit