WebCore:
[WebKit-https.git] / WebKit / mac / Plugins / WebPluginContainerCheck.mm
1 /*
2  * Copyright (C) 2005, 2008 Apple 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 "WebPluginContainerCheck.h"
30
31 #import "WebFrameInternal.h"
32 #import "WebPluginContainerPrivate.h"
33 #import "WebPluginController.h"
34 #import "WebPolicyDelegatePrivate.h"
35 #import "WebView.h"
36 #import "WebViewInternal.h"
37 #import <Foundation/NSDictionary.h>
38 #import <Foundation/NSURL.h>
39 #import <Foundation/NSURLRequest.h>
40 #import <JavaScriptCore/Assertions.h>
41 #import <WebCore/Frame.h>
42 #import <WebCore/FrameLoader.h>
43 #import <WebCore/FrameLoaderTypes.h>
44 #import <objc/objc-runtime.h>
45
46 using namespace WebCore;
47
48 @implementation WebPluginContainerCheck
49
50 + (id)checkWithRequest:(NSURLRequest *)request target:(NSString *)target resultObject:(id)obj selector:(SEL)selector controller:(WebPluginController *)controller
51 {
52     return [[[self alloc] initWithRequest:request target:target resultObject:obj selector:selector controller:controller] autorelease];
53 }
54
55 - (id)initWithRequest:(NSURLRequest *)request target:(NSString *)target resultObject:(id)obj selector:(SEL)selector controller:(WebPluginController *)controller
56 {
57     if (!(self = [super init]))
58         return nil;
59
60     _request = [request copy];
61     _target = [target copy];
62     _resultObject = [obj retain];
63     _resultSelector = selector;
64
65     // controller owns us so don't retain, to avoid cycle
66     _controller = controller;
67
68     return self;
69 }
70
71 - (void)finalize
72 {
73     // mandatory to complete or cancel before releasing this object
74     ASSERT(_done);
75     [super finalize];
76 }
77
78 - (void)dealloc
79 {
80     // mandatory to complete or cancel before releasing this object
81     ASSERT(_done);
82     [super dealloc];
83 }
84
85 - (void)_continueWithPolicy:(PolicyAction)policy
86 {
87     ((void (*)(id, SEL, BOOL))objc_msgSend)(_resultObject, _resultSelector, (policy == PolicyUse));
88
89     // this will call indirectly call cancel
90     [_controller _webPluginContainerCancelCheckIfAllowedToLoadRequest:self];
91 }
92
93 - (BOOL)_isForbiddenFileLoad
94 {
95    Frame* coreFrame = core([_controller webFrame]);
96    ASSERT(coreFrame);
97    if (!coreFrame->loader()->canLoad([_request URL], coreFrame->document())) {
98        [self _continueWithPolicy:PolicyIgnore];
99        return YES;
100    }
101
102    return NO;
103 }
104
105 - (NSDictionary *)_actionInformationWithURL:(NSURL *)URL
106 {
107     return [NSDictionary dictionaryWithObjectsAndKeys:
108                [NSNumber numberWithInt:WebNavigationTypePlugInRequest], WebActionNavigationTypeKey,
109                [NSNumber numberWithInt:0], WebActionModifierFlagsKey,
110                URL, WebActionOriginalURLKey,
111                nil];
112 }
113
114 - (void)_askPolicyDelegate
115 {
116     WebView *webView = [_controller webView];
117
118     WebFrame *targetFrame;
119     if ([_target length] > 0) {
120         targetFrame = [[_controller webFrame] findFrameNamed:_target];
121     } else {
122         targetFrame = [_controller webFrame];
123     }
124
125     NSDictionary *action = [self _actionInformationWithURL:[_request URL]];
126
127     _listener = [[WebPolicyDecisionListener alloc] _initWithTarget:self action:@selector(_continueWithPolicy:)];
128
129     if (targetFrame == nil) {
130         // would open new window
131         [[webView _policyDelegateForwarder] webView:webView
132                      decidePolicyForNewWindowAction:action
133                                             request:_request
134                                        newFrameName:_target
135                                    decisionListener:_listener];
136     } else {
137         // would target existing frame
138         [[webView _policyDelegateForwarder] webView:webView
139                     decidePolicyForNavigationAction:action
140                                             request:_request
141                                               frame:targetFrame
142                                    decisionListener:_listener];        
143     }
144 }
145
146 - (void)start
147 {
148     ASSERT(!_listener);
149     ASSERT(!_done);
150
151     if ([self _isForbiddenFileLoad])
152         return;
153
154     [self _askPolicyDelegate];
155 }
156
157 - (void)cancel
158 {
159     if (_done)
160         return;
161
162     [_request release];
163     _request = nil;
164     
165     [_target release];
166     _target = nil;
167
168     [_listener _invalidate];
169     [_listener release];
170     _listener = nil;
171
172     [_resultObject autorelease];
173     _resultObject = nil;
174
175     _controller = nil;
176
177     _done = YES;
178 }
179
180 @end