Plugins/WebKit Message View/ESWebView.m
author Zachary West <zacw@adium.im>
Sun Nov 01 11:15:19 2009 -0500 (2009-11-01)
changeset 2723 6fa58273701e
parent 2185 9d8345ab2d12
permissions -rw-r--r--
Prevent infinitely forwarding navigation events. Fixes #13251.
David@0
     1
/* 
David@0
     2
 * Adium is the legal property of its developers, whose names are listed in the copyright file included
David@0
     3
 * with this source distribution.
David@0
     4
 * 
David@0
     5
 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
David@0
     6
 * General Public License as published by the Free Software Foundation; either version 2 of the License,
David@0
     7
 * or (at your option) any later version.
David@0
     8
 * 
David@0
     9
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
David@0
    10
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
David@0
    11
 * Public License for more details.
David@0
    12
 * 
David@0
    13
 * You should have received a copy of the GNU General Public License along with this program; if not,
David@0
    14
 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
David@0
    15
 */
David@0
    16
David@0
    17
#import "ESWebView.h"
David@0
    18
David@84
    19
@interface WebView ()
David@0
    20
- (void)setDrawsBackground:(BOOL)flag;
David@0
    21
- (void)setBackgroundColor:(NSColor *)color;
David@0
    22
@end
David@0
    23
David@390
    24
@interface NSWindow ()
David@390
    25
- (void) _setContentHasShadow:(BOOL) shadow; 
David@390
    26
@end
David@390
    27
David@84
    28
@interface ESWebView ()
David@0
    29
- (void)forwardSelector:(SEL)selector withObject:(id)object;
David@0
    30
@end
David@0
    31
David@0
    32
@implementation ESWebView
David@0
    33
David@0
    34
- (id)initWithFrame:(NSRect)frameRect frameName:(NSString *)frameName groupName:(NSString *)groupName
David@0
    35
{
David@0
    36
	if ((self = [super initWithFrame:frameRect frameName:frameName groupName:groupName])) {
David@0
    37
		draggingDelegate = nil;
David@0
    38
		allowsDragAndDrop = YES;
David@0
    39
		shouldForwardEvents = YES;
David@0
    40
		transparentBackground = NO;
David@0
    41
	}
David@0
    42
	
David@0
    43
	return self;
David@0
    44
}
David@0
    45
David@0
    46
#pragma mark Transparency
David@0
    47
- (void)setTransparent:(BOOL)flag
David@0
    48
{
David@390
    49
	//Private method: this is new in Tiger
David@390
    50
	if( [[self window] respondsToSelector:@selector( _setContentHasShadow: )] )
David@390
    51
		[[self window] _setContentHasShadow:NO];
David@390
    52
	
David@390
    53
	//As of Safari 3.0, we must call setBackgroundColor: to make the webview transparent
David@390
    54
	[self setBackgroundColor:(flag ? [NSColor clearColor] : [NSColor whiteColor])];
David@0
    55
	
David@0
    56
	transparentBackground = flag;
David@0
    57
}
David@0
    58
David@0
    59
- (void)viewDidMoveToWindow
David@0
    60
{
David@0
    61
	NSWindow *win = [self window];
David@390
    62
	if(win) {
David@0
    63
		[win setOpaque:!transparentBackground];
David@390
    64
		[win _setContentHasShadow:NO];
David@390
    65
	}
catfish@2185
    66
	[super viewDidMoveToWindow];
David@0
    67
}
David@0
    68
David@0
    69
//Font Family ----------------------------------------------------------------------------------------------------------
David@0
    70
#pragma mark Font Family
David@0
    71
- (void)setFontFamily:(NSString *)familyName
David@0
    72
{
David@0
    73
	[[self preferences] setStandardFontFamily:familyName];
David@0
    74
	[[self preferences] setFixedFontFamily:familyName];
David@0
    75
	[[self preferences] setSerifFontFamily:familyName];
David@0
    76
	[[self preferences] setSansSerifFontFamily:familyName];
David@0
    77
}
David@0
    78
David@0
    79
- (NSString *)fontFamily
David@0
    80
{
David@0
    81
	return [[self preferences] standardFontFamily];
David@0
    82
}
David@0
    83
David@0
    84
David@0
    85
#pragma mark Key/Paste Forwarding
David@0
    86
- (void)setShouldForwardEvents:(BOOL)flag
David@0
    87
{
David@0
    88
	shouldForwardEvents = flag;
David@0
    89
}
David@0
    90
David@0
    91
//When the user attempts to type into the table view, we push the keystroke to the next responder,
David@0
    92
//and make it key.  This isn't required, but convienent behavior since one will never want to type
David@0
    93
//into this view.
David@0
    94
- (void)keyDown:(NSEvent *)theEvent
David@0
    95
{
zacw@2723
    96
	BOOL forwarded = YES;
zacw@2723
    97
	
David@0
    98
	if (shouldForwardEvents) {
zacw@2723
    99
		unichar		 inChar = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
zacw@2723
   100
		
zacw@2723
   101
		// Don't forward navigation key events. If we're receiving them, it's because
zacw@2723
   102
		// the frame itself didn't support them.
zacw@2723
   103
		if (inChar != NSUpArrowFunctionKey && inChar != NSDownArrowFunctionKey &&
zacw@2723
   104
			inChar != NSPageUpFunctionKey && inChar != NSPageDownFunctionKey)
zacw@2723
   105
		{
zacw@2723
   106
			[self forwardSelector:@selector(keyDown:) withObject:theEvent];
zacw@2723
   107
			forwarded = YES;
zacw@2723
   108
		}
zacw@2723
   109
	}
zacw@2723
   110
	
zacw@2723
   111
	if (!forwarded) {
David@0
   112
		[super keyDown:theEvent];
David@0
   113
	}
David@0
   114
}
David@0
   115
