WebCore:
[WebKit-https.git] / WebKit / WebView.subproj / WebHTMLRepresentation.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/WebHTMLRepresentation.h>
30
31 #import <WebKit/DOM.h>
32 #import <WebKit/WebArchive.h>
33 #import <WebKit/WebAssertions.h>
34 #import <WebKit/WebBridge.h>
35 #import <WebKit/WebDataSourcePrivate.h>
36 #import <WebKit/WebDocumentPrivate.h>
37 #import <WebKit/WebFramePrivate.h>
38 #import <WebKit/WebKitNSStringExtras.h>
39 #import <WebKit/WebKitStatisticsPrivate.h>
40 #import <WebKit/WebNSObjectExtras.h>
41 #import <WebKit/WebResourcePrivate.h>
42 #import <WebKit/WebView.h>
43
44 #import <Foundation/NSURLResponse.h>
45
46 @interface WebHTMLRepresentationPrivate : NSObject
47 {
48 @public
49     WebDataSource *dataSource;
50     WebBridge *bridge;
51     NSData *parsedArchiveData;
52 }
53 @end
54
55 @implementation WebHTMLRepresentationPrivate
56
57 - (void)dealloc
58 {
59     [parsedArchiveData release];
60     [super dealloc];
61 }
62
63 @end
64
65 @implementation WebHTMLRepresentation
66
67 - init
68 {
69     self = [super init];
70     if (!self)
71         return nil;
72     
73     _private = [[WebHTMLRepresentationPrivate alloc] init];
74     
75     ++WebHTMLRepresentationCount;
76     
77     return self;
78 }
79
80 - (void)dealloc
81 {
82     --WebHTMLRepresentationCount;
83     
84     [_private release];
85
86     [super dealloc];
87 }
88
89 - (void)finalize
90 {
91     --WebHTMLRepresentationCount;
92
93     [super finalize];
94 }
95
96 - (WebBridge *)_bridge
97 {
98     return _private->bridge;
99 }
100
101 - (void)setDataSource:(WebDataSource *)dataSource
102 {
103     _private->dataSource = dataSource;
104     _private->bridge = [[dataSource webFrame] _bridge];
105 }
106
107 - (BOOL)_isDisplayingWebArchive
108 {
109     return [[[_private->dataSource response] MIMEType] _webkit_isCaseInsensitiveEqualToString:@"application/x-webarchive"];
110 }
111
112 - (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource
113 {
114     if ([dataSource webFrame] && ![self _isDisplayingWebArchive]) {
115         [_private->bridge receivedData:data textEncodingName:[[_private->dataSource response] textEncodingName]];
116     }
117 }
118
119 - (void)receivedError:(NSError *)error withDataSource:(WebDataSource *)dataSource
120 {
121 }
122
123 - (void)loadArchive
124 {
125     WebArchive *archive = [[WebArchive alloc] initWithData:[_private->dataSource data]];
126     WebResource *mainResource = [archive mainResource];
127     NSArray *subresources = [archive subresources];
128     NSArray *subframeArchives = [archive subframeArchives];
129     [archive release];
130     if (!mainResource) {
131         return;
132     }
133     
134     NSData *data = [mainResource data];
135     [data retain];
136     [_private->parsedArchiveData release];
137     _private->parsedArchiveData = data;
138     
139     [_private->dataSource _addSubresources:subresources];
140     [_private->dataSource _addSubframeArchives:subframeArchives];
141     [_private->bridge closeURL];
142     [_private->bridge openURL:[mainResource URL]
143                        reload:NO 
144                   contentType:[mainResource MIMEType]
145                       refresh:NO
146                  lastModified:nil
147                     pageCache:nil];
148     [_private->bridge receivedData:data textEncodingName:[mainResource textEncodingName]];
149 }
150
151 - (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource
152 {
153     WebFrame *frame = [dataSource webFrame];
154     if (frame) {
155         if ([self _isDisplayingWebArchive]) {
156             [self loadArchive];
157         } else {
158             // Telling the bridge we received some data and passing nil as the data is our
159             // way to get work done that is normally done when the first bit of data is
160             // received, even for the case of a document with no data (like about:blank).
161             [_private->bridge receivedData:nil textEncodingName:[[_private->dataSource response] textEncodingName]];
162         }
163         
164         WebView *webView = [frame webView];
165         if ([webView isEditable]) {
166             [_private->bridge applyEditingStyleToBodyElement];
167         }
168     }
169 }
170
171 - (BOOL)canProvideDocumentSource
172 {
173     return YES;
174 }
175
176 - (NSString *)documentSource
177 {
178     if ([self _isDisplayingWebArchive]) {
179         return [[[NSString alloc] initWithData:_private->parsedArchiveData encoding:NSUTF8StringEncoding] autorelease];
180     } else {
181         return [WebBridge stringWithData:[_private->dataSource data] textEncoding:[_private->bridge textEncoding]];
182     }
183 }
184
185 - (NSString *)title
186 {
187     return [_private->dataSource _title];
188 }
189
190 - (DOMDocument *)DOMDocument
191 {
192     return [_private->bridge DOMDocument];
193 }
194
195 - (NSAttributedString *)attributedText
196 {
197     // FIXME:  Implement
198     return nil;
199 }
200
201 - (NSAttributedString *)attributedStringFrom: (DOMNode *)startNode startOffset: (int)startOffset to: (DOMNode *)endNode endOffset: (int)endOffset
202 {
203     return [_private->bridge attributedStringFrom: startNode startOffset: startOffset to: endNode endOffset: endOffset];
204 }
205
206 - (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form
207 {
208     return [_private->bridge elementWithName:name inForm:form];
209 }
210
211 - (DOMElement *)elementForView:(NSView *)view
212 {
213     return [_private->bridge elementForView:view];
214 }
215
216 - (NSView *)viewForElement:(DOMElement *)element
217 {
218     return [_private->bridge viewForElement:element];
219 }
220
221 - (BOOL)elementDoesAutoComplete:(DOMElement *)element
222 {
223     return [_private->bridge elementDoesAutoComplete:element];
224 }
225
226 - (BOOL)elementIsPassword:(DOMElement *)element
227 {
228     return [_private->bridge elementIsPassword:element];
229 }
230
231 - (DOMElement *)formForElement:(DOMElement *)element
232 {
233     return [_private->bridge formForElement:element];
234 }
235
236 - (DOMElement *)currentForm
237 {
238     return [_private->bridge currentForm];
239 }
240
241 - (NSArray *)controlsInForm:(DOMElement *)form
242 {
243     return [_private->bridge controlsInForm:form];
244 }
245
246 - (NSString *)searchForLabels:(NSArray *)labels beforeElement:(DOMElement *)element
247 {
248     return [_private->bridge searchForLabels:labels beforeElement:element];
249 }
250
251 - (NSString *)matchLabels:(NSArray *)labels againstElement:(DOMElement *)element
252 {
253     return [_private->bridge matchLabels:labels againstElement:element];
254 }
255
256 @end