JavaScriptCore:
[WebKit-https.git] / WebKit / WebView / WebHTMLRepresentation.m
1 /*
2  * Copyright (C) 2005, 2006 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 "WebHTMLRepresentation.h"
30
31 #import "DOMNodeInternal.h"
32 #import "DOMRangeInternal.h"
33 #import "WebArchive.h"
34 #import "WebBasePluginPackage.h"
35 #import "WebDataSourceInternal.h"
36 #import "WebDocumentPrivate.h"
37 #import "WebFrameBridge.h"
38 #import "WebFrameInternal.h"
39 #import "WebKitNSStringExtras.h"
40 #import "WebKitStatisticsPrivate.h"
41 #import "WebNSAttributedStringExtras.h"
42 #import "WebNSObjectExtras.h"
43 #import "WebResourcePrivate.h"
44 #import "WebView.h"
45 #import <Foundation/NSURLResponse.h>
46 #import <JavaScriptCore/Assertions.h>
47 #import <WebCore/Document.h>
48 #import <WebCore/DocumentLoader.h>
49 #import <WebCore/FrameMac.h>
50 #import <WebCore/Range.h>
51 #import <WebCore/WebMimeTypeRegistryBridge.h>
52
53 using namespace WebCore;
54
55 @interface WebHTMLRepresentationPrivate : NSObject
56 {
57 @public
58     WebDataSource *dataSource;
59     WebFrameBridge *bridge;
60     NSData *parsedArchiveData;
61     
62     BOOL hasSentResponseToPlugin;
63     id <WebPluginManualLoader> manualLoader;
64     NSView *pluginView;
65 }
66 @end
67
68 @implementation WebHTMLRepresentationPrivate
69
70 - (void)dealloc
71 {
72     [parsedArchiveData release];
73     [super dealloc];
74 }
75
76 @end
77
78 @implementation WebHTMLRepresentation
79
80 + (NSArray *)supportedMIMETypes
81 {
82     static NSMutableArray *mimeTypes\v = nil;
83     
84     if (!mimeTypes) {
85         mimeTypes = [[self supportedNonImageMIMETypes] mutableCopy];
86         [mimeTypes addObjectsFromArray:[self supportedImageMIMETypes]];
87     }
88     
89     return mimeTypes;
90 }
91
92 + (NSArray *)supportedNonImageMIMETypes
93 {
94     return [WebMimeTypeRegistryBridge supportedNonImageMIMETypes];
95 }
96
97 + (NSArray *)supportedImageMIMETypes
98 {
99     return [WebMimeTypeRegistryBridge supportedImageMIMETypes];
100 }
101
102 - init
103 {
104     self = [super init];
105     if (!self)
106         return nil;
107     
108     _private = [[WebHTMLRepresentationPrivate alloc] init];
109     
110     ++WebHTMLRepresentationCount;
111     
112     return self;
113 }
114
115 - (void)dealloc
116 {
117     --WebHTMLRepresentationCount;
118     
119     [_private release];
120
121     [super dealloc];
122 }
123
124 - (void)finalize
125 {
126     --WebHTMLRepresentationCount;
127
128     [super finalize];
129 }
130
131 - (WebFrameBridge *)_bridge
132 {
133     return _private->bridge;
134 }
135
136 - (void)_redirectDataToManualLoader:(id<WebPluginManualLoader>)manualLoader forPluginView:(NSView *)pluginView;
137 {
138     _private->manualLoader = manualLoader;
139     _private->pluginView = pluginView;
140 }
141
142 - (void)setDataSource:(WebDataSource *)dataSource
143 {
144     _private->dataSource = dataSource;
145     _private->bridge = [[dataSource webFrame] _bridge];
146 }
147
148 - (BOOL)_isDisplayingWebArchive
149 {
150     return [[[_private->dataSource response] MIMEType] _webkit_isCaseInsensitiveEqualToString:@"application/x-webarchive"];
151 }
152
153 - (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource
154 {
155     if ([dataSource webFrame] && ![self _isDisplayingWebArchive]) {
156         if (!_private->pluginView)
157             [_private->bridge receivedData:data textEncodingName:[[_private->dataSource response] textEncodingName]];
158
159         if (_private->pluginView) {
160             if (!_private->hasSentResponseToPlugin) {
161                 [_private->manualLoader pluginView:_private->pluginView receivedResponse:[dataSource response]];
162                 _private->hasSentResponseToPlugin = YES;
163             }
164             
165             [_private->manualLoader pluginView:_private->pluginView receivedData:data];
166         }
167     }
168 }
169
170 - (void)receivedError:(NSError *)error withDataSource:(WebDataSource *)dataSource
171 {
172     if (_private->pluginView) {
173         [_private->manualLoader pluginView:_private->pluginView receivedError:error];
174     }
175 }
176
177 - (void)loadArchive
178 {
179     WebArchive *archive = [[WebArchive alloc] initWithData:[_private->dataSource data]];
180     [[_private->dataSource webFrame] loadArchive:archive];
181 }
182
183 - (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource
184 {
185     WebFrame *frame = [dataSource webFrame];
186
187     if (_private->pluginView) {
188         [_private->manualLoader pluginViewFinishedLoading:_private->pluginView];
189         return;
190     }
191
192     if (frame) {
193         if ([self _isDisplayingWebArchive])
194             [self loadArchive];
195         else
196             // Telling the bridge we received some data and passing nil as the data is our
197             // way to get work done that is normally done when the first bit of data is
198             // received, even for the case of a document with no data (like about:blank).
199             [_private->bridge receivedData:nil textEncodingName:[[_private->dataSource response] textEncodingName]];
200         
201         WebView *webView = [frame webView];
202         if ([webView isEditable])
203             core(frame)->applyEditingStyleToBodyElement();
204     }
205 }
206
207 - (BOOL)canProvideDocumentSource
208 {
209     return [_private->bridge canProvideDocumentSource];
210 }
211
212 - (BOOL)canSaveAsWebArchive
213 {
214     return [_private->bridge canSaveAsWebArchive];
215 }
216
217 - (NSString *)documentSource
218 {
219     return [_private->bridge stringWithData:[_private->dataSource data]];
220 }
221
222 - (NSString *)title
223 {
224     return [_private->dataSource _documentLoader]->title();
225 }
226
227 - (DOMDocument *)DOMDocument
228 {
229     return [[_private->bridge webFrame] DOMDocument];
230 }
231
232 - (NSAttributedString *)attributedText
233 {
234     // FIXME: Implement
235     return nil;
236 }
237
238 - (NSAttributedString *)attributedStringFrom:(DOMNode *)startNode startOffset:(int)startOffset to:(DOMNode *)endNode endOffset:(int)endOffset
239 {
240     Range range([startNode _node]->document(), [startNode _node], startOffset, [endNode _node], endOffset);
241     return [NSAttributedString _web_attributedStringFromRange:&range];
242 }
243
244 - (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form
245 {
246     return [_private->bridge elementWithName:name inForm:form];
247 }
248
249 - (BOOL)elementDoesAutoComplete:(DOMElement *)element
250 {
251     return [_private->bridge elementDoesAutoComplete:element];
252 }
253
254 - (BOOL)elementIsPassword:(DOMElement *)element
255 {
256     return [_private->bridge elementIsPassword:element];
257 }
258
259 - (DOMElement *)formForElement:(DOMElement *)element
260 {
261     return [_private->bridge formForElement:element];
262 }
263
264 - (DOMElement *)currentForm
265 {
266     return [_private->bridge currentForm];
267 }
268
269 - (NSArray *)controlsInForm:(DOMElement *)form
270 {
271     return [_private->bridge controlsInForm:form];
272 }
273
274 - (NSString *)searchForLabels:(NSArray *)labels beforeElement:(DOMElement *)element
275 {
276     return [_private->bridge searchForLabels:labels beforeElement:element];
277 }
278
279 - (NSString *)matchLabels:(NSArray *)labels againstElement:(DOMElement *)element
280 {
281     return [_private->bridge matchLabels:labels againstElement:element];
282 }
283
284 @end