David@0
   116
- (void)paste:(id)sender
David@0
   117
{
David@0
   118
	[self forwardSelector:@selector(paste:) withObject:sender];
David@0
   119
}
David@0
   120
- (void)pasteAsPlainText:(id)sender
David@0
   121
{
David@0
   122
	[self forwardSelector:@selector(pasteAsPlainText:) withObject:sender];
David@0
   123
}
David@0
   124
- (void)pasteAsRichText:(id)sender
David@0
   125
{
David@0
   126
	[self forwardSelector:@selector(pasteAsRichText:) withObject:sender];
David@0
   127
}
David@0
   128
David@0
   129
- (void)forwardSelector:(SEL)selector withObject:(id)object
David@0
   130
{
David@0
   131
	id	responder = [self nextResponder];
David@0
   132
	
David@0
   133
	//When walking the responder chain, we want to skip ScrollViews and ClipViews.
David@0
   134
	while (responder && ([responder isKindOfClass:[NSClipView class]] || [responder isKindOfClass:[NSScrollView class]])) {
David@0
   135
		responder = [responder nextResponder];
David@0
   136
	}
David@0
   137
	
David@0
   138
	if (responder) {
David@0
   139
		[[self window] makeFirstResponder:responder]; //Make it first responder
David@0
   140
		[responder tryToPerform:selector with:object]; //Pass it this key event
David@0
   141
	}
David@0
   142
}
David@0
   143
David@0
   144
David@0
   145
//Accepting Drags ------------------------------------------------------------------------------------------------------
David@0
   146
#pragma mark Accepting Drags
David@0
   147
- (void)setAllowsDragAndDrop:(BOOL)flag
David@0
   148
{
David@0
   149
	allowsDragAndDrop = flag;
David@0
   150
}
David@0
   151
David@0
   152
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
David@0
   153
{
David@0
   154
	NSDragOperation dragOperation;
David@0
   155
	
David@0
   156
	if (allowsDragAndDrop) {
David@0
   157
		if (draggingDelegate && [draggingDelegate respondsToSelector:@selector(webView:draggingEntered:)]) {
David@0
   158
			dragOperation = [draggingDelegate webView:self draggingEntered:sender];
David@0
   159
		} else {
David@0
   160
			dragOperation = [super draggingEntered:sender];
David@0
   161
		}
David@0
   162
	} else {
David@0
   163
		dragOperation = NSDragOperationNone;
David@0
   164
	}
David@0
   165
	
David@0
   166
	return dragOperation;
David@0
   167
}
David@0
   168
David@0
   169
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
David@0
   170
{
David@0
   171
	NSDragOperation dragOperation;
David@0
   172
	
David@0
   173
	if (allowsDragAndDrop) {
David@0
   174
		if (draggingDelegate && [draggingDelegate respondsToSelector:@selector(webView:draggingUpdated:)]) {
David@0
   175
			dragOperation = [draggingDelegate webView:self draggingUpdated:sender];
David@0
   176
		} else {
David@0
   177
			dragOperation = [super draggingUpdated:sender];
David@0
   178
		}
David@0
   179
	} else {
David@0
   180
		dragOperation = NSDragOperationNone;
David@0
   181
	}
David@0
   182
	
David@0
   183
	return dragOperation;
David@0
   184
}
David@0
   185
David@0
   186
- (void)draggingExited:(id <NSDraggingInfo>)sender
David@0
   187
{
David@0
   188
	if (draggingDelegate) {
David@0
   189
		if ([draggingDelegate respondsToSelector:@selector(webView:draggingExited:)]) {
David@0
   190
			[draggingDelegate webView:self draggingExited:sender];
David@0
   191
		}
David@0
   192
	} else {
David@0
   193
		[super draggingExited:sender];
David@0
   194
	}
David@0
   195
}
David@0
   196
David@0
   197
//Dragging
David@0
   198
- (void)setDraggingDelegate:(id)inDelegate
David@0
   199
{
David@0
   200
	draggingDelegate = inDelegate;
David@0
   201
}
David@0
   202
David@0
   203
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
David@0
   204
{
David@0
   205
	if (draggingDelegate && [draggingDelegate respondsToSelector:@selector(webView:prepareForDragOperation:)]) {
David@0
   206
		return [draggingDelegate webView:self prepareForDragOperation:sender];
David@0
   207
	} else {
David@0
   208
		return [super prepareForDragOperation:sender];
David@0
   209
	}
David@0
   210
}
David@0
   211
David@0
   212
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
David@0
   213
{
David@0
   214
	if (draggingDelegate && [draggingDelegate respondsToSelector:@selector(webView:performDragOperation:)]) {
David@0
   215
		return [draggingDelegate webView:self performDragOperation:sender];
David@0
   216
	} else {
David@0
   217
		return [super performDragOperation:sender];
David@0
   218
	}
David@0
   219
}
David@0
   220
David@0
   221
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
David@0
   222
{
David@0
   223
	if (draggingDelegate && [draggingDelegate respondsToSelector:@selector(webView:concludeDragOperation:)]) {
David@0
   224
		[draggingDelegate webView:self concludeDragOperation:sender];
David@0
   225
	} else {
David@0
   226
		[super concludeDragOperation:sender];
David@0
   227
	}
David@0
   228
}
David@0
   229
David@0
   230
/*
David@0
   231
- (id)accessibilityAttributeValue:(NSString *)attribute
David@0
   232
{
David@0
   233
	NSLog(@"%@: Returning %@ for %@", self, [super accessibilityAttributeValue:attribute], attribute);
David@0
   234
David@0
   235
	return [super accessibilityAttributeValue:attribute];
David@0
   236
}
David@0
   237
*/
David@0
   238
David@0
   239
@end