WebKit:
[WebKit-https.git] / WebKit / Loader / WebFrameLoader.m
1 /*
2  * Copyright (C) 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 <WebKit/WebFrameLoader.h>
30
31 #import <JavaScriptCore/Assertions.h>
32 #import <WebKit/WebDataSourceInternal.h>
33 #import <WebKit/WebFrameInternal.h>
34 #import <WebKit/WebIconLoader.h>
35 #import <WebKit/WebMainResourceLoader.h>
36 #import <WebKit/WebKitLogging.h>
37 #import <WebKit/WebViewInternal.h>
38
39 @implementation WebFrameLoader
40
41 - (id)initWithWebFrame:(WebFrame *)wf
42 {
43     self = [super init];
44     if (self) {
45         webFrame = wf;
46         state = WebFrameStateCommittedPage;
47     }
48     return self;    
49 }
50
51 - (void)dealloc
52 {
53     // FIXME: should these even exist?
54     [mainResourceLoader release];
55     [subresourceLoaders release];
56     [plugInStreamLoaders release];
57     [iconLoader release];
58     [dataSource release];
59     [provisionalDataSource release];
60     
61     [super dealloc];
62 }
63
64 - (BOOL)hasIconLoader
65 {
66     return iconLoader != nil;
67 }
68
69 - (void)loadIconWithRequest:(NSURLRequest *)request
70 {
71     ASSERT(!iconLoader);
72     iconLoader = [[WebIconLoader alloc] initWithRequest:request];
73     [iconLoader setFrameLoader:self];
74     [iconLoader loadWithRequest:request];
75 }
76
77 - (void)stopLoadingIcon
78 {
79     [iconLoader stopLoading];
80 }
81
82 - (void)addPlugInStreamLoader:(WebLoader *)loader
83 {
84     if (!plugInStreamLoaders)
85         plugInStreamLoaders = [[NSMutableArray alloc] init];
86     [plugInStreamLoaders addObject:loader];
87 }
88
89 - (void)removePlugInStreamLoader:(WebLoader *)loader
90 {
91     [plugInStreamLoaders removeObject:loader];
92 }    
93
94 - (void)setDefersCallbacks:(BOOL)defers
95 {
96     [mainResourceLoader setDefersCallbacks:defers];
97     
98     NSEnumerator *e = [subresourceLoaders objectEnumerator];
99     WebLoader *loader;
100     while ((loader = [e nextObject]))
101         [loader setDefersCallbacks:defers];
102     
103     e = [plugInStreamLoaders objectEnumerator];
104     while ((loader = [e nextObject]))
105         [loader setDefersCallbacks:defers];
106 }
107
108 - (void)stopLoadingPlugIns
109 {
110     [plugInStreamLoaders makeObjectsPerformSelector:@selector(cancel)];
111     [plugInStreamLoaders removeAllObjects];   
112 }
113
114 - (BOOL)isLoadingMainResource
115 {
116     return mainResourceLoader != nil;
117 }
118
119 - (BOOL)isLoadingSubresources
120 {
121     return [subresourceLoaders count];
122 }
123
124 - (BOOL)isLoadingPlugIns
125 {
126     return [plugInStreamLoaders count];
127 }
128
129 - (BOOL)isLoading
130 {
131     return [self isLoadingMainResource] || [self isLoadingSubresources] || [self isLoadingPlugIns];
132 }
133
134 - (void)stopLoadingSubresources
135 {
136     NSArray *loaders = [subresourceLoaders copy];
137     [loaders makeObjectsPerformSelector:@selector(cancel)];
138     [loaders release];
139     [subresourceLoaders removeAllObjects];
140 }
141
142 - (void)addSubresourceLoader:(WebLoader *)loader
143 {
144     if (subresourceLoaders == nil)
145         subresourceLoaders = [[NSMutableArray alloc] init];
146     [subresourceLoaders addObject:loader];
147 }
148
149 - (void)removeSubresourceLoader:(WebLoader *)loader
150 {
151     [subresourceLoaders removeObject:loader];
152 }
153
154 - (NSData *)mainResourceData
155 {
156     return [mainResourceLoader resourceData];
157 }
158
159 - (void)releaseMainResourceLoader
160 {
161     [mainResourceLoader release];
162     mainResourceLoader = nil;
163 }
164
165 - (void)cancelMainResourceLoad
166 {
167     [mainResourceLoader cancel];
168 }
169
170 - (BOOL)startLoadingMainResourceWithRequest:(NSMutableURLRequest *)request identifier:(id)identifier
171 {
172     mainResourceLoader = [[WebMainResourceLoader alloc] initWithFrameLoader:self];
173     
174     [mainResourceLoader setIdentifier:identifier];
175     [[provisionalDataSource webFrame] _addExtraFieldsToRequest:request mainResource:YES alwaysFromRequest:NO];
176     if (![mainResourceLoader loadWithRequest:request]) {
177         // FIXME: if this should really be caught, we should just ASSERT this doesn't happen;
178         // should it be caught by other parts of WebKit or other parts of the app?
179         LOG_ERROR("could not create WebResourceHandle for URL %@ -- should be caught by policy handler level", [request URL]);
180         [mainResourceLoader release];
181         mainResourceLoader = nil;
182         return NO;
183     }
184     
185     return YES;
186 }
187
188 - (void)stopLoadingWithError:(NSError *)error
189 {
190     [mainResourceLoader cancelWithError:error];
191 }
192
193 - (WebDataSource *)dataSource
194 {
195     return dataSource; 
196 }
197
198 - (void)_setDataSource:(WebDataSource *)ds
199 {
200     if (ds == nil && dataSource == nil)
201         return;
202     
203     ASSERT(ds != dataSource);
204     
205     [webFrame _prepareForDataSourceReplacement];
206     [dataSource _setWebFrame:nil];
207     
208     [ds retain];
209     [dataSource release];
210     dataSource = ds;
211
212     [ds _setWebFrame:webFrame];
213 }
214
215 - (void)clearDataSource
216 {
217     [self _setDataSource:nil];
218 }
219
220 - (WebDataSource *)provisionalDataSource 
221 {
222     return provisionalDataSource; 
223 }
224
225 - (void)_setProvisionalDataSource: (WebDataSource *)d
226 {
227     ASSERT(!d || !provisionalDataSource);
228
229     if (provisionalDataSource != dataSource)
230         [provisionalDataSource _setWebFrame:nil];
231
232     [d retain];
233     [provisionalDataSource release];
234     provisionalDataSource = d;
235
236     [d _setWebFrame:webFrame];
237 }
238
239 - (void)_clearProvisionalDataSource
240 {
241     [self _setProvisionalDataSource:nil];
242 }
243
244 - (WebFrameState)state
245 {
246     return state;
247 }
248
249 #ifndef NDEBUG
250 static const char * const stateNames[] = {
251     "WebFrameStateProvisional",
252     "WebFrameStateCommittedPage",
253     "WebFrameStateComplete"
254 };
255 #endif
256
257 static CFAbsoluteTime _timeOfLastCompletedLoad;
258
259 + (CFAbsoluteTime)timeOfLastCompletedLoad
260 {
261     return _timeOfLastCompletedLoad;
262 }
263
264 - (void)_setState:(WebFrameState)newState
265 {
266     LOG(Loading, "%@:  transition from %s to %s", [webFrame name], stateNames[state], stateNames[newState]);
267     if ([webFrame webView])
268         LOG(Timing, "%@:  transition from %s to %s, %f seconds since start of document load", [webFrame name], stateNames[state], stateNames[newState], CFAbsoluteTimeGetCurrent() - [[[[webFrame webView] mainFrame] dataSource] _loadingStartedTime]);
269     
270     if (newState == WebFrameStateComplete && webFrame == [[webFrame webView] mainFrame])
271         LOG(DocumentLoad, "completed %@ (%f seconds)", [[[self dataSource] request] URL], CFAbsoluteTimeGetCurrent() - [[self dataSource] _loadingStartedTime]);
272     
273     state = newState;
274     
275     if (state == WebFrameStateProvisional)
276         [webFrame _provisionalLoadStarted];
277     else if (state == WebFrameStateComplete) {
278         [webFrame _frameLoadCompleted];
279         _timeOfLastCompletedLoad = CFAbsoluteTimeGetCurrent();
280         [dataSource _stopRecordingResponses];
281     }
282 }
283
284 - (void)clearProvisionalLoad
285 {
286     [self _setProvisionalDataSource:nil];
287     [[webFrame webView] _progressCompleted:webFrame];
288     [self _setState:WebFrameStateComplete];
289 }
290
291 - (void)markLoadComplete
292 {
293     [self _setState:WebFrameStateComplete];
294 }
295
296 - (void)clearIconLoader
297 {
298     [iconLoader release];
299     iconLoader = nil;
300 }
301
302 - (void)commitProvisionalLoad
303 {
304     [self stopLoadingSubresources];
305     [self stopLoadingPlugIns];
306     [self clearIconLoader];
307
308     [self _setDataSource:provisionalDataSource];
309     [self _setProvisionalDataSource:nil];
310     [self _setState:WebFrameStateCommittedPage];
311 }
312
313 - (void)stopLoading
314 {
315     [provisionalDataSource _stopLoading];
316     [dataSource _stopLoading];
317     [self _clearProvisionalDataSource];
318 }
319
320 // FIXME: poor method name; also why is this not part of startProvisionalLoad:?
321 - (void)startLoading
322 {
323     [provisionalDataSource _startLoading];
324 }
325
326 - (void)startProvisionalLoad:(WebDataSource *)ds
327 {
328     [self _setProvisionalDataSource:ds];
329     [self _setState:WebFrameStateProvisional];
330 }
331
332 - (void)setupForReplace
333 {
334     [self _setState:WebFrameStateProvisional];
335     WebDataSource *old = provisionalDataSource;
336     provisionalDataSource = dataSource;
337     dataSource = nil;
338     [old release];
339     
340     [webFrame _detachChildren];
341 }
342
343 - (WebDataSource *)activeDataSource
344 {
345     if (state == WebFrameStateProvisional)
346         return provisionalDataSource;
347
348     return dataSource;
349 }
350
351 - (WebResource *)_archivedSubresourceForURL:(NSURL *)URL
352 {
353     return [[self activeDataSource] _archivedSubresourceForURL:URL];
354 }
355
356 - (BOOL)_defersCallbacks
357 {
358     return [[self activeDataSource] _defersCallbacks];
359 }
360
361 - (id)_identifierForInitialRequest:(NSURLRequest *)clientRequest
362 {
363     return [[self activeDataSource] _identifierForInitialRequest:clientRequest];
364 }
365
366 - (NSURLRequest *)_willSendRequest:(NSMutableURLRequest *)clientRequest forResource:(id)identifier redirectResponse:(NSURLResponse *)redirectResponse
367 {
368     return [[self activeDataSource] _willSendRequest:clientRequest forResource:identifier redirectResponse:redirectResponse];
369 }
370
371 - (void)_didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
372 {
373     return [[self activeDataSource] _didReceiveAuthenticationChallenge:currentWebChallenge forResource:identifier];
374 }
375
376 - (void)_didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
377 {
378     return [[self activeDataSource] _didCancelAuthenticationChallenge:currentWebChallenge forResource:identifier];
379 }
380
381 - (void)_didReceiveResponse:(NSURLResponse *)r forResource:(id)identifier
382 {
383     return [[self activeDataSource] _didReceiveResponse:r forResource:identifier];
384 }
385
386 - (void)_didReceiveData:(NSData *)data contentLength:(int)lengthReceived forResource:(id)identifier
387 {
388     return [[self activeDataSource] _didReceiveData:data contentLength:lengthReceived forResource:identifier];
389 }
390
391 - (void)_didFinishLoadingForResource:(id)identifier
392 {
393     return [[self activeDataSource] _didFinishLoadingForResource:identifier];
394 }
395
396 - (void)_didFailLoadingWithError:(NSError *)error forResource:(id)identifier
397 {
398     return [[self activeDataSource] _didFailLoadingWithError:error forResource:identifier];
399 }
400
401 - (BOOL)_privateBrowsingEnabled
402 {
403     return [[self activeDataSource] _privateBrowsingEnabled];
404 }
405
406 - (void)_addPlugInStreamLoader:(WebLoader *)loader
407 {
408     return [[self activeDataSource] _addPlugInStreamLoader:loader];
409 }
410
411 - (void)_removePlugInStreamLoader:(WebLoader *)loader
412 {
413     return [[self activeDataSource] _removePlugInStreamLoader:loader];
414 }
415
416 - (void)_finishedLoadingResource
417 {
418     return [[self activeDataSource] _finishedLoadingResource];
419 }
420
421 - (void)_receivedError:(NSError *)error
422 {
423     return [[self activeDataSource] _receivedError:error];
424 }
425
426 - (void)_addSubresourceLoader:(WebLoader *)loader
427 {
428     return [[self activeDataSource] _addSubresourceLoader:loader];
429 }
430
431 - (void)_removeSubresourceLoader:(WebLoader *)loader
432 {
433     return [[self activeDataSource] _removeSubresourceLoader:loader];
434 }
435
436 - (NSURLRequest *)_originalRequest
437 {
438     return [[self activeDataSource] _originalRequest];
439 }
440
441 - (WebFrame *)webFrame
442 {
443     return [[self activeDataSource] webFrame];
444 }
445
446 - (void)_receivedMainResourceError:(NSError *)error complete:(BOOL)isComplete
447 {
448     WebDataSource *ds = [self activeDataSource];
449     [ds retain];
450     [ds _receivedMainResourceError:error complete:isComplete];
451     [ds release];
452 }
453
454 - (NSURLRequest *)initialRequest
455 {
456     return [[self activeDataSource] initialRequest];
457 }
458
459 - (void)_receivedData:(NSData *)data
460 {
461     [[self activeDataSource] _receivedData:data];
462 }
463
464 - (void)_setRequest:(NSURLRequest *)request
465 {
466     [[self activeDataSource] _setRequest:request];
467 }
468
469 - (void)_downloadWithLoadingConnection:(NSURLConnection *)connection request:(NSURLRequest *)request response:(NSURLResponse *)r proxy:(WKNSURLConnectionDelegateProxyPtr)proxy
470 {
471     [[self activeDataSource] _downloadWithLoadingConnection:connection request:request response:r proxy:proxy];
472 }
473
474 - (void)_handleFallbackContent
475 {
476     [[self activeDataSource] _handleFallbackContent];
477 }
478
479 - (BOOL)_isStopping
480 {
481     return [[self activeDataSource] _isStopping];
482 }
483
484 - (void)_decidePolicyForMIMEType:(NSString *)MIMEType decisionListener:(WebPolicyDecisionListener *)listener
485 {
486     [[self activeDataSource] _decidePolicyForMIMEType:MIMEType decisionListener:listener];
487 }
488
489 - (void)_setupForReplaceByMIMEType:(NSString *)newMIMEType
490 {
491     [[self activeDataSource] _setupForReplaceByMIMEType:newMIMEType];
492 }
493
494 - (void)_setResponse:(NSURLResponse *)response
495 {
496     [[self activeDataSource] _setResponse:response];
497 }
498
499 - (void)_mainReceivedError:(NSError *)error complete:(BOOL)isComplete
500 {
501     [[self activeDataSource] _mainReceivedError:error complete:isComplete];
502 }
503
504 - (void)_finishedLoading
505 {
506     [[self activeDataSource] _finishedLoading];
507 }
508
509 - (void)_mainReceivedBytesSoFar:(unsigned)bytesSoFar complete:(BOOL)isComplete
510 {
511     [[self activeDataSource] _mainReceivedBytesSoFar:bytesSoFar complete:isComplete];
512 }
513
514 - (void)_iconLoaderReceivedPageIcon:(WebIconLoader *)iLoader
515 {
516     ASSERT(iLoader == iconLoader);
517     [[self activeDataSource] _iconLoaderReceivedPageIcon:iLoader];
518 }
519
520 - (NSURL *)_URL
521 {
522     return [[self activeDataSource] _URL];
523 }
524
525 @end