2010-10-23 19:00:47 +02:00
|
|
|
// Copyright (c) 2008 The Chromium Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#import <Cocoa/Cocoa.h>
|
|
|
|
|
2012-01-10 00:46:23 +01:00
|
|
|
#import "libcef/browser_webview_mac.h"
|
|
|
|
#import "libcef/browser_impl.h"
|
|
|
|
#import "libcef/cef_context.h"
|
|
|
|
#import "libcef/web_drag_source_mac.h"
|
|
|
|
#import "libcef/web_drop_target_mac.h"
|
|
|
|
#import "libcef/webwidget_host.h"
|
2010-10-23 19:00:47 +02:00
|
|
|
|
2011-11-14 18:47:21 +01:00
|
|
|
#import "base/memory/scoped_ptr.h"
|
|
|
|
#import "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
|
|
|
|
#import "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
|
2011-08-02 18:50:06 +02:00
|
|
|
#import "third_party/mozilla/NSPasteboard+Utils.h"
|
2011-11-14 18:47:21 +01:00
|
|
|
#import "third_party/skia/include/core/SkRegion.h"
|
|
|
|
#import "ui/gfx/rect.h"
|
2010-10-23 19:00:47 +02:00
|
|
|
|
|
|
|
@implementation BrowserWebView
|
|
|
|
|
|
|
|
@synthesize browser = browser_;
|
2012-04-02 21:05:42 +02:00
|
|
|
@synthesize in_setfocus = is_in_setfocus_;
|
2010-10-23 19:00:47 +02:00
|
|
|
|
|
|
|
- (id)initWithFrame:(NSRect)frame {
|
|
|
|
self = [super initWithFrame:frame];
|
|
|
|
if (self) {
|
|
|
|
trackingArea_ =
|
2011-08-02 18:50:06 +02:00
|
|
|
[[NSTrackingArea alloc] initWithRect:frame
|
|
|
|
options:NSTrackingMouseMoved |
|
|
|
|
NSTrackingActiveInActiveApp |
|
|
|
|
NSTrackingInVisibleRect
|
|
|
|
owner:self
|
|
|
|
userInfo:nil];
|
2010-10-23 19:00:47 +02:00
|
|
|
[self addTrackingArea:trackingArea_];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc {
|
2011-08-17 03:28:45 +02:00
|
|
|
if (browser_)
|
2011-08-14 23:54:18 +02:00
|
|
|
browser_->UIT_DestroyBrowser();
|
2010-11-15 16:39:56 +01:00
|
|
|
|
2010-10-23 19:00:47 +02:00
|
|
|
[self removeTrackingArea:trackingArea_];
|
|
|
|
[trackingArea_ release];
|
2010-11-15 16:39:56 +01:00
|
|
|
|
2010-10-23 19:00:47 +02:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)drawRect:(NSRect)rect {
|
2011-10-03 17:48:32 +02:00
|
|
|
#ifndef NDEBUG
|
2011-11-08 17:19:03 +01:00
|
|
|
CGContextRef context = reinterpret_cast<CGContextRef>(
|
|
|
|
[[NSGraphicsContext currentContext] graphicsPort]);
|
|
|
|
CGContextSetRGBFillColor(context, 1, 0, 1, 1);
|
2010-10-23 19:00:47 +02:00
|
|
|
CGContextFillRect(context, NSRectToCGRect(rect));
|
2011-10-03 17:48:32 +02:00
|
|
|
#endif
|
2010-10-23 19:00:47 +02:00
|
|
|
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView()) {
|
2011-11-14 18:47:21 +01:00
|
|
|
NSInteger count;
|
|
|
|
const NSRect *rects;
|
|
|
|
[self getRectsBeingDrawn:&rects count:&count];
|
|
|
|
|
|
|
|
SkRegion update_rgn;
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
const NSRect r = rects[i];
|
|
|
|
const float min_x = NSMinX(r);
|
|
|
|
const float max_x = NSMaxX(r);
|
|
|
|
const float min_y = NSHeight([self bounds]) - NSMaxY(r);
|
|
|
|
const float max_y = NSHeight([self bounds]) - NSMinY(r);
|
|
|
|
update_rgn.op(min_x, min_y, max_x, max_y, SkRegion::kUnion_Op);
|
|
|
|
}
|
|
|
|
|
|
|
|
browser_->UIT_GetWebViewHost()->Paint(update_rgn);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseDown:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)rightMouseDown:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)otherMouseDown:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseUp:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)rightMouseUp:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)otherMouseUp:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseMoved:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseDragged:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)scrollWheel:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->WheelEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)rightMouseDragged:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)otherMouseDragged:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseEntered:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)mouseExited:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->MouseEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)keyDown:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->KeyEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)keyUp:(NSEvent *)theEvent {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->KeyEvent(theEvent);
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
2012-04-20 20:47:47 +02:00
|
|
|
- (void)flagsChanged:(NSEvent *)theEvent {
|
|
|
|
if (browser_ && browser_->UIT_GetWebView())
|
|
|
|
browser_->UIT_GetWebViewHost()->KeyEvent(theEvent);
|
|
|
|
}
|
|
|
|
|
2010-10-23 19:00:47 +02:00
|
|
|
- (BOOL)isOpaque {
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)canBecomeKeyView {
|
2011-01-29 02:42:59 +01:00
|
|
|
return browser_ && browser_->UIT_GetWebView();
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)acceptsFirstResponder {
|
2011-01-29 02:42:59 +01:00
|
|
|
return browser_ && browser_->UIT_GetWebView();
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)becomeFirstResponder {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView()) {
|
2012-04-02 21:05:42 +02:00
|
|
|
if (!is_in_setfocus_) {
|
|
|
|
CefRefPtr<CefClient> client = browser_->GetClient();
|
|
|
|
if (client.get()) {
|
|
|
|
CefRefPtr<CefFocusHandler> handler = client->GetFocusHandler();
|
|
|
|
if (handler.get() &&
|
|
|
|
handler->OnSetFocus(browser_, FOCUS_SOURCE_SYSTEM)) {
|
|
|
|
return NO;
|
|
|
|
}
|
2011-10-07 12:30:10 +02:00
|
|
|
}
|
2011-08-27 20:41:21 +02:00
|
|
|
}
|
|
|
|
|
2011-01-29 02:42:59 +01:00
|
|
|
browser_->UIT_GetWebViewHost()->SetFocus(YES);
|
2011-08-14 23:54:18 +02:00
|
|
|
return [super becomeFirstResponder];
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)resignFirstResponder {
|
2011-01-29 02:42:59 +01:00
|
|
|
if (browser_ && browser_->UIT_GetWebView()) {
|
|
|
|
browser_->UIT_GetWebViewHost()->SetFocus(NO);
|
2011-08-14 23:54:18 +02:00
|
|
|
return [super resignFirstResponder];
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setFrame:(NSRect)frameRect {
|
|
|
|
[super setFrame:frameRect];
|
2011-08-02 18:50:06 +02:00
|
|
|
if (browser_ && browser_->UIT_GetWebView()) {
|
2011-11-08 17:19:03 +01:00
|
|
|
const NSRect bounds = [self bounds];
|
|
|
|
browser_->UIT_GetWebViewHost()->Resize(gfx::Rect(NSRectToCGRect(bounds)));
|
2011-08-02 18:50:06 +02:00
|
|
|
}
|
2010-10-23 19:00:47 +02:00
|
|
|
}
|
|
|
|
|
2011-08-27 20:41:21 +02:00
|
|
|
- (void)undo:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Undo();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)redo:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Redo();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)cut:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Cut();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)copy:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Copy();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)paste:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Paste();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)delete:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->Delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)selectAll:(id)sender {
|
|
|
|
if (browser_)
|
|
|
|
browser_->GetFocusedFrame()->SelectAll();
|
|
|
|
}
|
|
|
|
|
2011-08-02 19:30:11 +02:00
|
|
|
- (void)registerDragDrop {
|
|
|
|
dropTarget_.reset([[WebDropTarget alloc] initWithWebView:self]);
|
|
|
|
|
|
|
|
// Register the view to handle the appropriate drag types.
|
|
|
|
NSArray* types = [NSArray arrayWithObjects:NSStringPboardType,
|
|
|
|
NSHTMLPboardType, NSURLPboardType, nil];
|
|
|
|
[self registerForDraggedTypes:types];
|
|
|
|
}
|
|
|
|
|
2011-08-02 18:50:06 +02:00
|
|
|
- (void)startDragWithDropData:(const WebDropData&)dropData
|
|
|
|
dragOperationMask:(NSDragOperation)operationMask
|
|
|
|
image:(NSImage*)image
|
|
|
|
offset:(NSPoint)offset {
|
|
|
|
dragSource_.reset([[WebDragSource alloc]
|
|
|
|
initWithWebView:self
|
|
|
|
dropData:&dropData
|
|
|
|
image:image
|
|
|
|
offset:offset
|
|
|
|
pasteboard:[NSPasteboard pasteboardWithName:NSDragPboard]
|
|
|
|
dragOperationMask:operationMask]);
|
|
|
|
[dragSource_ startDrag];
|
|
|
|
}
|
|
|
|
|
|
|
|
// NSPasteboardOwner methods
|
|
|
|
|
|
|
|
- (void)pasteboard:(NSPasteboard*)sender provideDataForType:(NSString*)type {
|
|
|
|
[dragSource_ lazyWriteToPasteboard:sender
|
|
|
|
forType:type];
|
|
|
|
}
|
|
|
|
|
|
|
|
// NSDraggingSource methods
|
|
|
|
|
|
|
|
// Returns what kind of drag operations are available. This is a required
|
|
|
|
// method for NSDraggingSource.
|
|
|
|
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
|
|
|
|
if (dragSource_.get())
|
|
|
|
return [dragSource_ draggingSourceOperationMaskForLocal:isLocal];
|
|
|
|
// No web drag source - this is the case for dragging a file from the
|
|
|
|
// downloads manager. Default to copy operation. Note: It is desirable to
|
|
|
|
// allow the user to either move or copy, but this requires additional
|
|
|
|
// plumbing to update the download item's path once its moved.
|
|
|
|
return NSDragOperationCopy;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Called when a drag initiated in our view ends.
|
|
|
|
- (void)draggedImage:(NSImage*)anImage
|
|
|
|
endedAt:(NSPoint)screenPoint
|
|
|
|
operation:(NSDragOperation)operation {
|
|
|
|
[dragSource_ endDragAt:screenPoint operation:operation];
|
|
|
|
|
|
|
|
// Might as well throw out this object now.
|
|
|
|
dragSource_.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Called when a drag initiated in our view moves.
|
|
|
|
- (void)draggedImage:(NSImage*)draggedImage movedTo:(NSPoint)screenPoint {
|
|
|
|
[dragSource_ moveDragTo:screenPoint];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Called when we're informed where a file should be dropped.
|
|
|
|
- (NSArray*)namesOfPromisedFilesDroppedAtDestination:(NSURL*)dropDest {
|
|
|
|
if (![dropDest isFileURL])
|
|
|
|
return nil;
|
|
|
|
|
|
|
|
NSString* file_name = [dragSource_ dragPromisedFileTo:[dropDest path]];
|
|
|
|
if (!file_name)
|
|
|
|
return nil;
|
|
|
|
|
|
|
|
return [NSArray arrayWithObject:file_name];
|
|
|
|
}
|
|
|
|
|
|
|
|
// NSDraggingDestination methods
|
|
|
|
|
|
|
|
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
|
|
|
|
return [dropTarget_ draggingEntered:sender view:self];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)draggingExited:(id<NSDraggingInfo>)sender {
|
|
|
|
[dropTarget_ draggingExited:sender];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
|
|
|
|
return [dropTarget_ draggingUpdated:sender view:self];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
|
|
|
|
return [dropTarget_ performDragOperation:sender view:self];
|
|
|
|
}
|
|
|
|
|
2010-10-23 19:00:47 +02:00
|
|
|
@end
|