2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #import "WebDataSource.h"
31 #import "WebArchive.h"
32 #import "WebArchiver.h"
33 #import "WebDOMOperationsPrivate.h"
34 #import "WebDataProtocol.h"
35 #import "WebDataSourceInternal.h"
36 #import "WebDefaultResourceLoadDelegate.h"
37 #import "WebDocument.h"
38 #import "WebDownloadInternal.h"
39 #import "WebFrameBridge.h"
40 #import "WebFrameInternal.h"
41 #import "WebFrameLoader.h"
42 #import "WebFrameLoadDelegate.h"
43 #import "WebFrameView.h"
44 #import "WebHTMLRepresentation.h"
45 #import "WebHTMLViewPrivate.h"
46 #import "WebHistory.h"
47 #import "WebHistoryItemPrivate.h"
48 #import "WebIconDatabasePrivate.h"
49 #import "WebKitErrorsPrivate.h"
50 #import "WebKitLogging.h"
51 #import "WebKitNSStringExtras.h"
52 #import "WebKitStatisticsPrivate.h"
53 #import "WebNSObjectExtras.h"
54 #import "WebNSURLExtras.h"
55 #import "WebNSURLRequestExtras.h"
56 #import "WebPDFRepresentation.h"
57 #import "WebPreferences.h"
58 #import "WebResourceLoadDelegate.h"
59 #import "WebResourcePrivate.h"
60 #import "WebScriptDebugServerPrivate.h"
61 #import "WebUnarchivingState.h"
62 #import "WebViewInternal.h"
63 #import <Foundation/NSURLConnection.h>
64 #import <Foundation/NSURLRequest.h>
65 #import <JavaScriptCore/Assertions.h>
66 #import <WebKit/DOMHTML.h>
67 #import <WebKit/DOMPrivate.h>
68 #import <WebKitSystemInterface.h>
69 #import "WebDocumentLoadStateMac.h"
71 @interface WebDataSourcePrivate : NSObject
75 WebDocumentLoadStateMac *loadState;
77 id <WebDocumentRepresentation> representation;
79 BOOL loadingFromPageCache;
80 WebUnarchivingState *unarchivingState;
81 NSMutableDictionary *subresources;
83 // The time when the data source was told to start loading.
84 double loadingStartedTime;
86 BOOL primaryLoadComplete;
88 BOOL isClientRedirect;
93 NSString *overrideEncoding;
95 BOOL representationFinishedLoading;
97 // The action that triggered loading of this data source -
98 // we keep this around for the benefit of the various policy
100 NSDictionary *triggeringAction;
102 // The last request that we checked click policy for - kept around
103 // so we can avoid asking again needlessly.
104 NSURLRequest *lastCheckedRequest;
106 // We retain all the received responses so we can play back the
107 // WebResourceLoadDelegate messages if the item is loaded from the
109 NSMutableArray *responses;
110 BOOL stopRecordingResponses;
115 @implementation WebDataSourcePrivate
119 ASSERT(![loadState isLoading]);
123 [representation release];
125 [triggeringAction release];
126 [lastCheckedRequest release];
128 [unarchivingState release];
135 @interface WebDataSource (WebFileInternal)
138 @implementation WebDataSource (WebFileInternal)
140 - (void)_setRepresentation: (id<WebDocumentRepresentation>)representation
142 [_private->representation release];
143 _private->representation = [representation retain];
144 _private->representationFinishedLoading = NO;
147 - (void)_prepareForLoadStart
149 ASSERT(![_private->loadState isStopping]);
150 [self _setPrimaryLoadComplete:NO];
151 ASSERT([self webFrame] != nil);
152 [_private->loadState clearErrors];
154 // Mark the start loading time.
155 _private->loadingStartedTime = CFAbsoluteTimeGetCurrent();
157 [_private->loadState setLoading:YES];
158 [[self _webView] _progressStarted:[self webFrame]];
159 [[self _webView] _didStartProvisionalLoadForFrame:[self webFrame]];
160 [[[self _webView] _frameLoadDelegateForwarder] webView:[self _webView]
161 didStartProvisionalLoadForFrame:[self webFrame]];
164 static inline void addTypesFromClass(NSMutableDictionary *allTypes, Class class, NSArray *supportTypes)
166 NSEnumerator *enumerator = [supportTypes objectEnumerator];
167 ASSERT(enumerator != nil);
168 NSString *mime = nil;
169 while ((mime = [enumerator nextObject]) != nil) {
170 // Don't clobber previously-registered classes.
171 if ([allTypes objectForKey:mime] == nil)
172 [allTypes setObject:class forKey:mime];
176 + (Class)_representationClassForMIMEType:(NSString *)MIMEType
179 return [WebView _viewClass:nil andRepresentationClass:&repClass forMIMEType:MIMEType] ? repClass : nil;
182 - (void)_addResponse:(NSURLResponse *)r
184 if (!_private->stopRecordingResponses) {
185 if (!_private->responses)
186 _private->responses = [[NSMutableArray alloc] init];
187 [_private->responses addObject: r];
193 @implementation WebDataSource (WebPrivate)
195 - (NSError *)_mainDocumentError
197 return [_private->loadState mainDocumentError];
200 - (void)_addSubframeArchives:(NSArray *)subframeArchives
202 NSEnumerator *enumerator = [subframeArchives objectEnumerator];
204 while ((archive = [enumerator nextObject]) != nil)
205 [self _addToUnarchiveState:archive];
208 - (NSFileWrapper *)_fileWrapperForURL:(NSURL *)URL
210 if ([URL isFileURL]) {
211 NSString *path = [[URL path] stringByResolvingSymlinksInPath];
212 return [[[NSFileWrapper alloc] initWithPath:path] autorelease];
215 WebResource *resource = [self subresourceForURL:URL];
217 return [resource _fileWrapperRepresentation];
220 NSCachedURLResponse *cachedResponse = [[self _webView] _cachedResponseForURL:URL];
221 if (cachedResponse) {
222 NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:[cachedResponse data]] autorelease];
223 [wrapper setPreferredFilename:[[cachedResponse response] suggestedFilename]];
232 @implementation WebDataSource (WebInternal)
234 - (void)_finishedLoading
236 _private->representationFinishedLoading = YES;
237 [[self representation] finishedLoadingWithDataSource:self];
240 - (void)_receivedData:(NSData *)data
242 [[self representation] receivedData:data withDataSource:self];
243 [[[[self webFrame] frameView] documentView] dataSourceUpdated:self];
246 - (void)_setMainDocumentError:(NSError *)error
248 if (!_private->representationFinishedLoading) {
249 _private->representationFinishedLoading = YES;
250 [[self representation] receivedError:error withDataSource:self];
254 - (void)_clearUnarchivingState
256 [_private->unarchivingState release];
257 _private->unarchivingState = nil;
260 - (void)_revertToProvisionalState
262 [self _setRepresentation:nil];
265 + (NSMutableDictionary *)_repTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission
267 static NSMutableDictionary *repTypes = nil;
268 static BOOL addedImageTypes = NO;
271 repTypes = [[NSMutableDictionary alloc] init];
272 addTypesFromClass(repTypes, [WebHTMLRepresentation class], [WebHTMLRepresentation supportedNonImageMIMETypes]);
274 // Since this is a "secret default" we don't both registering it.
275 BOOL omitPDFSupport = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitOmitPDFSupport"];
277 addTypesFromClass(repTypes, [WebPDFRepresentation class], [WebPDFRepresentation supportedMIMETypes]);
280 if (!addedImageTypes && !allowImageTypeOmission) {
281 addTypesFromClass(repTypes, [WebHTMLRepresentation class], [WebHTMLRepresentation supportedImageMIMETypes]);
282 addedImageTypes = YES;
288 - (void)_decidePolicyForMIMEType:(NSString *)MIMEType decisionListener:(WebPolicyDecisionListener *)listener
290 WebView *wv = [self _webView];
291 [[wv _policyDelegateForwarder] webView:wv decidePolicyForMIMEType:MIMEType
292 request:[self request]
293 frame:[self webFrame]
294 decisionListener:listener];
297 - (void)_receivedMainResourceError:(NSError *)error complete:(BOOL)isComplete
300 WebFrameBridge *bridge = [[self webFrame] _bridge];
302 // Retain the bridge because the stop may release the last reference to it.
306 // FIXME: Don't want to do this if an entirely new load is going, so should check
307 // that both data sources on the frame are either self or nil.
308 // Can't call [self _bridge] because we might not have commited yet
310 // FIXME: WebKitErrorPlugInWillHandleLoad is a workaround for the cancel we do to prevent loading plugin content twice. See <rdar://problem/4258008>
311 if ([error code] != NSURLErrorCancelled && [error code] != WebKitErrorPlugInWillHandleLoad)
312 [bridge handleFallbackContent];
317 [[self webFrame] _receivedMainResourceError:error];
318 [_private->loadState mainReceivedError:error complete:isComplete];
321 - (void)_downloadWithLoadingConnection:(NSURLConnection *)connection request:(NSURLRequest *)request response:(NSURLResponse *)r proxy:(WKNSURLConnectionDelegateProxyPtr) proxy
323 [WebDownload _downloadWithLoadingConnection:connection
326 delegate:[[self _webView] downloadDelegate]
330 - (void)_didFailLoadingWithError:(NSError *)error forResource:(id)identifier
332 WebView *webView = [self _webView];
334 [webView _completeProgressForIdentifier:identifier];
337 [[webView _resourceLoadDelegateForwarder] webView:webView resource:identifier didFailLoadingWithError:error fromDataSource:self];
340 - (void)_didFinishLoadingForResource:(id)identifier
342 WebView *webView = [self _webView];
344 [webView _completeProgressForIdentifier:identifier];
346 if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidFinishLoadingFromDataSource)
347 [[webView resourceLoadDelegate] webView:webView resource:identifier didFinishLoadingFromDataSource:self];
349 [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didFinishLoadingFromDataSource:self];
352 - (void)_didReceiveData:(NSData *)data contentLength:(int)lengthReceived forResource:(id)identifier
354 WebView *webView = [self _webView];
356 [webView _incrementProgressForIdentifier:identifier data:data];
358 if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveContentLength)
359 [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveContentLength:(WebNSUInteger)lengthReceived fromDataSource:self];
361 [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveContentLength:(WebNSUInteger)lengthReceived fromDataSource:self];
364 - (void)_didReceiveResponse:(NSURLResponse *)r forResource:(id)identifier
366 WebView *webView = [self _webView];
368 [self _addResponse:r];
370 [webView _incrementProgressForIdentifier:identifier response:r];
372 if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveResponse)
373 [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveResponse:r fromDataSource:self];
375 [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveResponse:r fromDataSource:self];
378 - (void)_didCancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
380 WebView *webView = [self _webView];
382 if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidCancelAuthenticationChallenge)
383 [[webView resourceLoadDelegate] webView:webView resource:identifier didCancelAuthenticationChallenge:currentWebChallenge fromDataSource:self];
385 [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didCancelAuthenticationChallenge:currentWebChallenge fromDataSource:self];
388 - (void)_didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)currentWebChallenge forResource:(id)identifier
390 WebView *webView = [self _webView];
392 if ([webView _resourceLoadDelegateImplementations].delegateImplementsDidReceiveAuthenticationChallenge)
393 [[webView resourceLoadDelegate] webView:webView resource:identifier didReceiveAuthenticationChallenge:currentWebChallenge fromDataSource:self];
395 [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier didReceiveAuthenticationChallenge:currentWebChallenge fromDataSource:self];
398 - (NSURLRequest *)_willSendRequest:(NSMutableURLRequest *)clientRequest forResource:(id)identifier redirectResponse:(NSURLResponse *)redirectResponse
400 WebView *webView = [self _webView];
402 [clientRequest _web_setHTTPUserAgent:[webView userAgentForURL:[clientRequest URL]]];
404 if ([webView _resourceLoadDelegateImplementations].delegateImplementsWillSendRequest)
405 return [[webView resourceLoadDelegate] webView:webView resource:identifier willSendRequest:clientRequest redirectResponse:redirectResponse fromDataSource:self];
407 return [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView resource:identifier willSendRequest:clientRequest redirectResponse:redirectResponse fromDataSource:self];
410 - (id)_identifierForInitialRequest:(NSURLRequest *)clientRequest
412 WebView *webView = [self _webView];
414 // The identifier is released after the last callback, rather than in dealloc
415 // to avoid potential cycles.
416 if ([webView _resourceLoadDelegateImplementations].delegateImplementsIdentifierForRequest)
417 return [[[webView resourceLoadDelegate] webView:webView identifierForInitialRequest:clientRequest fromDataSource:self] retain];
419 return [[[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:webView identifierForInitialRequest:clientRequest fromDataSource:self] retain];
422 - (WebResource *)_archivedSubresourceForURL:(NSURL *)URL
424 return [_private->unarchivingState archivedResourceForURL:URL];
427 - (void)_startLoading
429 [self _prepareForLoadStart];
431 if ([[_private->loadState frameLoader] isLoadingMainResource])
434 _private->loadingFromPageCache = NO;
437 id resourceLoadDelegate = [[self _webView] resourceLoadDelegate];
438 if ([resourceLoadDelegate respondsToSelector:@selector(webView:identifierForInitialRequest:fromDataSource:)])
439 identifier = [resourceLoadDelegate webView:[self _webView] identifierForInitialRequest:[_private->loadState originalRequest] fromDataSource:self];
441 identifier = [[WebDefaultResourceLoadDelegate sharedResourceLoadDelegate] webView:[self _webView] identifierForInitialRequest:[_private->loadState originalRequest] fromDataSource:self];
443 if (![[_private->loadState frameLoader] startLoadingMainResourceWithRequest:[_private->loadState request] identifier:identifier])
444 [_private->loadState updateLoading];
447 - (void)_stopRecordingResponses
449 _private->stopRecordingResponses = YES;
452 - (double)_loadingStartedTime
454 return _private->loadingStartedTime;
457 - (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement
459 DOMDocumentFragment *fragment = [self _documentFragmentWithArchive:archive];
461 [[self _bridge] replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:NO matchStyle:NO];
464 - (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive
467 WebResource *mainResource = [archive mainResource];
469 NSString *MIMEType = [mainResource MIMEType];
470 if ([WebView canShowMIMETypeAsHTML:MIMEType]) {
471 NSString *markupString = [[NSString alloc] initWithData:[mainResource data] encoding:NSUTF8StringEncoding];
472 // FIXME: seems poor form to do this as a side effect of getting a document fragment
473 [self _addToUnarchiveState:archive];
474 DOMDocumentFragment *fragment = [[self _bridge] documentFragmentWithMarkupString:markupString baseURLString:[[mainResource URL] _web_originalDataAsString]];
475 [markupString release];
477 } else if ([[WebFrameBridge supportedImageResourceMIMETypes] containsObject:MIMEType]) {
478 return [self _documentFragmentWithImageResource:mainResource];
485 - (DOMDocumentFragment *)_documentFragmentWithImageResource:(WebResource *)resource
487 DOMElement *imageElement = [self _imageElementWithImageResource:resource];
490 DOMDocumentFragment *fragment = [[[self _bridge] DOMDocument] createDocumentFragment];
491 [fragment appendChild:imageElement];
495 - (DOMElement *)_imageElementWithImageResource:(WebResource *)resource
500 [self addSubresource:resource];
502 DOMElement *imageElement = [[[self _bridge] DOMDocument] createElement:@"img"];
504 // FIXME: calling _web_originalDataAsString on a file URL returns an absolute path. Workaround this.
505 NSURL *URL = [resource URL];
506 [imageElement setAttribute:@"src" value:[URL isFileURL] ? [URL absoluteString] : [URL _web_originalDataAsString]];
513 return _private->pageTitle;
516 - (void)_setWebFrame:(WebFrame *)frame
520 [_private->loadState setFrameLoader:[frame _frameLoader]];
522 [_private->loadState setDataSource:self];
527 // May return nil if not initialized with a URL.
530 return [[self request] URL];
533 - (void)_loadFromPageCache:(NSDictionary *)pageCache
535 [self _prepareForLoadStart];
536 _private->loadingFromPageCache = YES;
537 [_private->loadState setCommitted:YES];
538 [[self webFrame] _commitProvisionalLoad:pageCache];
541 - (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName
543 return [_private->unarchivingState popSubframeArchiveWithFrameName:frameName];
546 - (void)_setIsClientRedirect:(BOOL)flag
548 _private->isClientRedirect = flag;
551 - (void)_setLastCheckedRequest:(NSURLRequest *)request
553 NSURLRequest *oldRequest = _private->lastCheckedRequest;
554 _private->lastCheckedRequest = [request copy];
555 [oldRequest release];
558 - (NSURLRequest *)_lastCheckedRequest
560 // It's OK not to make a copy here because we know the caller
561 // isn't going to modify this request
562 return [[_private->lastCheckedRequest retain] autorelease];
565 - (WebFrameBridge *)_bridge
567 ASSERT([_private->loadState isCommitted]);
568 return [[self webFrame] _bridge];
571 - (WebView *)_webView
573 return [[[_private->loadState frameLoader] webFrame] webView];
576 - (NSDictionary *)_triggeringAction
578 return [[_private->triggeringAction retain] autorelease];
581 - (void)_setTriggeringAction:(NSDictionary *)action
584 [_private->triggeringAction release];
585 _private->triggeringAction = action;
588 - (BOOL)_isDocumentHTML
590 NSString *MIMEType = [[self response] MIMEType];
591 return [WebView canShowMIMETypeAsHTML:MIMEType];
594 - (void)_stopLoadingWithError:(NSError *)error
596 [[_private->loadState frameLoader] stopLoadingWithError:error];
599 - (void)_setPrimaryLoadComplete:(BOOL)flag
601 _private->primaryLoadComplete = flag;
604 if ([[_private->loadState frameLoader] isLoadingMainResource]) {
605 [_private->loadState setMainResourceData:[[_private->loadState frameLoader] mainResourceData]];
606 [[_private->loadState frameLoader] releaseMainResourceLoader];
609 [_private->loadState updateLoading];
611 if ([WebScriptDebugServer listenerCount])
612 [[WebScriptDebugServer sharedScriptDebugServer] webView:[[self webFrame] webView] didLoadMainResourceForDataSource:self];
616 - (NSArray *)_responses
618 return _private->responses;
621 - (BOOL)_loadingFromPageCache
623 return _private->loadingFromPageCache;
626 -(void)_makeRepresentation
628 Class repClass = [[self class] _representationClassForMIMEType:[[self response] MIMEType]];
630 // Check if the data source was already bound?
631 if (![[self representation] isKindOfClass:repClass]) {
632 id newRep = repClass != nil ? [[repClass alloc] init] : nil;
633 [self _setRepresentation:(id <WebDocumentRepresentation>)newRep];
637 [_private->representation setDataSource:self];
640 - (BOOL)_isClientRedirect
642 return _private->isClientRedirect;
645 - (NSURL *)_URLForHistory
647 // Return the URL to be used for history and B/F list.
648 // Returns nil for WebDataProtocol URLs that aren't alternates
649 // for unreachable URLs, because these can't be stored in history.
650 NSURL *URL = [[_private->loadState originalRequestCopy] URL];
651 if ([WebDataProtocol _webIsDataProtocolURL:URL])
652 URL = [[_private->loadState originalRequestCopy] _webDataRequestUnreachableURL];
654 return [URL _webkit_canonicalize];
657 - (void)_addToUnarchiveState:(WebArchive *)archive
659 if (!_private->unarchivingState)
660 _private->unarchivingState = [[WebUnarchivingState alloc] init];
661 [_private->unarchivingState addArchive:archive];
664 - (void)_setOverrideEncoding:(NSString *)overrideEncoding
666 NSString *copy = [overrideEncoding copy];
667 [_private->overrideEncoding release];
668 _private->overrideEncoding = copy;
671 - (NSString *)_overrideEncoding
673 return [[_private->overrideEncoding copy] autorelease];
676 - (void)_setTitle:(NSString *)title
682 trimmed = [title _webkit_stringByTrimmingWhitespace];
683 if ([trimmed length] == 0)
686 if (trimmed == nil) {
687 if (_private->pageTitle == nil)
690 if ([_private->pageTitle isEqualToString:trimmed])
694 if (!trimmed || [trimmed length] == 0)
697 [[self _webView] _willChangeValueForKey:_WebMainFrameTitleKey];
698 [_private->pageTitle release];
699 _private->pageTitle = [trimmed copy];
700 [[self _webView] _didChangeValueForKey:_WebMainFrameTitleKey];
702 // The title doesn't get communicated to the WebView until we are committed.
703 if ([_private->loadState isCommitted]) {
704 NSURL *URLForHistory = [self _URLForHistory];
705 if (URLForHistory != nil) {
706 WebHistoryItem *entry = [[WebHistory optionalSharedHistory] itemForURL:URLForHistory];
707 [entry setTitle: _private->pageTitle];
709 // Must update the entries in the back-forward list too. This must go through the WebFrame because
710 // it has the right notion of the current b/f item.
711 [[self webFrame] _setTitle:_private->pageTitle];
713 [[self _webView] setMainFrameDocumentReady:YES]; // update observers with new DOMDocument
714 [[[self _webView] _frameLoadDelegateForwarder] webView:[self _webView]
715 didReceiveTitle:_private->pageTitle
716 forFrame:[self webFrame]];
721 - (WebDocumentLoadState *)_documentLoadState
723 return _private->loadState;
726 - (id)_initWithDocumentLoadState:(WebDocumentLoadStateMac *)loadState
733 _private = [[WebDataSourcePrivate alloc] init];
735 _private->loadState = [loadState retain];
737 LOG(Loading, "creating datasource for %@", [[_private->loadState request] URL]);
738 WKSupportsMultipartXMixedReplace([_private->loadState request]);
740 ++WebDataSourceCount;
748 @implementation WebDataSource
750 -(id)initWithRequest:(NSURLRequest *)request
752 return [self _initWithDocumentLoadState:[[WebDocumentLoadState alloc] initWithRequest:request]];
757 ASSERT([[_private->loadState frameLoader] activeDataSource] != self || ![[_private->loadState frameLoader] isLoading]);
759 --WebDataSourceCount;
768 --WebDataSourceCount;
775 return [_private->loadState mainResourceData];
778 - (id <WebDocumentRepresentation>)representation
780 return _private->representation;
783 - (WebFrame *)webFrame
785 return [[_private->loadState frameLoader] webFrame];
788 -(NSURLRequest *)initialRequest
790 NSURLRequest *clientRequest = [[_private->loadState originalRequest] _webDataRequestExternalRequest];
792 clientRequest = [_private->loadState originalRequest];
793 return clientRequest;
796 -(NSMutableURLRequest *)request
798 return [_private->loadState request];
801 - (NSURLResponse *)response
803 return [_private->loadState response];
806 - (NSString *)textEncodingName
808 NSString *textEncodingName = [self _overrideEncoding];
810 if (!textEncodingName)
811 textEncodingName = [[self response] textEncodingName];
813 return textEncodingName;
816 // Returns YES if there are any pending loads.
819 // Once a frame has loaded, we no longer need to consider subresources,
820 // but we still need to consider subframes.
821 if ([[[self webFrame] _frameLoader] state] != WebFrameStateComplete) {
822 if (!_private->primaryLoadComplete && [_private->loadState isLoading])
824 if ([[_private->loadState frameLoader] isLoadingSubresources])
826 if (![[[self webFrame] _bridge] doneProcessingData])
830 return [[self webFrame] _subframeIsLoading];
833 // Returns nil or the page title.
834 - (NSString *)pageTitle
836 return [[self representation] title];
839 - (NSURL *)unreachableURL
841 return [[_private->loadState originalRequest] _webDataRequestUnreachableURL];
844 - (WebArchive *)webArchive
846 // it makes no sense to grab a WebArchive from an uncommitted document.
847 if (![_private->loadState isCommitted])
850 return [WebArchiver archiveFrame:[self webFrame]];
853 - (WebResource *)mainResource
855 NSURLResponse *response = [self response];
856 return [[[WebResource alloc] initWithData:[self data]
858 MIMEType:[response MIMEType]
859 textEncodingName:[response textEncodingName]
860 frameName:[[self webFrame] name]] autorelease];
863 - (NSArray *)subresources
867 [[self _bridge] getAllResourceDatas:&datas andResponses:&responses];
868 ASSERT([datas count] == [responses count]);
870 NSMutableArray *subresources = [[NSMutableArray alloc] initWithCapacity:[datas count]];
871 for (unsigned i = 0; i < [datas count]; ++i) {
872 NSURLResponse *response = [responses objectAtIndex:i];
873 [subresources addObject:[[[WebResource alloc] _initWithData:[datas objectAtIndex:i] URL:[response URL] response:response] autorelease]];
876 return [subresources autorelease];
879 - (WebResource *)subresourceForURL:(NSURL *)URL
882 NSURLResponse *response;
883 if (![[self _bridge] getData:&data andResponse:&response forURL:URL])
886 return [[[WebResource alloc] _initWithData:data URL:URL response:response] autorelease];
889 - (void)addSubresource:(WebResource *)subresource
892 if (!_private->unarchivingState)
893 _private->unarchivingState = [[WebUnarchivingState alloc] init];
894 [_private->unarchivingState addResource:subresource];