WebKit:
[WebKit-https.git] / WebKit / Plugins.subproj / WebPluginContainerCheck.m
1 //
2 //  WebPluginContainerCheck.m
3 //  WebKit
4 //
5 //  Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
6 //
7
8 #import <WebKit/WebPluginContainerCheck.h>
9
10 #import <Foundation/NSDictionary.h>
11 #import <Foundation/NSURL.h>
12 #import <Foundation/NSURLRequest.h>
13 #import <WebKit/WebAssertions.h>
14 #import <WebKit/WebBridge.h>
15 #import <WebKit/WebFrame.h>
16 #import <WebKit/WebPluginContainer.h>
17 #import <WebKit/WebPluginContainerPrivate.h>
18 #import <WebKit/WebPluginController.h>
19 #import <WebKit/WebPolicyDelegate.h>
20 #import <WebKit/WebPolicyDelegatePrivate.h>
21 #import <WebKit/WebView.h>
22 #import <WebKit/WebViewPrivate.h>
23 #import <objc/objc-runtime.h>
24
25 @implementation WebPluginContainerCheck
26
27 + (id)checkWithRequest:(NSURLRequest *)request target:(NSString *)target resultObject:(id)obj selector:(SEL)selector controller:(WebPluginController *)controller
28 {
29     return [[[self alloc] initWithRequest:request target:target resultObject:obj selector:selector controller:controller] autorelease];
30 }
31
32 - (id)initWithRequest:(NSURLRequest *)request target:(NSString *)target resultObject:(id)obj selector:(SEL)selector controller:(WebPluginController *)controller
33 {
34     if (!(self = [super init]))
35         return nil;
36
37     _request = [request copy];
38     _target = [target copy];
39     _resultObject = [obj retain];
40     _resultSelector = selector;
41
42     // controller owns us so don't retain, to avoid cycle
43     _controller = controller;
44
45     return self;
46 }
47
48 - (void)finalize
49 {
50     // mandatory to complete or cancel before releasing this object
51     ASSERT(_done);
52 }
53
54 - (void)dealloc
55 {
56     // mandatory to complete or cancel before releasing this object
57     ASSERT(_done);
58     [super dealloc];
59 }
60
61 - (void)_continueWithPolicy:(WebPolicyAction)policy
62 {
63     void (*callBack)(id, SEL, BOOL) = (void (*)(id, SEL, BOOL))objc_msgSend;
64     (*callBack) (_resultObject, _resultSelector, (policy == WebPolicyUse));
65
66     // this will call indirectly call cancel
67     [_controller _webPluginContainerCancelCheckIfAllowedToLoadRequest:self];
68 }
69
70 - (BOOL)_isForbiddenFileLoad
71 {
72    BOOL ignore;
73    WebBridge *bridge = [_controller bridge];
74    if (![bridge canLoadURL:[_request URL] fromReferrer:[bridge referrer] hideReferrer:&ignore]) {
75        [self _continueWithPolicy:WebPolicyIgnore];
76        return YES;
77    }
78
79    return NO;
80 }
81
82 - (NSDictionary *)_actionInformationWithURL:(NSURL *)URL
83 {
84     return [NSDictionary dictionaryWithObjectsAndKeys:
85                [NSNumber numberWithInt:WebNavigationTypePlugInRequest], WebActionNavigationTypeKey,
86                [NSNumber numberWithInt:0], WebActionModifierFlagsKey,
87                URL, WebActionOriginalURLKey,
88                nil];
89 }
90
91 - (void)_askPolicyDelegate
92 {
93     WebView *webView = [_controller webView];
94
95     WebFrame *targetFrame;
96     if ([_target length] > 0) {
97         targetFrame = [[_controller webFrame] findFrameNamed:_target];
98     } else {
99         targetFrame = [_controller webFrame];
100     }
101
102     NSDictionary *action = [self _actionInformationWithURL:[_request URL]];
103
104     _listener = [[WebPolicyDecisionListener alloc] _initWithTarget:self action:@selector(_continueWithPolicy:)];
105
106     if (targetFrame == nil) {
107         // would open new window
108         [[webView _policyDelegateForwarder] webView:webView
109                      decidePolicyForNewWindowAction:action
110                                             request:_request
111                                        newFrameName:_target
112                                    decisionListener:_listener];
113     } else {
114         // would target existing frame
115         [[webView _policyDelegateForwarder] webView:webView
116                     decidePolicyForNavigationAction:action
117                                             request:_request
118                                               frame:targetFrame
119                                    decisionListener:_listener];        
120     }
121 }
122
123 - (void)start
124 {
125     ASSERT(!_listener);
126     ASSERT(!_done);
127
128     if ([self _isForbiddenFileLoad])
129         return;
130
131     [self _askPolicyDelegate];
132 }
133
134 - (void)cancel
135 {
136     if (_done)
137         return;
138
139     [_request release];
140     _request = nil;
141     
142     [_target release];
143     _target = nil;
144
145     [_listener _invalidate];
146     [_listener release];
147     _listener = nil;
148
149     [_resultObject autorelease];
150     _resultObject = nil;
151
152     _controller = nil;
153
154     _done = YES;
155 }
156
157 @end