3b6d2560a64b424ed1fb3ba7a8ad3c0d92b759f4
[WebKit-https.git] / WebKit / Plugins.subproj / WebPluginController.m
1 //
2 //  WebPluginController.m
3 //  WebKit
4 //
5 //  Created by Chris Blumenberg on Wed Oct 23 2002.
6 //  Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
7 //
8
9 #import <WebKit/WebPluginController.h>
10
11 #import <WebKit/WebBridge.h>
12 #import <WebKit/WebFramePrivate.h>
13 #import <WebKit/WebFrameView.h>
14 #import <WebKit/WebHTMLViewPrivate.h>
15 #import <WebKit/WebKitLogging.h>
16 #import <WebKit/WebNSViewExtras.h>
17 #import <WebKit/WebPlugin.h>
18 #import <WebKit/WebPluginContainer.h>
19 #import <WebKit/WebPluginPackage.h>
20 #import <WebKit/WebPluginViewFactory.h>
21 #import <WebKit/WebViewPrivate.h>
22 #import <WebKit/WebUIDelegate.h>
23
24 #import <WebCore/WebCoreBridge.h>
25
26 #import <Foundation/NSURL_NSURLExtras.h>
27 #import <Foundation/NSURLRequest.h>
28
29 @interface NSView (PluginSecrets)
30 - (void)setContainingWindow:(NSWindow *)w;
31 @end
32
33 // For compatibility only.
34 @interface NSObject (OldPluginAPI)
35 + (NSView *)pluginViewWithArguments:(NSDictionary *)arguments;
36 @end
37
38 @interface NSView (OldPluginAPI)
39 - (void)pluginInitialize;
40 - (void)pluginStart;
41 - (void)pluginStop;
42 - (void)pluginDestroy;
43 @end
44
45 static NSMutableSet *pluginViews = nil;
46
47 @implementation WebPluginController
48
49 + (NSView *)plugInViewWithArguments:(NSDictionary *)arguments fromPluginPackage:(WebPluginPackage *)pluginPackage
50 {
51     [pluginPackage load];
52     Class viewFactory = [pluginPackage viewFactory];
53     
54     NSView *view = nil;
55     if ([viewFactory respondsToSelector:@selector(plugInViewWithArguments:)]) {
56         view = [viewFactory plugInViewWithArguments:arguments];
57     } else if ([viewFactory respondsToSelector:@selector(pluginViewWithArguments:)]) {
58         view = [viewFactory pluginViewWithArguments:arguments];
59     }
60     
61     if (view == nil) {
62         return nil;
63     }
64     
65     if (pluginViews == nil) {
66         pluginViews = [[NSMutableSet alloc] init];
67     }
68     [pluginViews addObject:view];
69     
70     return view;
71 }
72
73 + (BOOL)isPlugInView:(NSView *)view
74 {
75     return [pluginViews containsObject:view];
76 }
77
78 - (id)initWithDocumentView:(NSView *)view
79 {
80     [super init];
81     _documentView = view;
82     _views = [[NSMutableArray alloc] init];
83     return self;
84 }
85
86 - (void)startAllPlugins
87 {
88     if (_started) {
89         return;
90     }
91     
92     if ([_views count] > 0) {
93         LOG(Plugins, "starting WebKit plugins : %@", [_views description]);
94     }
95     
96     int i, count = [_views count];
97     for (i = 0; i < count; i++) {
98         id aView = [_views objectAtIndex:i];
99         if ([aView respondsToSelector:@selector(webPlugInStart)])
100             [aView webPlugInStart];
101         else if ([aView respondsToSelector:@selector(pluginStart)])
102             [aView pluginStart];
103     }
104     _started = YES;
105 }
106
107 - (void)stopAllPlugins
108 {
109     if (!_started) {
110         return;
111     }
112
113     if ([_views count] > 0) {
114         LOG(Plugins, "stopping WebKit plugins: %@", [_views description]);
115     }
116     
117     int i, count = [_views count];
118     for (i = 0; i < count; i++) {
119         id aView = [_views objectAtIndex:i];
120         if ([aView respondsToSelector:@selector(webPlugInStop)])
121             [aView webPlugInStop];
122         else if ([aView respondsToSelector:@selector(pluginStop)])
123             [aView pluginStop];
124     }
125     _started = NO;
126 }
127
128 - (void)addPlugin:(NSView *)view
129 {
130     if (!_documentView) {
131         ERROR("can't add a plug-in to a defunct WebPluginController");
132         return;
133     }
134     
135     if (![_views containsObject:view]) {
136         [_views addObject:view];
137         
138         LOG(Plugins, "initializing plug-in %@", view);
139         if ([view respondsToSelector:@selector(webPlugInInitialize)])
140             [view webPlugInInitialize];
141         else if ([view respondsToSelector:@selector(pluginInitialize)])
142             [view pluginInitialize];
143
144         if (_started) {
145             LOG(Plugins, "starting plug-in %@", view);
146             if ([view respondsToSelector:@selector(webPlugInStart)])
147                 [view webPlugInStart];
148             else if ([view respondsToSelector:@selector(pluginStart)])
149                 [view pluginStart];
150             
151             if ([view respondsToSelector:@selector(setContainingWindow:)])
152                 [view setContainingWindow:[_documentView window]];
153         }
154     }
155 }
156
157 - (void)destroyAllPlugins
158 {    
159     [self stopAllPlugins];
160
161     if ([_views count] > 0) {
162         LOG(Plugins, "destroying WebKit plugins: %@", [_views description]);
163     }
164     
165     int i, count = [_views count];
166     for (i = 0; i < count; i++) {
167         id aView = [_views objectAtIndex:i];
168         if ([aView respondsToSelector:@selector(webPlugInDestroy)]) {
169             [aView webPlugInDestroy];
170         } else if ([aView respondsToSelector:@selector(pluginDestroy)]) {
171             [aView pluginDestroy];
172         }
173         [pluginViews removeObject:aView];
174     }
175     [_views makeObjectsPerformSelector:@selector(removeFromSuperviewWithoutNeedingDisplay)];
176     [_views release];
177     _views = nil;
178
179     _documentView = nil;
180 }
181
182 - (id)_webPluginContainerCheckIfAllowedToLoadRequest:(NSURLRequest *)Request inFrame:(NSString *)target resultObject:(id)obj selector:(SEL)selector
183 {
184     // FIXME: really implement this
185     [obj performSelector:selector withObject:(id)YES];
186     return nil;
187 }
188
189 - (void)_webPluginContainerCancelCheckIfAllowedToLoadRequest:(id)checkIdentifier
190 {
191     // FIXME: really implement this
192 }
193
194 - (void)webPlugInContainerLoadRequest:(NSURLRequest *)request inFrame:(NSString *)target
195 {
196     if (!request) {
197         ERROR("nil URL passed");
198         return;
199     }
200     if (!_documentView) {
201         ERROR("could not load URL %@ because plug-in has already been destroyed", request);
202         return;
203     }
204     WebFrame *frame = [_documentView _frame];
205     if (!frame) {
206         ERROR("could not load URL %@ because plug-in has already been stopped", request);
207         return;
208     }
209     if (!target) {
210         target = @"_top";
211     }
212     NSString *JSString = [[request URL] _web_scriptIfJavaScriptURL];
213     if (JSString) {
214         if ([frame findFrameNamed:target] != frame) {
215             ERROR("JavaScript requests can only be made on the frame that contains the plug-in");
216             return;
217         }
218         [[frame _bridge] stringByEvaluatingJavaScriptFromString:JSString];
219     } else {
220         if (!request) {
221             ERROR("could not load URL %@", [request URL]);
222             return;
223         }
224         [frame _loadRequest:request inFrameNamed:target];
225     }
226 }
227
228 // For compatibility only.
229 - (void)showURL:(NSURL *)URL inFrame:(NSString *)target
230 {
231     [self webPlugInContainerLoadRequest:[NSURLRequest requestWithURL:URL] inFrame:target];
232 }
233
234 - (void)webPlugInContainerShowStatus:(NSString *)message
235 {
236     if (!message) {
237         message = @"";
238     }
239     if (!_documentView) {
240         ERROR("could not show status message (%@) because plug-in has already been destroyed", message);
241         return;
242     }
243     WebView *v = [_documentView _webView];
244     [[v _UIDelegateForwarder] webView:v setStatusText:message];
245 }
246
247 // For compatibility only.
248 - (void)showStatus:(NSString *)message
249 {
250     [self webPlugInContainerShowStatus:message];
251 }
252
253 - (NSColor *)webPlugInContainerSelectionColor
254 {
255     return [[_documentView _bridge] selectionColor];
256 }
257
258 // For compatibility only.
259 - (NSColor *)selectionColor
260 {
261     return [self webPlugInContainerSelectionColor];
262 }
263
264 - (WebFrame *)webFrame
265 {
266     return [_documentView _frame];
267 }
268
269 @end