PageClientImpl.mm revision ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb
1/* 2 * Copyright (C) 2010 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 26#import "NativeWebKeyboardEvent.h" 27#import "PageClientImpl.h" 28 29#import "DataReference.h" 30#import "FindIndicator.h" 31#import "WKAPICast.h" 32#import "WKStringCF.h" 33#import "WKViewInternal.h" 34#import "WebContextMenuProxyMac.h" 35#import "WebEditCommandProxy.h" 36#import "WebPopupMenuProxyMac.h" 37#import <WebCore/Cursor.h> 38#import <WebCore/FloatRect.h> 39#import <WebCore/FoundationExtras.h> 40#import <WebCore/GraphicsContext.h> 41#import <WebCore/KeyboardEvent.h> 42#import <wtf/PassOwnPtr.h> 43#import <wtf/text/CString.h> 44#import <wtf/text/WTFString.h> 45 46using namespace WebCore; 47 48@interface WebEditCommandObjC : NSObject 49{ 50 RefPtr<WebKit::WebEditCommandProxy> m_command; 51} 52 53- (id)initWithWebEditCommandProxy:(PassRefPtr<WebKit::WebEditCommandProxy>)command; 54- (WebKit::WebEditCommandProxy*)command; 55 56@end 57 58@implementation WebEditCommandObjC 59 60- (id)initWithWebEditCommandProxy:(PassRefPtr<WebKit::WebEditCommandProxy>)command 61{ 62 self = [super init]; 63 if (!self) 64 return nil; 65 66 m_command = command; 67 return self; 68} 69 70- (WebKit::WebEditCommandProxy*)command 71{ 72 return m_command.get(); 73} 74 75@end 76 77@interface WebEditorUndoTargetObjC : NSObject 78 79- (void)undoEditing:(id)sender; 80- (void)redoEditing:(id)sender; 81 82@end 83 84@implementation WebEditorUndoTargetObjC 85 86- (void)undoEditing:(id)sender 87{ 88 ASSERT([sender isKindOfClass:[WebEditCommandObjC class]]); 89 [sender command]->unapply(); 90} 91 92- (void)redoEditing:(id)sender 93{ 94 ASSERT([sender isKindOfClass:[WebEditCommandObjC class]]); 95 [sender command]->reapply(); 96} 97 98@end 99 100namespace WebKit { 101 102NSString* nsStringFromWebCoreString(const String& string) 103{ 104 return string.impl() ? HardAutorelease(WKStringCopyCFString(0, toAPI(string.impl()))) : @""; 105} 106 107PassOwnPtr<PageClientImpl> PageClientImpl::create(WKView* wkView) 108{ 109 return adoptPtr(new PageClientImpl(wkView)); 110} 111 112PageClientImpl::PageClientImpl(WKView* wkView) 113 : m_wkView(wkView) 114 , m_undoTarget(AdoptNS, [[WebEditorUndoTargetObjC alloc] init]) 115{ 116} 117 118PageClientImpl::~PageClientImpl() 119{ 120} 121 122PassOwnPtr<DrawingAreaProxy> PageClientImpl::createDrawingAreaProxy() 123{ 124 return [m_wkView _createDrawingAreaProxy]; 125} 126 127void PageClientImpl::setViewNeedsDisplay(const WebCore::IntRect& rect) 128{ 129 [m_wkView setNeedsDisplayInRect:rect]; 130} 131 132void PageClientImpl::displayView() 133{ 134 [m_wkView displayIfNeeded]; 135} 136 137void PageClientImpl::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset) 138{ 139 NSRect clippedScrollRect = NSIntersectionRect(scrollRect, NSOffsetRect(scrollRect, -scrollOffset.width(), -scrollOffset.height())); 140 141 [m_wkView translateRectsNeedingDisplayInRect:clippedScrollRect by:scrollOffset]; 142 [m_wkView scrollRect:clippedScrollRect by:scrollOffset]; 143} 144 145IntSize PageClientImpl::viewSize() 146{ 147 return IntSize([m_wkView bounds].size); 148} 149 150bool PageClientImpl::isViewWindowActive() 151{ 152 return [[m_wkView window] isKeyWindow]; 153} 154 155bool PageClientImpl::isViewFocused() 156{ 157 return [m_wkView _isFocused]; 158} 159 160bool PageClientImpl::isViewVisible() 161{ 162 if (![m_wkView window]) 163 return false; 164 165 if ([m_wkView isHiddenOrHasHiddenAncestor]) 166 return false; 167 168 return true; 169} 170 171bool PageClientImpl::isViewInWindow() 172{ 173 return [m_wkView window]; 174} 175 176void PageClientImpl::processDidCrash() 177{ 178 [m_wkView _processDidCrash]; 179} 180 181void PageClientImpl::didRelaunchProcess() 182{ 183 [m_wkView _didRelaunchProcess]; 184} 185 186void PageClientImpl::takeFocus(bool direction) 187{ 188 [m_wkView _takeFocus:direction]; 189} 190 191void PageClientImpl::toolTipChanged(const String& oldToolTip, const String& newToolTip) 192{ 193 [m_wkView _toolTipChangedFrom:nsStringFromWebCoreString(oldToolTip) to:nsStringFromWebCoreString(newToolTip)]; 194} 195 196void PageClientImpl::setCursor(const WebCore::Cursor& cursor) 197{ 198 [m_wkView _setCursor:cursor.platformCursor()]; 199} 200 201void PageClientImpl::setViewportArguments(const WebCore::ViewportArguments&) 202{ 203 204} 205 206static NSString* nameForEditAction(EditAction editAction) 207{ 208 // FIXME: Use localized strings. 209 // FIXME: Move this to a platform independent location. 210 211 switch (editAction) { 212 case EditActionUnspecified: return nil; 213 case EditActionSetColor: return @"Set Color"; 214 case EditActionSetBackgroundColor: return @"Set Background Color"; 215 case EditActionTurnOffKerning: return @"Turn Off Kerning"; 216 case EditActionTightenKerning: return @"Tighten Kerning"; 217 case EditActionLoosenKerning: return @"Loosen Kerning"; 218 case EditActionUseStandardKerning: return @"Use Standard Kerning"; 219 case EditActionTurnOffLigatures: return @"Turn Off Ligatures"; 220 case EditActionUseStandardLigatures: return @"Use Standard Ligatures"; 221 case EditActionUseAllLigatures: return @"Use All Ligatures"; 222 case EditActionRaiseBaseline: return @"Raise Baseline"; 223 case EditActionLowerBaseline: return @"Lower Baseline"; 224 case EditActionSetTraditionalCharacterShape: return @"Set Traditional Character Shape"; 225 case EditActionSetFont: return @"Set Font"; 226 case EditActionChangeAttributes: return @"Change Attributes"; 227 case EditActionAlignLeft: return @"Align Left"; 228 case EditActionAlignRight: return @"Align Right"; 229 case EditActionCenter: return @"Center"; 230 case EditActionJustify: return @"Justify"; 231 case EditActionSetWritingDirection: return @"Set Writing Direction"; 232 case EditActionSubscript: return @"Subscript"; 233 case EditActionSuperscript: return @"Superscript"; 234 case EditActionUnderline: return @"Underline"; 235 case EditActionOutline: return @"Outline"; 236 case EditActionUnscript: return @"Unscript"; 237 case EditActionDrag: return @"Drag"; 238 case EditActionCut: return @"Cut"; 239 case EditActionPaste: return @"Paste"; 240 case EditActionPasteFont: return @"Paste Font"; 241 case EditActionPasteRuler: return @"Paste Ruler"; 242 case EditActionTyping: return @"Typing"; 243 case EditActionCreateLink: return @"Create Link"; 244 case EditActionUnlink: return @"Unlink"; 245 case EditActionInsertList: return @"Insert List"; 246 case EditActionFormatBlock: return @"Formatting"; 247 case EditActionIndent: return @"Indent"; 248 case EditActionOutdent: return @"Outdent"; 249 } 250 return nil; 251} 252 253void PageClientImpl::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo) 254{ 255 RefPtr<WebEditCommandProxy> command = prpCommand; 256 257 RetainPtr<WebEditCommandObjC> commandObjC(AdoptNS, [[WebEditCommandObjC alloc] initWithWebEditCommandProxy:command]); 258 NSString *actionName = nameForEditAction(command->editAction()); 259 260 NSUndoManager *undoManager = [m_wkView undoManager]; 261 [undoManager registerUndoWithTarget:m_undoTarget.get() selector:((undoOrRedo == WebPageProxy::Undo) ? @selector(undoEditing:) : @selector(redoEditing:)) object:commandObjC.get()]; 262 if (actionName) 263 [undoManager setActionName:actionName]; 264} 265 266void PageClientImpl::clearAllEditCommands() 267{ 268 [[m_wkView undoManager] removeAllActionsWithTarget:m_undoTarget.get()]; 269} 270 271void PageClientImpl::setEditCommandState(const String& commandName, bool isEnabled, int newState) 272{ 273 [m_wkView _setUserInterfaceItemState:nsStringFromWebCoreString(commandName) enabled:isEnabled state:newState]; 274} 275 276void PageClientImpl::interceptKeyEvent(const NativeWebKeyboardEvent& event, Vector<WebCore::KeypressCommand>& commandsList, uint32_t selectionStart, uint32_t selectionEnd, Vector<WebCore::CompositionUnderline>& underlines) 277{ 278 commandsList = [m_wkView _interceptKeyEvent:event.nativeEvent()]; 279 [m_wkView _getTextInputState:selectionStart selectionEnd:selectionEnd underlines:underlines]; 280} 281 282void PageClientImpl::setDragImage(const IntPoint& clientPosition, const IntSize& imageSize, PassRefPtr<ShareableBitmap> dragImage, bool isLinkDrag) 283{ 284 OwnPtr<GraphicsContext> graphicsContext = dragImage->createGraphicsContext(); 285 RetainPtr<NSImage> dragNSImage(AdoptNS, [[NSImage alloc] initWithCGImage:CGBitmapContextCreateImage(graphicsContext->platformContext()) size:imageSize]); 286 [dragNSImage.get() setFlipped:YES]; 287 [m_wkView _setDragImage:dragNSImage.get() at:clientPosition linkDrag:isLinkDrag]; 288} 289 290FloatRect PageClientImpl::convertToDeviceSpace(const FloatRect& rect) 291{ 292 return [m_wkView _convertToDeviceSpace:rect]; 293} 294 295FloatRect PageClientImpl::convertToUserSpace(const FloatRect& rect) 296{ 297 return [m_wkView _convertToUserSpace:rect]; 298} 299 300void PageClientImpl::didNotHandleKeyEvent(const NativeWebKeyboardEvent& event) 301{ 302 NSEvent* nativeEvent = event.nativeEvent(); 303 if ([nativeEvent type] == NSKeyDown) { 304 [m_wkView _setEventBeingResent:nativeEvent]; 305 [[NSApplication sharedApplication] sendEvent:nativeEvent]; 306 } 307} 308 309PassRefPtr<WebPopupMenuProxy> PageClientImpl::createPopupMenuProxy(WebPageProxy* page) 310{ 311 return WebPopupMenuProxyMac::create(m_wkView, page); 312} 313 314PassRefPtr<WebContextMenuProxy> PageClientImpl::createContextMenuProxy(WebPageProxy* page) 315{ 316 return WebContextMenuProxyMac::create(m_wkView, page); 317} 318 319void PageClientImpl::setFindIndicator(PassRefPtr<FindIndicator> findIndicator, bool fadeOut) 320{ 321 [m_wkView _setFindIndicator:findIndicator fadeOut:fadeOut]; 322} 323 324void PageClientImpl::accessibilityChildTokenReceived(const CoreIPC::DataReference& data) 325{ 326 NSData* remoteToken = [NSData dataWithBytes:data.data() length:data.size()]; 327 [m_wkView _setAccessibilityChildToken:remoteToken]; 328} 329 330#if USE(ACCELERATED_COMPOSITING) 331void PageClientImpl::pageDidEnterAcceleratedCompositing() 332{ 333 [m_wkView _pageDidEnterAcceleratedCompositing]; 334} 335 336void PageClientImpl::pageDidLeaveAcceleratedCompositing() 337{ 338 [m_wkView _pageDidLeaveAcceleratedCompositing]; 339} 340#endif // USE(ACCELERATED_COMPOSITING) 341 342void PageClientImpl::setComplexTextInputEnabled(uint64_t pluginComplexTextInputIdentifier, bool complexTextInputEnabled) 343{ 344 [m_wkView _setComplexTextInputEnabled:complexTextInputEnabled pluginComplexTextInputIdentifier:pluginComplexTextInputIdentifier]; 345} 346 347CGContextRef PageClientImpl::containingWindowGraphicsContext() 348{ 349 return static_cast<CGContextRef>([[[m_wkView window] graphicsContext] graphicsPort]); 350} 351 352void PageClientImpl::didCommitLoadForMainFrame(bool useCustomRepresentation) 353{ 354 [m_wkView _setPageHasCustomRepresentation:useCustomRepresentation]; 355} 356 357void PageClientImpl::didFinishLoadingDataForCustomRepresentation(const CoreIPC::DataReference& dataReference) 358{ 359 [m_wkView _didFinishLoadingDataForCustomRepresentation:dataReference]; 360} 361 362double PageClientImpl::customRepresentationZoomFactor() 363{ 364 return [m_wkView _customRepresentationZoomFactor]; 365} 366 367void PageClientImpl::setCustomRepresentationZoomFactor(double zoomFactor) 368{ 369 [m_wkView _setCustomRepresentationZoomFactor:zoomFactor]; 370} 371 372} // namespace WebKit 373