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