c3d43e3fee86ebdcb6bdaa7826b66b8d3e2b4978
[WebKit-https.git] / WebKit / Plugins / WebPluginDocumentView.m
1 /*
2  * Copyright (C) 2005 Apple Computer, 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer. 
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution. 
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission. 
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #import <WebKit/WebPluginDocumentView.h>
30
31 #import <JavaScriptCore/Assertions.h>
32 #import <WebKit/WebDataSourcePrivate.h>
33 #import <WebKit/WebFrame.h>
34 #import <WebKit/WebFrameView.h>
35 #import <WebKit/WebKitErrorsPrivate.h>
36 #import <WebKit/WebNSURLExtras.h>
37 #import <WebKit/WebNSViewExtras.h>
38 #import <WebKit/WebPlugin.h>
39 #import <WebKit/WebPluginPrivate.h>
40 #import <WebKit/WebPluginController.h>
41 #import <WebKit/WebPluginDatabase.h>
42 #import <WebKit/WebPluginPackage.h>
43 #import <WebKit/WebPluginViewFactoryPrivate.h>
44 #import <WebKit/WebView.h>
45
46 @implementation WebPluginDocumentView
47
48 - initWithFrame:(NSRect)frame
49 {
50     [super initWithFrame:frame];
51     [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
52     needsLayout = YES;
53     pluginController = [[WebPluginController alloc] initWithDocumentView:self];
54     return self;
55 }
56
57 - (void)dealloc
58 {
59     [pluginView release];
60     [plugin release];
61     [pluginController destroyAllPlugins];
62     [pluginController release];
63     [super dealloc];
64 }
65
66 - (void)drawRect:(NSRect)rect
67 {
68     if (needsLayout) {
69         [self layout];
70     }
71     [super drawRect:rect];
72 }
73
74 - (void)setDataSource:(WebDataSource *)dataSource
75 {
76     // Since this class is a WebDocumentView and WebDocumentRepresentation, setDataSource: will be called twice. Do work only once.
77     if (dataSourceHasBeenSet)
78         return;
79     
80     // As noted above, -setDataSource: will be called twice -- once for the WebDocumentRepresentation, once for the WebDocumentView.
81     // We don't want to make the plugin until we know we're being committed as the WebDocumentView for the WebFrame.  This check is
82     // to ensure that we've been added to the view hierarchy before attempting to create the plugin, as some plugins currently work
83     // under this assumption.
84     if (![self superview])
85         return;
86         
87     _dataSource = dataSource;
88     [pluginController setDataSource:dataSource];
89     dataSourceHasBeenSet = YES;
90     
91     NSURLResponse *response = [dataSource response];
92     NSString *MIMEType = [response MIMEType];    
93     plugin = (WebPluginPackage *)[[[WebPluginDatabase installedPlugins] pluginForMIMEType:MIMEType] retain];
94     ASSERT([plugin isKindOfClass:[WebPluginPackage class]]);
95     
96     NSURL *URL = [response URL];
97     NSString *URLString = [URL _web_originalDataAsString];
98     NSDictionary *attributes = [[NSDictionary alloc] initWithObjectsAndKeys:MIMEType, @"type", URLString, @"src", nil];
99     NSDictionary *arguments = [[NSDictionary alloc] initWithObjectsAndKeys:
100         URL,                WebPlugInBaseURLKey,
101         attributes,         WebPlugInAttributesKey,
102         pluginController,   WebPlugInContainerKey,
103         [NSNumber numberWithInt:WebPlugInModeFull], WebPlugInModeKey,
104         [NSNumber numberWithBool:NO], WebPlugInShouldLoadMainResourceKey, // NO because we're already loading the data!
105         nil];
106     [attributes release];
107     pluginView = [[WebPluginController plugInViewWithArguments:arguments fromPluginPackage:plugin] retain];
108     [arguments release];
109
110     ASSERT(pluginView != nil);
111
112     [self addSubview:pluginView];
113     [pluginController addPlugin:pluginView];
114     [pluginView setFrame:[self bounds]];
115     [pluginView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
116     
117     if ([pluginView respondsToSelector:@selector(webPlugInMainResourceDidReceiveResponse:)])
118         [pluginView webPlugInMainResourceDidReceiveResponse:[dataSource response]];
119 }
120
121 - (void)dataSourceUpdated:(WebDataSource *)dataSource
122 {
123     if (![pluginView respondsToSelector:@selector(webPlugInMainResourceDidReceiveData:)]) {
124         // Cancel the load since this plug-in does its own loading.
125         NSURLResponse *response = [dataSource response];
126         // FIXME: See <rdar://problem/4258008>
127         NSError *error = [[NSError alloc] _initWithPluginErrorCode:WebKitErrorPlugInWillHandleLoad
128                                                         contentURL:[response URL]
129                                                      pluginPageURL:nil
130                                                         pluginName:[plugin name]
131                                                           MIMEType:[response MIMEType]];
132         [dataSource _stopLoadingWithError:error];
133         [error release];
134     }
135 }
136
137 - (void)setNeedsLayout:(BOOL)flag
138 {
139     needsLayout = flag;
140 }
141
142 - (void)layout
143 {
144     NSRect superFrame = [[[_dataSource webFrame] frameView] frame];
145     [self setFrame:NSMakeRect(0, 0, NSWidth(superFrame), NSHeight(superFrame))];
146     needsLayout = NO;    
147 }
148
149 - (NSWindow *)currentWindow
150 {
151     NSWindow *window = [self window];
152     return window != nil ? window : [[_dataSource _webView] hostWindow];
153 }
154
155 - (void)viewWillMoveToWindow:(NSWindow *)window
156 {
157     if ([[_dataSource _webView] hostWindow] == nil) {
158         [pluginController stopAllPlugins];
159     }
160 }
161
162 - (void)viewDidMoveToWindow
163 {
164     if ([self currentWindow] != nil) {
165         [pluginController startAllPlugins];
166     }
167 }
168
169 - (void)viewWillMoveToHostWindow:(NSWindow *)hostWindow
170 {
171     if ([self window] == nil) {
172         [pluginController stopAllPlugins];
173     }
174 }
175
176 - (void)viewDidMoveToHostWindow
177 {
178     if ([self currentWindow] != nil) {
179         [pluginController startAllPlugins];
180     }    
181 }
182
183 - (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource
184 {
185     if ([pluginView respondsToSelector:@selector(webPlugInMainResourceDidReceiveData:)])
186         [pluginView webPlugInMainResourceDidReceiveData:data];
187 }
188
189 - (void)receivedError:(NSError *)error withDataSource:(WebDataSource *)dataSource
190 {
191     if ([pluginView respondsToSelector:@selector(webPlugInMainResourceDidFailWithError:)])
192         [pluginView webPlugInMainResourceDidFailWithError:error];
193 }
194
195 - (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource
196 {
197     if ([pluginView respondsToSelector:@selector(webPlugInMainResourceDidFinishLoading)])
198         [pluginView webPlugInMainResourceDidFinishLoading];
199 }
200
201 - (BOOL)canProvideDocumentSource
202 {
203     return NO;
204 }
205
206 - (NSString *)documentSource
207 {
208     return nil;
209 }
210
211 - (NSString *)title
212 {
213     return nil;
214 }
215
216 @end