Changeset 31281 in webkit
- Timestamp:
- Mar 25, 2008 10:11:16 AM (16 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 2 deleted
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r31279 r31281 1 2008-03-25 Brady Eidson <beidson@apple.com> 2 3 Reviewed by Darin 4 5 <rdar://problem/4516169> - Support WebArchives on Windows 6 And pave the way for many future WebArchive bug fixes and enhancements 7 8 This patch accomplishes two main goals: 9 1 - Consolidates much of the spread out WebKitMac archive code into one place in WebCore. This allows for cleaner refactoring 10 in the future as well as adding more archive formats with ease. 11 2 - Hooks up WebArchive support on Windows. Safari-style .webarchive files are nothing more than property lists readable by 12 CoreFoundation. While there are still some outstanding issues, including an NSKeyedArchiver chunk of data for the 13 ResourceResponse for each resource, this patch manually parses through the property list on CoreFoundation platforms and 14 gets many archives loading on Windows 15 16 My goal for this first cut was zero behavior change. As such, I went for a direct port of the WebKitMac code. There will be 17 opportunities for redesign and refactoring as followups. 18 19 * WebCore.base.exp: 20 21 * loader/DocumentLoader.cpp: 22 (WebCore::DocumentLoader::setupForReplaceByMIMEType): Ported from WebKitMac, WebDataSource 23 (WebCore::DocumentLoader::addAllArchiveResources): 24 (WebCore::DocumentLoader::addArchiveResource): 25 (WebCore::DocumentLoader::archiveResourceForURL): 26 (WebCore::DocumentLoader::popArchiveForSubframe): 27 (WebCore::DocumentLoader::clearArchiveResources): 28 * loader/DocumentLoader.h: 29 30 * loader/FrameLoader.cpp: Moved WebFrameLoaderClient and WebFrame code down into their more appropriate FrameLoader home 31 (WebCore::FrameLoader::FrameLoader): 32 (WebCore::FrameLoader::setDefersLoading): 33 (WebCore::FrameLoader::deliverArchivedResourcesAfterDelay): 34 (WebCore::FrameLoader::archiveResourceDeliveryTimerFired): 35 (WebCore::FrameLoader::loadURLIntoChildFrame): 36 (WebCore::FrameLoader::loadArchive): 37 (WebCore::FrameLoader::scheduleArchiveLoad): 38 (WebCore::FrameLoader::stopAllLoaders): 39 (WebCore::FrameLoader::cancelPendingArchiveLoad): 40 (WebCore::FrameLoader::isArchiveLoadPending): 41 (WebCore::FrameLoader::finishedLoadingDocument): 42 * loader/FrameLoader.h: 43 44 * loader/ResourceLoader.cpp: 45 (WebCore::ResourceLoader::load): 46 47 * loader/archive/Archive.h: Generic "Archive of web resources" class that is only useful when subclassed. 48 Contains a MainResource, subresources, and Archives for subframes 49 (WebCore::Archive::mainResource): 50 (WebCore::Archive::subresources): 51 (WebCore::Archive::subframeArchives): 52 (WebCore::Archive::setMainResource): 53 (WebCore::Archive::addSubresource): 54 (WebCore::Archive::addSubframeArchive): 55 56 * loader/archive/ArchiveFactory.cpp: A class that will take raw archive data and the MIMEtype, and create the 57 appropriate Archive class for it. Additionally it handles registering the known MIMEtypes for all known archive formats 58 (WebCore::archiveFactoryCreate): 59 (WebCore::archiveMIMETypes): 60 (WebCore::ArchiveFactory::isArchiveMimeType): 61 (WebCore::ArchiveFactory::create): 62 (WebCore::ArchiveFactory::registerKnownArchiveMIMETypes): 63 * loader/archive/ArchiveFactory.h: 64 65 * loader/archive/ArchiveResource.cpp: Analog to "WebResource" in WebKitMac. Contains the data and other important 66 attributes of an archived resource 67 (WebCore::ArchiveResource::create): 68 (WebCore::ArchiveResource::ArchiveResource): 69 (WebCore::ArchiveResource::response): 70 * loader/archive/ArchiveResource.h: 71 (WebCore::ArchiveResource::data): 72 (WebCore::ArchiveResource::url): 73 (WebCore::ArchiveResource::mimeType): 74 (WebCore::ArchiveResource::textEncoding): 75 (WebCore::ArchiveResource::frameName): 76 (WebCore::ArchiveResource::ignoreWhenUnarchiving): 77 (WebCore::ArchiveResource::shouldIgnoreWhenUnarchiving): 78 79 * loader/archive/ArchiveResourceCollection.cpp: Analog of "WebUnarchivingState" in WebKitMac. Contains a hash of 80 all the resources for every frame in an archive, and contains the archives for each subframe needed to load a multi-frame archive 81 (WebCore::ArchiveResourceCollection::ArchiveResourceCollection): 82 (WebCore::ArchiveResourceCollection::addAllResources): 83 (WebCore::ArchiveResourceCollection::addResource): 84 (WebCore::ArchiveResourceCollection::archiveResourceForURL): 85 (WebCore::ArchiveResourceCollection::popSubframeArchive): 86 * loader/archive/ArchiveResourceCollection.h: 87 88 * loader/archive/cf/LegacyWebArchive.cpp: Subclass of Archive specifically for Webkit's Objective-C based ".webarchive" format. 89 Mostly a collection of static methods involved in parsing and serializing a WebKit-style .webarchive. Is mostly supported 90 for any CF platform. 91 (WebCore::createPropertyListRepresentationFromResource): 92 (WebCore::createPropertyListRep): 93 (WebCore::createResourceResponseFromPropertyListData): 94 (WebCore::createResource): 95 (WebCore::LegacyWebArchive::create): 96 (WebCore::LegacyWebArchive::LegacyWebArchive): 97 (WebCore::LegacyWebArchive::init): 98 (WebCore::LegacyWebArchive::extract): 99 (WebCore::LegacyWebArchive::rawDataRepresentation): 100 (WebCore::createResourceResponseFromMacArchivedData): 101 (WebCore::propertyListDataFromResourceResponse): 102 * loader/archive/cf/LegacyWebArchive.h: 103 * loader/archive/cf/LegacyWebArchiveMac.mm: 104 (WebCore::createResourceResponseFromMacArchivedData): 105 (WebCore::propertyListDataFromResourceResponse): 106 107 * platform/network/mac/ResourceRequest.h: 108 * platform/network/mac/ResourceRequestMac.mm: 109 (WebCore::ResourceRequest::applyWebArchiveHackForMail): Tweak the resource request for Mac clients when loading WebArchives 110 1 111 2008-03-25 David Hyatt <hyatt@apple.com> 2 112 -
trunk/WebCore/WebCore.base.exp
r31177 r31281 139 139 __ZN7WebCore11FileChooserD1Ev 140 140 __ZN7WebCore11FrameLoader11completeURLERKNS_6StringE 141 __ZN7WebCore11FrameLoader11loadArchiveEN3WTF10PassRefPtrINS_7ArchiveEEE 141 142 __ZN7WebCore11FrameLoader11setEncodingERKNS_6StringEb 142 143 __ZN7WebCore11FrameLoader12canCachePageEv … … 151 152 __ZN7WebCore11FrameLoader18shouldHideReferrerERKNS_4KURLERKNS_6StringE 152 153 __ZN7WebCore11FrameLoader20continueLoadWithDataEPNS_12SharedBufferERKNS_6StringES5_RKNS_4KURLE 154 __ZN7WebCore11FrameLoader21loadURLIntoChildFrameERKNS_4KURLERKNS_6StringEPNS_5FrameE 153 155 __ZN7WebCore11FrameLoader21setCurrentHistoryItemEN3WTF10PassRefPtrINS_11HistoryItemEEE 154 156 __ZN7WebCore11FrameLoader22findFrameForNavigationERKNS_12AtomicStringE … … 266 268 __ZN7WebCore14DocumentLoader13attachToFrameEv 267 269 __ZN7WebCore14DocumentLoader15detachFromFrameEv 270 __ZN7WebCore14DocumentLoader18addArchiveResourceEN3WTF10PassRefPtrINS_15ArchiveResourceEEE 268 271 __ZN7WebCore14DocumentLoader19prepareForLoadStartEv 269 272 __ZN7WebCore14DocumentLoader21addPlugInStreamLoaderEPNS_14ResourceLoaderE 273 __ZN7WebCore14DocumentLoader21archiveResourceForURLERKNS_4KURLE 274 __ZN7WebCore14DocumentLoader22addAllArchiveResourcesEPNS_7ArchiveE 270 275 __ZN7WebCore14DocumentLoader22cancelMainResourceLoadERKNS_13ResourceErrorE 271 276 __ZN7WebCore14DocumentLoader24removePlugInStreamLoaderEPNS_14ResourceLoaderE … … 285 290 __ZN7WebCore14ResourceLoader19setShouldBufferDataEb 286 291 __ZN7WebCore14SecurityOrigin6createERKNS_6StringES3_tPS0_ 292 __ZN7WebCore15ArchiveResource6createEN3WTF10PassRefPtrINS_12SharedBufferEEERKNS_4KURLERKNS_6StringESA_SA_RKNS_16ResourceResponseE 293 __ZN7WebCore15ArchiveResource8responseEv 287 294 __ZN7WebCore15BackForwardList10removeItemEPNS_11HistoryItemE 288 295 __ZN7WebCore15BackForwardList10setEnabledEb … … 333 340 __ZN7WebCore16FontPlatformDataC1EP6NSFontbb 334 341 __ZN7WebCore16FontPlatformDataD1Ev 342 __ZN7WebCore16LegacyWebArchive21rawDataRepresentationEv 343 __ZN7WebCore16LegacyWebArchive6createEN3WTF10PassRefPtrINS_15ArchiveResourceEEERNS1_6VectorIS4_Lm0EEERNS5_INS2_IS0_EELm0EEE 344 __ZN7WebCore16LegacyWebArchive6createEPNS_12SharedBufferE 345 __ZN7WebCore16LegacyWebArchive6createEv 335 346 __ZN7WebCore16MIMETypeRegistry24isSupportedImageMIMETypeERKNS_6StringE 336 347 __ZN7WebCore16MIMETypeRegistry26getSupportedImageMIMETypesEv -
trunk/WebCore/loader/DocumentLoader.cpp
r31038 r31281 30 30 #include "DocumentLoader.h" 31 31 32 #include "ArchiveResourceCollection.h" 32 33 #include "CachedPage.h" 33 34 #include "DocLoader.h" … … 43 44 #include "StringBuffer.h" 44 45 #include "XMLTokenizer.h" 46 45 47 #include <wtf/Assertions.h> 46 48 #include <wtf/unicode/Unicode.h> … … 365 367 stopLoadingSubresources(); 366 368 stopLoadingPlugIns(); 367 368 frameLoader()->finalSetupForReplace(this); 369 clearArchiveResources(); 369 370 } 370 371 … … 439 440 } 440 441 442 void DocumentLoader::addAllArchiveResources(Archive* archive) 443 { 444 if (!m_archiveResourceCollection) 445 m_archiveResourceCollection.set(new ArchiveResourceCollection); 446 447 ASSERT(archive); 448 if (!archive) 449 return; 450 451 m_archiveResourceCollection->addAllResources(archive); 452 } 453 454 // FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on. 455 // Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps? 456 void DocumentLoader::addArchiveResource(PassRefPtr<ArchiveResource> resource) 457 { 458 if (!m_archiveResourceCollection) 459 m_archiveResourceCollection.set(new ArchiveResourceCollection); 460 461 ASSERT(resource); 462 if (!resource) 463 return; 464 465 m_archiveResourceCollection->addResource(resource); 466 } 467 468 ArchiveResource* DocumentLoader::archiveResourceForURL(const KURL& url) 469 { 470 if (!m_archiveResourceCollection) 471 return 0; 472 473 ArchiveResource* resource = m_archiveResourceCollection->archiveResourceForURL(url); 474 475 return resource && !resource->shouldIgnoreWhenUnarchiving() ? resource : 0; 476 } 477 478 PassRefPtr<Archive> DocumentLoader::popArchiveForSubframe(const String& frameName) 479 { 480 return m_archiveResourceCollection ? m_archiveResourceCollection->popSubframeArchive(frameName) : 0; 481 } 482 483 void DocumentLoader::clearArchiveResources() 484 { 485 m_archiveResourceCollection.clear(); 486 } 487 441 488 void DocumentLoader::addResponse(const ResourceResponse& r) 442 489 { -
trunk/WebCore/loader/DocumentLoader.h
r31035 r31281 44 44 namespace WebCore { 45 45 46 class Archive; 47 class ArchiveResource; 48 class ArchiveResourceCollection; 46 49 class CachedPage; 47 50 class Frame; … … 118 121 #endif 119 122 123 void addAllArchiveResources(Archive*); 124 void addArchiveResource(PassRefPtr<ArchiveResource>); 125 ArchiveResource* archiveResourceForURL(const KURL&); 126 PassRefPtr<Archive> popArchiveForSubframe(const String& frameName); 127 void clearArchiveResources(); 128 120 129 void addResponse(const ResourceResponse&); 121 130 const ResponseVector& responses() const { return m_responses; } … … 226 235 ResponseVector m_responses; 227 236 bool m_stopRecordingResponses; 237 238 OwnPtr<ArchiveResourceCollection> m_archiveResourceCollection; 228 239 }; 229 240 -
trunk/WebCore/loader/FrameLoader.cpp
r31228 r31281 31 31 #include "FrameLoader.h" 32 32 33 #include "Archive.h" 34 #include "ArchiveFactory.h" 33 35 #include "CString.h" 34 36 #include "Cache.h" … … 255 257 , m_committedFirstRealDocumentLoad(false) 256 258 , m_didPerformFirstNavigation(false) 259 , m_archiveResourceDeliveryTimer(this, &FrameLoader::archiveResourceDeliveryTimerFired) 257 260 #ifndef NDEBUG 258 261 , m_didDispatchDidCommitLoad(false) … … 302 305 if (m_policyDocumentLoader) 303 306 m_policyDocumentLoader->setDefersLoading(defers); 304 m_client->setDefersLoading(defers); 307 if (!defers) 308 deliverArchivedResourcesAfterDelay(); 305 309 } 306 310 … … 1489 1493 } 1490 1494 1495 void FrameLoader::deliverArchivedResourcesAfterDelay() 1496 { 1497 if (m_pendingArchiveResources.isEmpty()) 1498 return; 1499 if (m_frame->page()->defersLoading()) 1500 return; 1501 if (!m_archiveResourceDeliveryTimer.isActive()) 1502 m_archiveResourceDeliveryTimer.startOneShot(0); 1503 } 1504 1505 void FrameLoader::archiveResourceDeliveryTimerFired(Timer<FrameLoader>*) 1506 { 1507 if (m_pendingArchiveResources.isEmpty()) 1508 return; 1509 if (m_frame->page()->defersLoading()) 1510 return; 1511 1512 ArchiveResourceMap copy; 1513 copy.swap(m_pendingArchiveResources); 1514 1515 ArchiveResourceMap::const_iterator end = copy.end(); 1516 for (ArchiveResourceMap::const_iterator it = copy.begin(); it != end; ++it) { 1517 RefPtr<ResourceLoader> loader = it->first; 1518 ArchiveResource* resource = it->second.get(); 1519 1520 SharedBuffer* data = resource->data(); 1521 1522 loader->didReceiveResponse(resource->response()); 1523 loader->didReceiveData(data->data(), data->size(), data->size(), true); 1524 loader->didFinishLoading(); 1525 } 1526 } 1527 1528 /* 1529 In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree. 1530 The item that was the target of the user's navigation is designated as the "targetItem". 1531 When this method is called with doClip=YES we're able to create the whole tree except for the target's children, 1532 which will be loaded in the future. That part of the tree will be filled out as the child loads are committed. 1533 */ 1534 void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer, Frame* childFrame) 1535 { 1536 ASSERT(childFrame); 1537 HistoryItem* parentItem = currentHistoryItem(); 1538 FrameLoadType loadType = this->loadType(); 1539 FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory; 1540 1541 KURL workingURL = url; 1542 1543 // If we're moving in the backforward list, we might want to replace the content 1544 // of this child frame with whatever was there at that point. 1545 // Reload will maintain the frame contents, LoadSame will not. 1546 if (parentItem && parentItem->children().size() && 1547 (isBackForwardLoadType(loadType) || loadType == FrameLoadTypeReloadAllowingStaleData)) 1548 { 1549 HistoryItem* childItem = parentItem->childItemWithName(childFrame->tree()->name()); 1550 if (childItem) { 1551 // Use the original URL to ensure we get all the side-effects, such as 1552 // onLoad handlers, of any redirects that happened. An example of where 1553 // this is needed is Radar 3213556. 1554 workingURL = KURL(childItem->originalURLString()); 1555 // These behaviors implied by these loadTypes should apply to the child frames 1556 childLoadType = loadType; 1557 1558 if (isBackForwardLoadType(loadType)) { 1559 // For back/forward, remember this item so we can traverse any child items as child frames load 1560 childFrame->loader()->setProvisionalHistoryItem(childItem); 1561 } else { 1562 // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item 1563 childFrame->loader()->setCurrentHistoryItem(childItem); 1564 } 1565 } 1566 } 1567 1568 RefPtr<Archive> subframeArchive = activeDocumentLoader()->popArchiveForSubframe(childFrame->tree()->name()); 1569 1570 if (subframeArchive) 1571 childFrame->loader()->loadArchive(subframeArchive.release()); 1572 else 1573 childFrame->loader()->load(workingURL, referer, childLoadType, String(), 0, 0); 1574 } 1575 1576 void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive) 1577 { 1578 RefPtr<Archive> archive = prpArchive; 1579 1580 ArchiveResource* mainResource = archive->mainResource(); 1581 ASSERT(mainResource); 1582 if (!mainResource) 1583 return; 1584 1585 SubstituteData substituteData(mainResource->data(), mainResource->mimeType(), mainResource->textEncoding(), KURL()); 1586 1587 ResourceRequest request(mainResource->url()); 1588 #if PLATFORM(MAC) 1589 request.applyWebArchiveHackForMail(); 1590 #endif 1591 1592 RefPtr<DocumentLoader> documentLoader = m_client->createDocumentLoader(request, substituteData); 1593 documentLoader->addAllArchiveResources(archive.get()); 1594 load(documentLoader.get()); 1595 } 1596 1491 1597 String FrameLoader::encoding() const 1492 1598 { … … 1934 2040 } 1935 2041 1936 void FrameLoader::finalSetupForReplace(DocumentLoader* loader)1937 {1938 m_client->clearUnarchivingState(loader);1939 }1940 1941 2042 void FrameLoader::load(const KURL& url, Event* event) 1942 2043 { … … 2207 2308 } 2208 2309 2209 bool FrameLoader::willUseArchive(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL) const 2210 { 2211 return m_client->willUseArchive(loader, request, originalURL); 2310 bool FrameLoader::scheduleArchiveLoad(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL) 2311 { 2312 if (request.url() != originalURL) 2313 return false; 2314 2315 DocumentLoader* activeLoader = activeDocumentLoader(); 2316 ASSERT(activeLoader); 2317 if (!activeLoader) 2318 return false; 2319 2320 ArchiveResource* resource = activeLoader->archiveResourceForURL(originalURL); 2321 if (!resource) 2322 return false; 2323 2324 m_pendingArchiveResources.set(loader, resource); 2325 deliverArchivedResourcesAfterDelay(); 2326 2327 return true; 2212 2328 } 2213 2329 … … 2402 2518 if (m_provisionalDocumentLoader) 2403 2519 m_provisionalDocumentLoader->stopLoading(); 2404 if (m_documentLoader) 2520 if (m_documentLoader) { 2405 2521 m_documentLoader->stopLoading(); 2522 m_documentLoader->clearArchiveResources(); 2523 m_archiveResourceDeliveryTimer.stop(); 2524 } 2406 2525 setProvisionalDocumentLoader(0); 2407 m_client->clearArchivedResources();2408 2526 2409 2527 m_inStopAllLoaders = false; … … 2422 2540 void FrameLoader::cancelPendingArchiveLoad(ResourceLoader* loader) 2423 2541 { 2424 m_client->cancelPendingArchiveLoad(loader); 2542 if (m_pendingArchiveResources.isEmpty()) 2543 return; 2544 m_pendingArchiveResources.remove(loader); 2545 if (m_pendingArchiveResources.isEmpty()) 2546 m_archiveResourceDeliveryTimer.stop(); 2425 2547 } 2426 2548 … … 2812 2934 } 2813 2935 2936 #ifndef NDEBUG 2814 2937 bool FrameLoader::isArchiveLoadPending(ResourceLoader* loader) const 2815 2938 { 2816 return m_client->isArchiveLoadPending(loader); 2817 } 2939 return m_pendingArchiveResources.contains(loader); 2940 } 2941 #endif 2818 2942 2819 2943 bool FrameLoader::isHostedByObjectElement() const … … 2858 2982 { 2859 2983 #if PLATFORM(WIN) 2860 if (!m_creatingInitialEmptyDocument) 2984 if (m_creatingInitialEmptyDocument) 2985 return; 2861 2986 #endif 2862 m_client->finishedLoading(loader); 2987 m_client->finishedLoading(loader); 2988 2989 // If loading a webarchive, run through webarchive machinery 2990 const String& responseMIMEType = loader->responseMIMEType(); 2991 if (!ArchiveFactory::isArchiveMimeType(responseMIMEType)) 2992 return; 2993 2994 RefPtr<Archive> archive(ArchiveFactory::create(loader->mainResourceData().get(), responseMIMEType)); 2995 if (!archive) 2996 return; 2997 2998 loader->addAllArchiveResources(archive.get()); 2999 3000 ArchiveResource* mainResource = archive->mainResource(); 3001 continueLoadWithData(mainResource->data(), mainResource->mimeType(), mainResource->textEncoding(), mainResource->url()); 2863 3002 } 2864 3003 -
trunk/WebCore/loader/FrameLoader.h
r31071 r31281 54 54 namespace WebCore { 55 55 56 class Archive; 57 class ArchiveResource; 56 58 class AuthenticationChallenge; 57 59 class CachedPage; … … 141 143 void setupForReplace(); 142 144 void setupForReplaceByMIMEType(const String& newMIMEType); 143 void finalSetupForReplace(DocumentLoader*);144 145 void load(const KURL&, Event*); 145 146 void load(const FrameLoadRequest&, bool lockHistory, bool userGesture, … … 158 159 void load(DocumentLoader*); 159 160 void load(DocumentLoader*, FrameLoadType, PassRefPtr<FormState>); 161 162 void loadURLIntoChildFrame(const KURL&, const String& referer, Frame*); 163 void loadArchive(PassRefPtr<Archive> archive); 160 164 161 165 static bool canLoad(const KURL&, const String& referrer); … … 215 219 ResourceError fileDoesNotExistError(const ResourceResponse&) const; 216 220 ResourceError blockedError(const ResourceRequest&) const; 217 bool willUseArchive(ResourceLoader*, const ResourceRequest&, const KURL&) const; 221 bool scheduleArchiveLoad(ResourceLoader*, const ResourceRequest&, const KURL&); 222 #ifndef NDEBUG 218 223 bool isArchiveLoadPending(ResourceLoader*) const; 224 #endif 219 225 void cannotShowMIMEType(const ResourceResponse&); 220 226 ResourceError interruptionForPolicyChangeError(const ResourceRequest&); … … 461 467 void checkCompletedTimerFired(Timer<FrameLoader>*); 462 468 void checkLoadCompleteTimerFired(Timer<FrameLoader>*); 469 470 void deliverArchivedResourcesAfterDelay(); 471 void archiveResourceDeliveryTimerFired(Timer<FrameLoader>*); 463 472 464 473 void cancelRedirection(bool newLoadInProgress = false); … … 640 649 641 650 bool m_didPerformFirstNavigation; 651 652 typedef HashMap<RefPtr<ResourceLoader>, RefPtr<ArchiveResource> > ArchiveResourceMap; 653 ArchiveResourceMap m_pendingArchiveResources; 654 Timer<FrameLoader> m_archiveResourceDeliveryTimer; 642 655 643 656 #ifndef NDEBUG -
trunk/WebCore/loader/ResourceLoader.cpp
r31204 r31281 116 116 } 117 117 118 if (frameLoader()-> willUseArchive(this, clientRequest, r.url()))118 if (frameLoader()->scheduleArchiveLoad(this, clientRequest, r.url())) 119 119 return true; 120 120 -
trunk/WebCore/loader/archive/Archive.h
r31258 r31281 30 30 #define Archive_h 31 31 32 // FIXME: Code will go here! 32 #include "ArchiveResource.h" 33 34 #include <wtf/PassRefPtr.h> 35 #include <wtf/RefCounted.h> 36 #include <wtf/RefPtr.h> 37 #include <wtf/Vector.h> 38 39 namespace WebCore { 40 41 class Archive : public RefCounted<Archive> { 42 public: 43 ArchiveResource* mainResource() { return m_mainResource.get(); } 44 const Vector<RefPtr<ArchiveResource> >& subresources() const { return m_subresources; } 45 const Vector<RefPtr<Archive> >& subframeArchives() const { return m_subframeArchives; } 46 47 protected: 48 // These methods are meant for subclasses for different archive types to add resources in to the archive, 49 // and should not be exposed as archives should be immutable to clients 50 void setMainResource(PassRefPtr<ArchiveResource> mainResource) { m_mainResource = mainResource; } 51 void addSubresource(PassRefPtr<ArchiveResource> subResource) { m_subresources.append(subResource); } 52 void addSubframeArchive(PassRefPtr<Archive> subframeArchive) { m_subframeArchives.append(subframeArchive); } 53 54 private: 55 RefPtr<ArchiveResource> m_mainResource; 56 Vector<RefPtr<ArchiveResource> > m_subresources; 57 Vector<RefPtr<Archive> > m_subframeArchives; 58 }; 59 60 } 33 61 34 62 #endif // Archive -
trunk/WebCore/loader/archive/ArchiveFactory.cpp
r31258 r31281 30 30 #include "ArchiveFactory.h" 31 31 32 // FIXME: Code will go here! 32 #include "LegacyWebArchive.h" 33 #include "MIMETypeRegistry.h" 34 #include "PlatformString.h" 35 36 #include <wtf/HashMap.h> 37 #include <wtf/HashSet.h> 38 39 namespace WebCore { 40 41 typedef PassRefPtr<Archive> RawDataCreationFunction(SharedBuffer*); 42 43 // The create functions in the archive classes return PassRefPtr to concrete subclasses 44 // of Archive. This adaptor makes the functions have a uniform return type. 45 template <typename ArchiveClass> static PassRefPtr<Archive> archiveFactoryCreate(SharedBuffer* buffer) 46 { 47 return ArchiveClass::create(buffer); 48 } 49 50 static HashMap<String, RawDataCreationFunction*, CaseFoldingHash>& archiveMIMETypes() 51 { 52 static HashMap<String, RawDataCreationFunction*, CaseFoldingHash> mimeTypes; 53 static bool initialized = false; 54 55 if (initialized) 56 return mimeTypes; 57 58 #if PLATFORM(CF) 59 mimeTypes.set("application/x-webarchive", archiveFactoryCreate<LegacyWebArchive>); 60 #endif 61 62 initialized = true; 63 return mimeTypes; 64 } 65 66 bool ArchiveFactory::isArchiveMimeType(const String& mimeType) 67 { 68 return archiveMIMETypes().contains(mimeType); 69 } 70 71 PassRefPtr<Archive> ArchiveFactory::create(SharedBuffer* data, const String& mimeType) 72 { 73 RawDataCreationFunction* function = archiveMIMETypes().get(mimeType); 74 return function ? function(data) : 0; 75 } 76 77 void ArchiveFactory::registerKnownArchiveMIMETypes() 78 { 79 HashSet<String>& mimeTypes = MIMETypeRegistry::getSupportedNonImageMIMETypes(); 80 HashMap<String, RawDataCreationFunction*, CaseFoldingHash>::iterator i = archiveMIMETypes().begin(); 81 HashMap<String, RawDataCreationFunction*, CaseFoldingHash>::iterator end = archiveMIMETypes().end(); 82 83 for (; i != end; ++i) 84 mimeTypes.add(i->first); 85 } 86 87 } -
trunk/WebCore/loader/archive/ArchiveFactory.h
r31258 r31281 30 30 #define ArchiveFactory_h 31 31 32 // FIXME: Code will go here! 32 #include "Archive.h" 33 33 34 #endif // ArchiveFactory 34 #include <wtf/PassRefPtr.h> 35 36 namespace WebCore { 37 38 class SharedBuffer; 39 class String; 40 41 class ArchiveFactory { 42 public: 43 static bool isArchiveMimeType(const String&); 44 static PassRefPtr<Archive> create(SharedBuffer* data, const String& mimeType); 45 static void registerKnownArchiveMIMETypes(); 46 }; 47 48 } 49 50 #endif // ArchiveFactory_h -
trunk/WebCore/loader/archive/ArchiveResource.cpp
r31258 r31281 30 30 #include "ArchiveResource.h" 31 31 32 // FIXME: Code will go here! 32 #include "SharedBuffer.h" 33 34 namespace WebCore { 35 36 PassRefPtr<ArchiveResource> ArchiveResource::create(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName) 37 { 38 return adoptRef(new ArchiveResource(data, url, mimeType, textEncoding, frameName)); 39 } 40 41 PassRefPtr<ArchiveResource> ArchiveResource::create(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse& resourceResponse) 42 { 43 return adoptRef(new ArchiveResource(data, url, mimeType, textEncoding, frameName, resourceResponse)); 44 } 45 46 ArchiveResource::ArchiveResource(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName) 47 : m_data(data) 48 , m_url(url) 49 , m_mimeType(mimeType) 50 , m_textEncoding(textEncoding) 51 , m_frameName(frameName) 52 , m_shouldIgnoreWhenUnarchiving(false) 53 { 54 } 55 56 ArchiveResource::ArchiveResource(PassRefPtr<SharedBuffer> data, const KURL& url, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse& response) 57 : m_data(data) 58 , m_url(url) 59 , m_mimeType(mimeType) 60 , m_textEncoding(textEncoding) 61 , m_frameName(frameName) 62 , m_response(response) 63 , m_shouldIgnoreWhenUnarchiving(false) 64 { 65 } 66 67 const ResourceResponse& ArchiveResource::response() 68 { 69 if (!m_response.isNull()) 70 return m_response; 71 72 m_response = ResourceResponse(m_url, m_mimeType, m_data->size(), m_textEncoding, String()); 73 return m_response; 74 } 75 76 } -
trunk/WebCore/loader/archive/ArchiveResource.h
r31258 r31281 30 30 #define ArchiveResource_h 31 31 32 // FIXME: Code will go here! 32 #include "KURL.h" 33 #include "PlatformString.h" 34 #include "ResourceResponse.h" 35 #include "SharedBuffer.h" 33 36 34 #endif // ArchiveResource 37 #include <wtf/RefCounted.h> 38 39 namespace WebCore { 40 41 class ArchiveResource : public RefCounted<ArchiveResource> { 42 public: 43 static PassRefPtr<ArchiveResource> create(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName); 44 static PassRefPtr<ArchiveResource> create(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse&); 45 46 SharedBuffer* data() { return m_data.get(); } 47 48 const KURL& url() const { return m_url; } 49 const String& mimeType() const { return m_mimeType; } 50 const String& textEncoding() const { return m_textEncoding; } 51 const String& frameName() const { return m_frameName; } 52 const ResourceResponse& response(); 53 54 void ignoreWhenUnarchiving() { m_shouldIgnoreWhenUnarchiving = true; } 55 bool shouldIgnoreWhenUnarchiving() const { return m_shouldIgnoreWhenUnarchiving; } 56 57 private: 58 ArchiveResource(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName); 59 ArchiveResource(PassRefPtr<SharedBuffer>, const KURL&, const String& mimeType, const String& textEncoding, const String& frameName, const ResourceResponse&); 60 61 RefPtr<SharedBuffer> m_data; 62 KURL m_url; 63 String m_mimeType; 64 String m_textEncoding; 65 String m_frameName; 66 67 ResourceResponse m_response; 68 69 bool m_shouldIgnoreWhenUnarchiving; 70 }; 71 72 } 73 74 #endif // ArchiveResource_h -
trunk/WebCore/loader/archive/ArchiveResourceCollection.cpp
r31258 r31281 30 30 #include "ArchiveResourceCollection.h" 31 31 32 // FIXME: Code will go here! 32 namespace WebCore { 33 34 ArchiveResourceCollection::ArchiveResourceCollection() 35 { 36 } 37 38 void ArchiveResourceCollection::addAllResources(Archive* archive) 39 { 40 ASSERT(archive); 41 if (!archive) 42 return; 43 44 const Vector<RefPtr<ArchiveResource> >& subresources = archive->subresources(); 45 Vector<RefPtr<ArchiveResource> >::const_iterator iRes = subresources.begin(); 46 Vector<RefPtr<ArchiveResource> >::const_iterator endRes = subresources.end(); 47 48 for (; iRes != endRes; ++iRes) 49 m_subresources.set((*iRes)->url(), iRes->get()); 50 51 const Vector<RefPtr<Archive> >& subframes = archive->subframeArchives(); 52 Vector<RefPtr<Archive> >::const_iterator iFrame = subframes.begin(); 53 Vector<RefPtr<Archive> >::const_iterator endFrame = subframes.end(); 54 55 for (; iFrame != endFrame; ++iFrame) { 56 ASSERT((*iFrame)->mainResource()); 57 const String& frameName = (*iFrame)->mainResource()->frameName(); 58 if (!frameName.isNull()) 59 m_subframes.set(frameName, iFrame->get()); 60 } 61 } 62 63 // FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on. 64 // Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps? 65 void ArchiveResourceCollection::addResource(PassRefPtr<ArchiveResource> resource) 66 { 67 ASSERT(resource); 68 if (!resource) 69 return; 70 71 const KURL& url = resource->url(); // get before passing PassRefPtr (which sets it to 0) 72 m_subresources.set(url, resource); 73 } 74 75 ArchiveResource* ArchiveResourceCollection::archiveResourceForURL(const KURL& url) 76 { 77 ArchiveResource* resource = m_subresources.get(url).get(); 78 if (!resource) 79 return 0; 80 81 return resource; 82 } 83 84 PassRefPtr<Archive> ArchiveResourceCollection::popSubframeArchive(const String& frameName) 85 { 86 return m_subframes.take(frameName); 87 } 88 89 } -
trunk/WebCore/loader/archive/ArchiveResourceCollection.h
r31258 r31281 30 30 #define ArchiveResourceCollection_h 31 31 32 // FIXME: Code will go here! 32 #include "Archive.h" 33 #include "ArchiveResource.h" 34 #include "KURL.h" 35 #include "PlatformString.h" 33 36 34 #endif // ArchiveResourceCollection 37 #include <wtf/HashMap.h> 38 #include <wtf/RefCounted.h> 39 40 namespace WebCore { 41 42 class ArchiveResourceCollection : Noncopyable { 43 public: 44 ArchiveResourceCollection(); 45 46 void addResource(PassRefPtr<ArchiveResource>); 47 void addAllResources(Archive*); 48 49 ArchiveResource* archiveResourceForURL(const KURL&); 50 PassRefPtr<Archive> popSubframeArchive(const String& frameName); 51 52 private: 53 HashMap<String, RefPtr<ArchiveResource> > m_subresources; 54 HashMap<String, RefPtr<Archive> > m_subframes; 55 }; 56 57 } 58 59 #endif -
trunk/WebCore/loader/archive/cf/LegacyWebArchive.cpp
r31258 r31281 30 30 #include "LegacyWebArchive.h" 31 31 32 // FIXME: Code will go here! 32 #include "KURL.h" 33 #include "Logging.h" 34 #include "SharedBuffer.h" 35 36 #include <wtf/RetainPtr.h> 37 38 namespace WebCore { 39 40 static const CFStringRef LegacyWebArchiveMainResourceKey = CFSTR("WebMainResource"); 41 static const CFStringRef LegacyWebArchiveSubresourcesKey = CFSTR("WebSubresources"); 42 static const CFStringRef LegacyWebArchiveSubframeArchivesKey = CFSTR("WebSubframeArchives"); 43 static const CFStringRef LegacyWebArchiveResourceDataKey = CFSTR("WebResourceData"); 44 static const CFStringRef LegacyWebArchiveResourceFrameNameKey = CFSTR("WebResourceFrameName"); 45 static const CFStringRef LegacyWebArchiveResourceMIMETypeKey = CFSTR("WebResourceMIMEType"); 46 static const CFStringRef LegacyWebArchiveResourceURLKey = CFSTR("WebResourceURL"); 47 static const CFStringRef LegacyWebArchiveResourceTextEncodingNameKey = CFSTR("WebResourceTextEncodingName"); 48 static const CFStringRef LegacyWebArchiveResourceResponseKey = CFSTR("WebResourceResponse"); 49 static const CFStringRef LegacyWebArchiveResourceResponseVersionKey = CFSTR("WebResourceResponseVersion"); 50 51 static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(ArchiveResource* resource, bool mainResource) 52 { 53 if (!resource) { 54 // The property list representation of a null/empty WebResource has the following 3 objects stored as nil 55 RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, 0)); 56 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, 0); 57 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, 0); 58 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, 0); 59 60 return propertyList; 61 } 62 63 RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 6, 0, &kCFTypeDictionaryValueCallBacks)); 64 65 // Resource data can be empty, but must be represented by an empty CFDataRef 66 SharedBuffer* data = resource->data(); 67 RetainPtr<CFDataRef> cfData; 68 if (data) 69 cfData.adoptCF(data->createCFData()); 70 else 71 cfData.adoptCF(CFDataCreate(0, 0, 0)); 72 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, cfData.get()); 73 74 // Resource URL cannot be null 75 RetainPtr<CFStringRef> cfURL(AdoptCF, resource->url().string().createCFString()); 76 if (cfURL) 77 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, cfURL.get()); 78 else { 79 LOG(Archives, "LegacyWebArchive - NULL resource URL is invalid - returning null property list"); 80 return 0; 81 } 82 83 // FrameName should be left out if empty for subresources, but always included for main resources 84 const String& frameName(resource->frameName()); 85 if (!frameName.isEmpty() || mainResource) { 86 RetainPtr<CFStringRef> cfFrameName(AdoptCF, frameName.createCFString()); 87 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceFrameNameKey, cfFrameName.get()); 88 } 89 90 // Set MIMEType, TextEncodingName, and ResourceResponse only if they actually exist 91 const String& mimeType(resource->mimeType()); 92 if (!mimeType.isEmpty()) { 93 RetainPtr<CFStringRef> cfMIMEType(AdoptCF, mimeType.createCFString()); 94 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, cfMIMEType.get()); 95 } 96 97 const String& textEncoding(resource->textEncoding()); 98 if (!textEncoding.isEmpty()) { 99 RetainPtr<CFStringRef> cfTextEncoding(AdoptCF, textEncoding.createCFString()); 100 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceTextEncodingNameKey, cfTextEncoding.get()); 101 } 102 103 // Don't include the resource response for the main resource 104 if (!mainResource) { 105 RetainPtr<CFDataRef> resourceResponseData = propertyListDataFromResourceResponse(resource->response()); 106 if (resourceResponseData) 107 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceResponseKey, resourceResponseData.get()); 108 } 109 110 return propertyList; 111 } 112 113 static RetainPtr<CFDictionaryRef> createPropertyListRep(Archive* archive) 114 { 115 RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, &kCFTypeDictionaryValueCallBacks)); 116 117 RetainPtr<CFDictionaryRef> mainResourceDict = createPropertyListRepresentationFromResource(archive->mainResource(), true); 118 if (!mainResourceDict) 119 return 0; 120 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveMainResourceKey, mainResourceDict.get()); 121 122 RetainPtr<CFMutableArrayRef> subresourcesArray(AdoptCF, CFArrayCreateMutable(0, archive->subresources().size(), &kCFTypeArrayCallBacks)); 123 const Vector<RefPtr<ArchiveResource> >& subresources(archive->subresources()); 124 for (unsigned i = 0; i < subresources.size(); ++i) { 125 RetainPtr<CFDictionaryRef> subresource = createPropertyListRepresentationFromResource(subresources[i].get(), false); 126 if (subresource) 127 CFArrayAppendValue(subresourcesArray.get(), subresource.get()); 128 else 129 LOG(Archives, "LegacyWebArchive - Failed to create property list for subresource"); 130 } 131 if (CFArrayGetCount(subresourcesArray.get())) 132 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveSubresourcesKey, subresourcesArray.get()); 133 134 RetainPtr<CFMutableArrayRef> subframesArray(AdoptCF, CFArrayCreateMutable(0, archive->subframeArchives().size(), &kCFTypeArrayCallBacks)); 135 const Vector<RefPtr<Archive> >& subframeArchives(archive->subframeArchives()); 136 for (unsigned i = 0; i < subframeArchives.size(); ++i) { 137 RetainPtr<CFDictionaryRef> subframeArchive = createPropertyListRep(subframeArchives[i].get()); 138 if (subframeArchive) 139 CFArrayAppendValue(subframesArray.get(), subframeArchive.get()); 140 else 141 LOG(Archives, "LegacyWebArchive - Failed to create property list for subframe archive"); 142 } 143 if (CFArrayGetCount(subframesArray.get())) 144 CFDictionarySetValue(propertyList.get(), LegacyWebArchiveSubframeArchivesKey, subframesArray.get()); 145 146 return propertyList; 147 } 148 149 static ResourceResponse createResourceResponseFromPropertyListData(CFDataRef data, CFStringRef responseDataType) 150 { 151 ASSERT(data); 152 if (!data) 153 return ResourceResponse(); 154 155 // If the ResourceResponseVersion (passed in as responseDataType) exists at all, this is a "new" webarchive that we can parse well in a cross platform manner 156 // If it doesn't exist, we will assume this is an "old" Cocoa-based WebArchive, and parse the ResourceResponse as such 157 if (!responseDataType) 158 return createResourceResponseFromMacArchivedData(data); 159 160 // FIXME: Parse the "new" format that the above comment references here 161 return ResourceResponse(); 162 } 163 164 static PassRefPtr<ArchiveResource> createResource(CFDictionaryRef dictionary) 165 { 166 ASSERT(dictionary); 167 if (!dictionary) 168 return 0; 169 170 CFDataRef resourceData = static_cast<CFDataRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceDataKey)); 171 if (resourceData && CFGetTypeID(resourceData) != CFDataGetTypeID()) { 172 LOG(Archives, "LegacyWebArchive - Resource data is not of type CFData, cannot create invalid resource"); 173 return 0; 174 } 175 176 CFStringRef frameName = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceFrameNameKey)); 177 if (frameName && CFGetTypeID(frameName) != CFStringGetTypeID()) { 178 LOG(Archives, "LegacyWebArchive - Frame name is not of type CFString, cannot create invalid resource"); 179 return 0; 180 } 181 182 CFStringRef mimeType = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceMIMETypeKey)); 183 if (mimeType && CFGetTypeID(mimeType) != CFStringGetTypeID()) { 184 LOG(Archives, "LegacyWebArchive - MIME type is not of type CFString, cannot create invalid resource"); 185 return 0; 186 } 187 188 CFStringRef url = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceURLKey)); 189 if (url && CFGetTypeID(url) != CFStringGetTypeID()) { 190 LOG(Archives, "LegacyWebArchive - URL is not of type CFString, cannot create invalid resource"); 191 return 0; 192 } 193 194 CFStringRef textEncoding = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceTextEncodingNameKey)); 195 if (textEncoding && CFGetTypeID(textEncoding) != CFStringGetTypeID()) { 196 LOG(Archives, "LegacyWebArchive - Text encoding is not of type CFString, cannot create invalid resource"); 197 return 0; 198 } 199 200 ResourceResponse response; 201 202 CFDataRef resourceResponseData = static_cast<CFDataRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceResponseKey)); 203 if (resourceResponseData) { 204 if (CFGetTypeID(resourceResponseData) != CFDataGetTypeID()) { 205 LOG(Archives, "LegacyWebArchive - Resource response data is not of type CFData, cannot create invalid resource"); 206 return 0; 207 } 208 209 CFStringRef resourceResponseVersion = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceResponseVersionKey)); 210 if (resourceResponseVersion && CFGetTypeID(resourceResponseVersion) != CFStringGetTypeID()) { 211 LOG(Archives, "LegacyWebArchive - Resource response version is not of type CFString, cannot create invalid resource"); 212 return 0; 213 } 214 215 response = createResourceResponseFromPropertyListData(resourceResponseData, resourceResponseVersion); 216 } 217 218 return ArchiveResource::create(SharedBuffer::create(CFDataGetBytePtr(resourceData), CFDataGetLength(resourceData)), KURL(url), mimeType, textEncoding, frameName, response); 219 } 220 221 PassRefPtr<LegacyWebArchive> LegacyWebArchive::create() 222 { 223 return adoptRef(new LegacyWebArchive); 224 } 225 226 PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(SharedBuffer* data) 227 { 228 LOG(Archives, "LegacyWebArchive - Creating from raw data"); 229 230 RefPtr<LegacyWebArchive> archive = create(); 231 if (!archive->init(data)) 232 return 0; 233 234 return archive.release(); 235 } 236 237 PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives) 238 { 239 ASSERT(mainResource); 240 if (!mainResource) 241 return 0; 242 243 RefPtr<LegacyWebArchive> archive = create(); 244 archive->setMainResource(mainResource); 245 246 for (unsigned i = 0; i < subresources.size(); ++i) 247 archive->addSubresource(subresources[i]); 248 249 for (unsigned i = 0; i < subframeArchives.size(); ++i) 250 archive->addSubframeArchive(subframeArchives[i]); 251 252 return archive.release(); 253 } 254 255 LegacyWebArchive::LegacyWebArchive() 256 { 257 } 258 259 bool LegacyWebArchive::init(SharedBuffer* data) 260 { 261 ASSERT(data); 262 if (!data) 263 return false; 264 265 RetainPtr<CFDataRef> cfData(AdoptCF, data->createCFData()); 266 if (!cfData) 267 return false; 268 269 CFStringRef errorString = 0; 270 271 RetainPtr<CFDictionaryRef> plist(AdoptCF, static_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(0, cfData.get(), kCFPropertyListImmutable, &errorString))); 272 if (!plist) { 273 #ifndef NDEBUG 274 const char* cError = errorString ? CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8) : "unknown error"; 275 LOG(Archives, "LegacyWebArchive - Error parsing PropertyList from archive data - %s", cError); 276 #endif 277 if (errorString) 278 CFRelease(errorString); 279 return false; 280 } 281 282 if (CFGetTypeID(plist.get()) != CFDictionaryGetTypeID()) { 283 LOG(Archives, "LegacyWebArchive - Archive property list is not the expected CFDictionary, aborting invalid WebArchive"); 284 return false; 285 } 286 287 return extract(plist.get()); 288 } 289 290 bool LegacyWebArchive::extract(CFDictionaryRef dictionary) 291 { 292 ASSERT(dictionary); 293 if (!dictionary) { 294 LOG(Archives, "LegacyWebArchive - Null root CFDictionary, aborting invalid WebArchive"); 295 return false; 296 } 297 298 CFDictionaryRef mainResourceDict = static_cast<CFDictionaryRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveMainResourceKey)); 299 if (!mainResourceDict) { 300 LOG(Archives, "LegacyWebArchive - No main resource in archive, aborting invalid WebArchive"); 301 return false; 302 } 303 if (CFGetTypeID(mainResourceDict) != CFDictionaryGetTypeID()) { 304 LOG(Archives, "LegacyWebArchive - Main resource is not the expected CFDictionary, aborting invalid WebArchive"); 305 return false; 306 } 307 308 setMainResource(createResource(mainResourceDict)); 309 if (!mainResource()) { 310 LOG(Archives, "LegacyWebArchive - Failed to parse main resource from CFDictionary or main resource does not exist, aborting invalid WebArchive"); 311 return false; 312 } 313 314 CFArrayRef subresourceArray = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveSubresourcesKey)); 315 if (subresourceArray && CFGetTypeID(subresourceArray) != CFArrayGetTypeID()) { 316 LOG(Archives, "LegacyWebArchive - Subresources is not the expected Array, aborting invalid WebArchive"); 317 return false; 318 } 319 320 if (subresourceArray) { 321 CFIndex count = CFArrayGetCount(subresourceArray); 322 for (CFIndex i = 0; i < count; ++i) { 323 CFDictionaryRef subresourceDict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(subresourceArray, i)); 324 if (CFGetTypeID(subresourceDict) != CFDictionaryGetTypeID()) { 325 LOG(Archives, "LegacyWebArchive - Subresource is not expected CFDictionary, aborting invalid WebArchive"); 326 return false; 327 } 328 addSubresource(createResource(subresourceDict)); 329 } 330 } 331 332 CFArrayRef subframeArray = static_cast<CFArrayRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveSubframeArchivesKey)); 333 if (subframeArray && CFGetTypeID(subframeArray) != CFArrayGetTypeID()) { 334 LOG(Archives, "LegacyWebArchive - Subframe archives is not the expected Array, aborting invalid WebArchive"); 335 return false; 336 } 337 338 if (subframeArray) { 339 CFIndex count = CFArrayGetCount(subframeArray); 340 for (CFIndex i = 0; i < count; ++i) { 341 CFDictionaryRef subframeDict = static_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(subframeArray, i)); 342 if (CFGetTypeID(subframeDict) != CFDictionaryGetTypeID()) { 343 LOG(Archives, "LegacyWebArchive - Subframe array is not expected CFDictionary, aborting invalid WebArchive"); 344 return false; 345 } 346 347 RefPtr<LegacyWebArchive> subframeArchive = create(); 348 if (subframeArchive->extract(subframeDict)) 349 addSubframeArchive(subframeArchive.release()); 350 else 351 LOG(Archives, "LegacyWebArchive - Invalid subframe archive skipped"); 352 } 353 } 354 355 return true; 356 } 357 358 RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation() 359 { 360 RetainPtr<CFDictionaryRef> propertyList = createPropertyListRep(this); 361 if (!propertyList) { 362 LOG(Archives, "LegacyWebArchive - Failed to create property list for archive, returning no data"); 363 return 0; 364 } 365 366 // FIXME: On Mac, WebArchives have been written out as Binary Property Lists until this change. 367 // Unless we jump through CFWriteStream hoops, they'll now be textual XML data. Is this okay? 368 RetainPtr<CFDataRef> plistData(AdoptCF, CFPropertyListCreateXMLData(0, propertyList.get())); 369 if (!plistData) { 370 LOG(Archives, "LegacyWebArchive - Failed to convert property list into raw data, returning no data"); 371 return 0; 372 } 373 374 return plistData; 375 } 376 377 #if !PLATFORM(MAC) 378 // FIXME: Is it possible to parse in a Cocoa-style resource response manually, 379 // without NSKeyed(Un)Archiver, manipulating plists directly? 380 // If so, the code that does it will go here. 381 // In the meantime, Mac will continue to NSKeyed(Un)Archive the response as it always has 382 ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef responseData) 383 { 384 return ResourceResponse(); 385 } 386 387 RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse& response) 388 { 389 // FIXME: Write out the "new" format described in ::createResourceResponseFromPropertyListData() up above 390 return 0; 391 } 392 #endif 393 394 } -
trunk/WebCore/loader/archive/cf/LegacyWebArchive.h
r31258 r31281 30 30 #define LegacyWebArchive_h 31 31 32 // FIXME: Code will go here! 32 #include "Archive.h" 33 34 #include <wtf/PassRefPtr.h> 35 36 namespace WebCore { 37 38 class LegacyWebArchive : public Archive { 39 public: 40 static PassRefPtr<LegacyWebArchive> create(); 41 static PassRefPtr<LegacyWebArchive> create(SharedBuffer*); 42 static PassRefPtr<LegacyWebArchive> create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives); 43 44 RetainPtr<CFDataRef> rawDataRepresentation(); 45 46 private: 47 LegacyWebArchive(); 48 bool init(SharedBuffer*); 49 bool extract(CFDictionaryRef); 50 51 }; 52 53 ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef); 54 RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse&); 55 56 } 33 57 34 58 #endif // Archive -
trunk/WebCore/loader/archive/cf/LegacyWebArchiveMac.mm
r31258 r31281 30 30 #include "LegacyWebArchive.h" 31 31 32 // FIXME: Code will go here! 32 namespace WebCore { 33 34 static const NSString *LegacyWebArchiveResourceResponseKey = @"WebResourceResponse"; 35 36 // FIXME: Is it possible to parse in a Cocoa-style resource response manually, 37 // without NSKeyed(Un)Archiver, manipulating plists directly? 38 ResourceResponse createResourceResponseFromMacArchivedData(CFDataRef responseData) 39 { 40 ASSERT(responseData); 41 if (!responseData) 42 return ResourceResponse(); 43 44 NSURLResponse *response; 45 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)responseData]; 46 @try { 47 id responseObject = [unarchiver decodeObjectForKey:LegacyWebArchiveResourceResponseKey]; 48 if ([responseObject isKindOfClass:[NSURLResponse class]]) 49 response = responseObject; 50 [unarchiver finishDecoding]; 51 } @catch(id) { 52 response = nil; 53 } 54 [unarchiver release]; 55 56 return ResourceResponse(response); 57 } 58 59 RetainPtr<CFDataRef> propertyListDataFromResourceResponse(const ResourceResponse& response) 60 { 61 NSURLResponse *nsResponse = response.nsURLResponse(); 62 if (!nsResponse) 63 return 0; 64 65 NSMutableData *responseData = (NSMutableData *)CFDataCreateMutable(0, 0); 66 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData]; 67 [archiver encodeObject:nsResponse forKey:LegacyWebArchiveResourceResponseKey]; 68 [archiver finishEncoding]; 69 [archiver release]; 70 71 return RetainPtr<CFDataRef>(AdoptCF, (CFDataRef)responseData); 72 } 73 74 } -
trunk/WebCore/platform/network/mac/ResourceRequest.h
r30243 r31281 67 67 , m_nsRequest(nsRequest) { } 68 68 69 void applyWebArchiveHackForMail(); 69 70 NSURLRequest* nsURLRequest() const; 70 71 -
trunk/WebCore/platform/network/mac/ResourceRequestMac.mm
r30661 r31281 102 102 } 103 103 104 void ResourceRequest::applyWebArchiveHackForMail() 105 { 106 // Hack because Mail checks for this property to detect data / archive loads 107 [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)nsURLRequest()]; 104 108 } 109 110 } -
trunk/WebKit/ChangeLog
r31258 r31281 1 2008-03-25 Brady Eidson <beidson@apple.com> 2 3 Reviewed by Darin 4 5 <rdar://problem/4516169> - Support WebArchives on Windows 6 7 * WebKit.xcodeproj/project.pbxproj: 8 1 9 2008-03-24 Brady Eidson <beidson@apple.com> 2 10 -
trunk/WebKit/WebKit.xcodeproj/project.pbxproj
r31258 r31281 64 64 5DF7B1D10D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DF7B1CF0D161FCF0062CD32 /* WebNetscapePlugInStreamLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; }; 65 65 5DF7B1D20D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5DF7B1D00D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.mm */; }; 66 650F74E409E488F70020118A /* WebUnarchivingState.h in Headers */ = {isa = PBXBuildFile; fileRef = 650F74E209E488F70020118A /* WebUnarchivingState.h */; };67 650F74E509E488F70020118A /* WebUnarchivingState.m in Sources */ = {isa = PBXBuildFile; fileRef = 650F74E309E488F70020118A /* WebUnarchivingState.m */; };68 66 65488DA1084FBCCB00831AD0 /* WebNSDictionaryExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 65488D9F084FBCCB00831AD0 /* WebNSDictionaryExtras.h */; }; 69 67 65488DA2084FBCCB00831AD0 /* WebNSDictionaryExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = 65488DA0084FBCCB00831AD0 /* WebNSDictionaryExtras.m */; }; … … 424 422 5DF7B1CF0D161FCF0062CD32 /* WebNetscapePlugInStreamLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebNetscapePlugInStreamLoaderClient.h; sourceTree = "<group>"; }; 425 423 5DF7B1D00D161FD00062CD32 /* WebNetscapePlugInStreamLoaderClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebNetscapePlugInStreamLoaderClient.mm; sourceTree = "<group>"; }; 426 650F74E209E488F70020118A /* WebUnarchivingState.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebUnarchivingState.h; sourceTree = "<group>"; };427 650F74E309E488F70020118A /* WebUnarchivingState.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WebUnarchivingState.m; sourceTree = "<group>"; };428 424 65488D9F084FBCCB00831AD0 /* WebNSDictionaryExtras.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSDictionaryExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; 429 425 65488DA0084FBCCB00831AD0 /* WebNSDictionaryExtras.m */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebNSDictionaryExtras.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; }; … … 977 973 515E27CC0458C86500CA2D3A /* WebUIDelegate.h */, 978 974 65A7D44A0568AB2600E70EF6 /* WebUIDelegatePrivate.h */, 979 650F74E209E488F70020118A /* WebUnarchivingState.h */,980 975 51A8B579042834F700CA2D3A /* WebView.h */, 981 976 930D02BB06275F640076701E /* WebViewInternal.h */, … … 994 989 84311A1305EAAAF00088EDA4 /* WebResource.mm */, 995 990 7E6FEF0608985A7200C44C3F /* WebScriptDebugDelegate.mm */, 996 650F74E309E488F70020118A /* WebUnarchivingState.m */,997 991 51A8B57A042834F700CA2D3A /* WebView.mm */, 998 992 ); … … 1313 1307 939810830824BF01008DF038 /* WebUIDelegatePrivate.h in Headers */, 1314 1308 939810150824BF01008DF038 /* WebURLsWithTitles.h in Headers */, 1315 650F74E409E488F70020118A /* WebUnarchivingState.h in Headers */,1316 1309 939810700824BF01008DF038 /* WebView.h in Headers */, 1317 1310 939810460824BF01008DF038 /* WebViewFactory.h in Headers */, … … 1603 1596 93EB178D09F88D460091F8FF /* WebSystemInterface.m in Sources */, 1604 1597 939810BE0824BF01008DF038 /* WebURLsWithTitles.m in Sources */, 1605 650F74E509E488F70020118A /* WebUnarchivingState.m in Sources */,1606 1598 939811070824BF01008DF038 /* WebView.mm in Sources */, 1607 1599 939810E80824BF01008DF038 /* WebViewFactory.mm in Sources */, -
trunk/WebKit/mac/ChangeLog
r31274 r31281 1 2008-03-25 Brady Eidson <beidson@apple.com> 2 3 Reviewed by Darin 4 5 <rdar://problem/4516169> - Support WebArchives on Windows 6 And paves the way for many future WebArchive bug fixes and enhancements 7 8 This change moves most of the real workhorse code about WebArchives into WebCore. It maintains 9 1-to-1 relationships between a few objects in WebCore and WebKit. Such as: 10 * WebArchive <-> LegacyWebArchive 11 * WebResource <-> ArchiveResource 12 * WebUnarchivingState <-> ArchiveResourceCollection 13 14 The other biggest changes involve many FrameLoaderClient methods that existed soley for WebArchives 15 and now exist in WebCore 16 17 * WebCoreSupport/WebFrameLoaderClient.mm: 18 (WebFrameLoaderClient::clearUnarchivingState): Emptied - to be removed in a followup patch 19 (WebFrameLoaderClient::finalSetupForReplace): 20 (WebFrameLoaderClient::setDefersLoading): 21 (WebFrameLoaderClient::willUseArchive): 22 (WebFrameLoaderClient::isArchiveLoadPending): 23 (WebFrameLoaderClient::cancelPendingArchiveLoad): 24 (WebFrameLoaderClient::clearArchivedResources): 25 (WebFrameLoaderClient::createFrame): 26 27 * WebView/WebArchive.mm: 28 (+[WebArchivePrivate initialize]): 29 (-[WebArchivePrivate init]): 30 (-[WebArchivePrivate initWithCoreArchive:]): 31 (-[WebArchivePrivate coreArchive]): 32 (-[WebArchivePrivate setCoreArchive:]): 33 (-[WebArchivePrivate dealloc]): 34 (-[WebArchivePrivate finalize]): 35 (-[WebArchive init]): 36 (-[WebArchive initWithMainResource:subresources:subframeArchives:]): 37 (-[WebArchive initWithData:]): 38 (-[WebArchive initWithCoder:]): 39 (-[WebArchive encodeWithCoder:]): 40 (-[WebArchive mainResource]): 41 (-[WebArchive subresources]): 42 (-[WebArchive subframeArchives]): 43 (-[WebArchive data]): 44 (-[WebArchive _initWithCoreLegacyWebArchive:WebCore::]): 45 (-[WebArchive WebCore::]): 46 * WebView/WebArchiveInternal.h: Added. 47 48 * WebView/WebDataSource.mm: 49 (-[WebDataSourcePrivate dealloc]): 50 (-[WebDataSource _addSubframeArchives:]): 51 (-[WebDataSource _documentFragmentWithArchive:]): 52 (-[WebDataSource subresourceForURL:]): 53 (-[WebDataSource addSubresource:]): 54 * WebView/WebDataSourceInternal.h: 55 56 * WebView/WebFrame.mm: 57 (-[WebFrame loadArchive:]): 58 * WebView/WebFrameInternal.h: 59 60 * WebView/WebHTMLRepresentation.mm: 61 (-[WebHTMLRepresentation finishedLoadingWithDataSource:]): 62 63 * WebView/WebResource.mm: 64 (+[WebResourcePrivate initialize]): 65 (-[WebResourcePrivate init]): 66 (-[WebResourcePrivate initWithCoreResource:]): 67 (-[WebResourcePrivate dealloc]): 68 (-[WebResourcePrivate finalize]): 69 (-[WebResource initWithCoder:]): 70 (-[WebResource encodeWithCoder:]): 71 (-[WebResource data]): 72 (-[WebResource URL]): 73 (-[WebResource MIMEType]): 74 (-[WebResource textEncodingName]): 75 (-[WebResource frameName]): 76 (-[WebResource _initWithCoreResource:WebCore::]): 77 (-[WebResource WebCore::]): 78 (-[WebResource _ignoreWhenUnarchiving]): 79 (-[WebResource _initWithData:URL:MIMEType:textEncodingName:frameName:response:copyData:]): 80 (-[WebResource _fileWrapperRepresentation]): 81 (-[WebResource _response]): 82 (-[WebResource _stringValue]): 83 * WebView/WebResourceInternal.h: Added. 84 * WebView/WebResourcePrivate.h: 85 86 * WebView/WebUnarchivingState.h: Removed. 87 * WebView/WebUnarchivingState.m: Removed. 88 1 89 2008-03-24 Oliver Hunt <oliver@apple.com> 2 90 -
trunk/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm
r31056 r31281 655 655 void WebFrameLoaderClient::clearUnarchivingState(DocumentLoader* loader) 656 656 { 657 [dataSource(loader) _clearUnarchivingState];658 657 } 659 658 … … 722 721 void WebFrameLoaderClient::finalSetupForReplace(DocumentLoader* loader) 723 722 { 724 [dataSource(loader) _clearUnarchivingState];725 723 } 726 724 … … 780 778 void WebFrameLoaderClient::setDefersLoading(bool defers) 781 779 { 782 if (!defers)783 deliverArchivedResourcesAfterDelay();784 780 } 785 781 786 782 bool WebFrameLoaderClient::willUseArchive(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL) const 787 783 { 788 if (request.url() != originalURL) 789 return false; 790 791 WebResource *resource = [dataSource(core(m_webFrame.get())->loader()->activeDocumentLoader()) _archivedSubresourceForURL:originalURL]; 792 if (!resource) 793 return false; 794 795 m_pendingArchivedResources.set(loader, resource); 796 // Deliver the resource after a delay because callers don't expect to receive callbacks while calling this method. 797 deliverArchivedResourcesAfterDelay(); 798 799 return true; 784 return false; 800 785 } 801 786 802 787 bool WebFrameLoaderClient::isArchiveLoadPending(ResourceLoader* loader) const 803 788 { 804 return m_pendingArchivedResources.contains(loader);789 return false; 805 790 } 806 791 807 792 void WebFrameLoaderClient::cancelPendingArchiveLoad(ResourceLoader* loader) 808 793 { 809 if (m_pendingArchivedResources.isEmpty())810 return;811 m_pendingArchivedResources.remove(loader);812 if (m_pendingArchivedResources.isEmpty())813 m_archivedResourcesDeliveryTimer.stop();814 794 } 815 795 816 796 void WebFrameLoaderClient::clearArchivedResources() 817 797 { 818 m_pendingArchivedResources.clear();819 m_archivedResourcesDeliveryTimer.stop();820 798 } 821 799 … … 1148 1126 [[newFrame _dataSource] _documentLoader]->setOverrideEncoding([[m_webFrame.get() _dataSource] _documentLoader]->overrideEncoding()); 1149 1127 1150 [m_webFrame.get() _loadURL:url referrer:referrer intoChild:newFrame];1128 core(m_webFrame.get())->loader()->loadURLIntoChildFrame(url, referrer, newCoreFrame.get()); 1151 1129 1152 1130 // The frame's onload handler may have removed it from the document. -
trunk/WebKit/mac/WebView/WebArchive.mm
r31258 r31281 28 28 29 29 #import "WebArchive.h" 30 #import "WebArchiveInternal.h" 30 31 31 32 #import "WebKitLogging.h" 33 #import "WebResourceInternal.h" 32 34 #import "WebResourcePrivate.h" 33 35 #import "WebTypesInternal.h" 36 37 #import <WebCore/ArchiveResource.h> 38 #import <WebCore/LegacyWebArchive.h> 39 #import <WebCore/WebCoreObjCExtras.h> 40 41 using namespace WebCore; 34 42 35 43 NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type"; … … 41 49 @interface WebArchivePrivate : NSObject 42 50 { 43 @public 44 WebResource *mainResource; 45 NSArray *subresources; 46 NSArray *subframeArchives; 47 } 51 @public 52 WebResource *cachedMainResource; 53 NSArray *cachedSubresources; 54 NSArray *cachedSubframeArchives; 55 @private 56 LegacyWebArchive* coreArchive; 57 } 58 59 - (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)coreArchive; 60 - (LegacyWebArchive*)coreArchive; 61 - (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive; 48 62 @end 49 63 50 64 @implementation WebArchivePrivate 51 65 66 #ifndef BUILDING_ON_TIGER 67 + (void)initialize 68 { 69 WebCoreObjCFinalizeOnMainThread(self); 70 } 71 #endif 72 73 - (id)init 74 { 75 self = [super init]; 76 if (self) 77 coreArchive = LegacyWebArchive::create().releaseRef(); 78 return self; 79 } 80 81 - (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)_coreArchive 82 { 83 self = [super init]; 84 if (!self || !_coreArchive) { 85 [self release]; 86 return nil; 87 } 88 89 coreArchive = _coreArchive.releaseRef(); 90 91 return self; 92 } 93 94 - (LegacyWebArchive*)coreArchive 95 { 96 return coreArchive; 97 } 98 99 - (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive 100 { 101 ASSERT(coreArchive); 102 ASSERT(newCoreArchive); 103 coreArchive = newCoreArchive.releaseRef(); 104 } 105 52 106 - (void)dealloc 53 107 { 54 [mainResource release]; 55 [subresources release]; 56 [subframeArchives release]; 108 ASSERT(coreArchive); 109 coreArchive->deref(); 110 coreArchive = 0; 111 112 [cachedMainResource release]; 113 [cachedSubresources release]; 114 [cachedSubframeArchives release]; 115 57 116 [super dealloc]; 58 117 } 59 118 119 - (void)finalize 120 { 121 ASSERT(coreArchive); 122 coreArchive->deref(); 123 coreArchive = 0; 124 125 [super finalize]; 126 } 127 60 128 @end 129 130 @implementation WebArchive 131 132 - (id)init 133 { 134 self = [super init]; 135 if (!self) 136 return nil; 137 _private = [[WebArchivePrivate alloc] init]; 138 return self; 139 } 61 140 62 141 static BOOL isArrayOfClass(id object, Class elementClass) … … 72 151 } 73 152 74 @implementation WebArchive 75 76 - (id)init 153 - (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives 77 154 { 78 155 self = [super init]; 79 156 if (!self) 80 157 return nil; 158 81 159 _private = [[WebArchivePrivate alloc] init]; 82 return self; 83 } 84 85 - (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives 86 { 87 self = [self init]; 160 161 _private->cachedMainResource = [mainResource retain]; 162 if (!_private->cachedMainResource) { 163 [self release]; 164 return nil; 165 } 166 167 if (!subresources || isArrayOfClass(subresources, [WebResource class])) 168 _private->cachedSubresources = [subresources retain]; 169 else { 170 [self release]; 171 return nil; 172 } 173 174 if (!subframeArchives || isArrayOfClass(subframeArchives, [WebArchive class])) 175 _private->cachedSubframeArchives = [subframeArchives retain]; 176 else { 177 [self release]; 178 return nil; 179 } 180 181 RefPtr<ArchiveResource> coreMainResource = mainResource ? [mainResource _coreResource] : 0; 182 183 Vector<PassRefPtr<ArchiveResource> > coreResources; 184 NSEnumerator *enumerator = [subresources objectEnumerator]; 185 WebResource *subresource; 186 while ((subresource = [enumerator nextObject]) != nil) 187 coreResources.append([subresource _coreResource]); 188 189 Vector<PassRefPtr<LegacyWebArchive> > coreArchives; 190 enumerator = [subframeArchives objectEnumerator]; 191 WebArchive *subframeArchive; 192 while ((subframeArchive = [enumerator nextObject]) != nil) 193 coreArchives.append([subframeArchive->_private coreArchive]); 194 195 [_private setCoreArchive:LegacyWebArchive::create(coreMainResource.release(), coreResources, coreArchives)]; 196 if (![_private coreArchive]) { 197 [self release]; 198 return nil; 199 } 200 201 return self; 202 } 203 204 - (id)initWithData:(NSData *)data 205 { 206 self = [super init]; 88 207 if (!self) 89 208 return nil; 90 91 _private->mainResource = [mainResource retain]; 92 _private->subresources = [subresources retain]; 93 _private->subframeArchives = [subframeArchives retain]; 94 95 if (!_private->mainResource) { 96 [self release]; 97 return nil; 98 } 99 100 return self; 101 } 102 103 - (id)_initWithPropertyList:(id)propertyList 104 { 105 self = [self init]; 106 if (!self) 107 return nil; 108 109 if (![propertyList isKindOfClass:[NSDictionary class]]) { 110 [self release]; 111 return nil; 112 } 113 114 _private->mainResource = [[WebResource alloc] _initWithPropertyList:[propertyList objectForKey:WebMainResourceKey]]; 115 if (!_private->mainResource) { 116 [self release]; 117 return nil; 118 } 119 120 _private->subresources = [[WebResource _resourcesFromPropertyLists:[propertyList objectForKey:WebSubresourcesKey]] retain]; 121 122 NSEnumerator *enumerator = [[propertyList objectForKey:WebSubframeArchivesKey] objectEnumerator]; 123 NSMutableArray *subframeArchives = [[NSMutableArray alloc] init]; 124 NSDictionary *archivePropertyList; 125 while ((archivePropertyList = [enumerator nextObject]) != nil) { 126 WebArchive *archive = [[WebArchive alloc] _initWithPropertyList:archivePropertyList]; 127 if (archive) { 128 [subframeArchives addObject:archive]; 129 [archive release]; 130 } 131 } 132 _private->subframeArchives = subframeArchives; 133 134 return self; 135 } 136 137 - (id)initWithData:(NSData *)data 138 { 209 139 210 #if !LOG_DISABLED 140 211 CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); 141 212 #endif 142 NSDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:data 143 mutabilityOption:NSPropertyListImmutable144 format:nil145 errorDescription:nil];213 214 _private = [[WebArchivePrivate alloc] init]; 215 [_private setCoreArchive:LegacyWebArchive::create(SharedBuffer::wrapNSData(data).get())]; 216 146 217 #if !LOG_DISABLED 147 218 CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); … … 150 221 LOG(Timing, "Parsing web archive with [NSPropertyListSerialization propertyListFromData::::] took %f seconds", duration); 151 222 152 return [self _initWithPropertyList:propertyList];223 return self; 153 224 } 154 225 155 226 - (id)initWithCoder:(NSCoder *)decoder 156 227 { 157 self = [self init];158 if (!self)159 returnnil;160 228 WebResource *mainResource = nil; 229 NSArray *subresources = nil; 230 NSArray *subframeArchives = nil; 231 161 232 @try { 162 233 id object = [decoder decodeObjectForKey:WebMainResourceKey]; 163 234 if ([object isKindOfClass:[WebResource class]]) 164 _private->mainResource = [object retain];235 mainResource = [object retain]; 165 236 object = [decoder decodeObjectForKey:WebSubresourcesKey]; 166 237 if (isArrayOfClass(object, [WebResource class])) 167 _private->subresources = [object retain];238 subresources = [object retain]; 168 239 object = [decoder decodeObjectForKey:WebSubframeArchivesKey]; 169 240 if (isArrayOfClass(object, [WebArchive class])) 170 _private->subframeArchives = [object retain];241 subframeArchives = [object retain]; 171 242 } @catch(id) { 172 243 [self release]; … … 174 245 } 175 246 176 if (!_private->mainResource) { 177 [self release]; 178 return nil; 179 } 180 181 return self; 247 return [self initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives]; 182 248 } 183 249 184 250 - (void)encodeWithCoder:(NSCoder *)encoder 185 251 { 186 [encoder encodeObject: _private->mainResourceforKey:WebMainResourceKey];187 [encoder encodeObject: _private->subresourcesforKey:WebSubresourcesKey];188 [encoder encodeObject: _private->subframeArchivesforKey:WebSubframeArchivesKey];252 [encoder encodeObject:[self mainResource] forKey:WebMainResourceKey]; 253 [encoder encodeObject:[self subresources] forKey:WebSubresourcesKey]; 254 [encoder encodeObject:[self subframeArchives] forKey:WebSubframeArchivesKey]; 189 255 } 190 256 … … 202 268 - (WebResource *)mainResource 203 269 { 204 return [[_private->mainResource retain] autorelease]; 270 // Currently from WebKit API perspective, WebArchives are entirely immutable once created 271 // If they ever become mutable, we'll need to rethink this. 272 if (!_private->cachedMainResource) { 273 LegacyWebArchive* coreArchive = [_private coreArchive]; 274 if (coreArchive) 275 _private->cachedMainResource = [[WebResource alloc] _initWithCoreResource:coreArchive->mainResource()]; 276 } 277 278 return [[_private->cachedMainResource retain] autorelease]; 205 279 } 206 280 207 281 - (NSArray *)subresources 208 282 { 209 return [[_private->subresources retain] autorelease]; 283 // Currently from WebKit API perspective, WebArchives are entirely immutable once created 284 // If they ever become mutable, we'll need to rethink this. 285 if (!_private->cachedSubresources) { 286 LegacyWebArchive* coreArchive = [_private coreArchive]; 287 if (!coreArchive) 288 _private->cachedSubresources = [[NSArray alloc] init]; 289 else { 290 const Vector<RefPtr<ArchiveResource> >& subresources(coreArchive->subresources()); 291 NSMutableArray *mutableArray = _private->cachedSubresources = [[NSMutableArray alloc] initWithCapacity:subresources.size()]; 292 for (unsigned i = 0; i < subresources.size(); ++i) { 293 WebResource *resource = [[WebResource alloc] _initWithCoreResource:subresources[i].get()]; 294 [mutableArray addObject:resource]; 295 [resource release]; 296 } 297 } 298 } 299 300 return [[_private->cachedSubresources retain] autorelease]; 210 301 } 211 302 212 303 - (NSArray *)subframeArchives 213 304 { 214 return [[_private->subframeArchives retain] autorelease]; 215 } 216 217 - (NSDictionary *)_propertyListRepresentation 218 { 219 NSMutableDictionary *propertyList = [NSMutableDictionary dictionary]; 220 if (_private->mainResource) { 221 [propertyList setObject:[_private->mainResource _propertyListRepresentation] forKey:WebMainResourceKey]; 222 } 223 NSArray *propertyLists = [WebResource _propertyListsFromResources:_private->subresources]; 224 if ([propertyLists count] > 0) { 225 [propertyList setObject:propertyLists forKey:WebSubresourcesKey]; 226 } 227 NSEnumerator *enumerator = [_private->subframeArchives objectEnumerator]; 228 NSMutableArray *subarchivePropertyLists = [[NSMutableArray alloc] init]; 229 WebArchive *archive; 230 while ((archive = [enumerator nextObject]) != nil) { 231 [subarchivePropertyLists addObject:[archive _propertyListRepresentation]]; 232 } 233 if ([subarchivePropertyLists count] > 0) { 234 [propertyList setObject:subarchivePropertyLists forKey:WebSubframeArchivesKey]; 235 } 236 [subarchivePropertyLists release]; 237 return propertyList; 305 // Currently from WebKit API perspective, WebArchives are entirely immutable once created 306 // If they ever become mutable, we'll need to rethink this. 307 if (!_private->cachedSubframeArchives) { 308 LegacyWebArchive* coreArchive = [_private coreArchive]; 309 if (!coreArchive) 310 _private->cachedSubframeArchives = [[NSArray alloc] init]; 311 else { 312 const Vector<RefPtr<Archive> >& subframeArchives(coreArchive->subframeArchives()); 313 NSMutableArray *mutableArray = _private->cachedSubframeArchives = [[NSMutableArray alloc] initWithCapacity:subframeArchives.size()]; 314 for (unsigned i = 0; i < subframeArchives.size(); ++i) { 315 WebArchive *archive = [[WebArchive alloc] _initWithCoreLegacyWebArchive:(LegacyWebArchive *)subframeArchives[i].get()]; 316 [mutableArray addObject:archive]; 317 [archive release]; 318 } 319 } 320 } 321 322 return [[_private->cachedSubframeArchives retain] autorelease]; 238 323 } 239 324 240 325 - (NSData *)data 241 326 { 242 NSDictionary *propertyList = [self _propertyListRepresentation];243 327 #if !LOG_DISABLED 244 328 CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); 245 329 #endif 246 NSData *data = [NSPropertyListSerialization dataFromPropertyList:propertyList format:NSPropertyListBinaryFormat_v1_0 errorDescription:nil]; 330 331 RetainPtr<CFDataRef> data = [_private coreArchive]->rawDataRepresentation(); 332 247 333 #if !LOG_DISABLED 248 334 CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); 249 335 CFAbsoluteTime duration = end - start; 250 336 #endif 251 LOG(Timing, "Serializing web archive with [NSPropertyListSerialization dataFromPropertyList:::] took %f seconds", duration); 252 return data; 337 LOG(Timing, "Serializing web archive to raw CFPropertyList data took %f seconds", duration); 338 339 return [[(NSData *)data.get() retain] autorelease]; 253 340 } 254 341 255 342 @end 343 344 @implementation WebArchive (WebInternal) 345 346 - (id)_initWithCoreLegacyWebArchive:(PassRefPtr<WebCore::LegacyWebArchive>)coreLegacyWebArchive 347 { 348 self = [super init]; 349 if (!self) 350 return nil; 351 352 _private = [[WebArchivePrivate alloc] initWithCoreArchive:coreLegacyWebArchive]; 353 if (!_private) { 354 [self release]; 355 return nil; 356 } 357 358 return self; 359 } 360 361 - (WebCore::LegacyWebArchive *)_coreLegacyWebArchive 362 { 363 return [_private coreArchive]; 364 } 365 366 @end -
trunk/WebKit/mac/WebView/WebDataSource.mm
r31260 r31281 30 30 31 31 #import "WebArchive.h" 32 #import "WebArchiveInternal.h" 32 33 #import "WebArchiver.h" 33 34 #import "WebDataSourceInternal.h" … … 44 45 #import "WebNSURLRequestExtras.h" 45 46 #import "WebPDFRepresentation.h" 47 #import "WebResourceInternal.h" 46 48 #import "WebResourceLoadDelegate.h" 47 49 #import "WebResourcePrivate.h" 48 #import "WebUnarchivingState.h"49 50 #import "WebViewInternal.h" 50 51 #import <JavaScriptCore/Assertions.h> 51 52 #import <WebCore/FrameLoader.h> 52 53 #import <WebCore/KURL.h> 54 #import <WebCore/LegacyWebArchive.h> 53 55 #import <WebCore/MIMETypeRegistry.h> 54 56 #import <WebCore/ResourceRequest.h> … … 67 69 id <WebDocumentRepresentation> representation; 68 70 69 WebUnarchivingState *unarchivingState;70 71 BOOL representationFinishedLoading; 71 72 } … … 88 89 89 90 [representation release]; 90 [unarchivingState release];91 91 92 92 [super dealloc]; … … 146 146 - (void)_addSubframeArchives:(NSArray *)subframeArchives 147 147 { 148 // FIXME: This SPI is poor, poor design. Can we come up with another solution for those who need it? 149 DocumentLoader* loader = [self _documentLoader]; 150 ASSERT(loader); 151 148 152 NSEnumerator *enumerator = [subframeArchives objectEnumerator]; 149 153 WebArchive *archive; 150 154 while ((archive = [enumerator nextObject]) != nil) 151 [self _addToUnarchiveState:archive];155 loader->addAllArchiveResources([archive _coreLegacyWebArchive]); 152 156 } 153 157 … … 203 207 [[self representation] receivedError:error withDataSource:self]; 204 208 } 205 }206 207 - (void)_clearUnarchivingState208 {209 [_private->unarchivingState release];210 _private->unarchivingState = nil;211 209 } 212 210 … … 239 237 } 240 238 241 - (WebResource *)_archivedSubresourceForURL:(NSURL *)URL242 {243 return [_private->unarchivingState archivedResourceForURL:URL];244 }245 246 239 - (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement 247 240 { … … 251 244 } 252 245 246 // FIXME: There are few reasons why this method and many of its related methods can't be pushed entirely into WebCore in the future. 253 247 - (DOMDocumentFragment *)_documentFragmentWithArchive:(WebArchive *)archive 254 248 { … … 260 254 NSString *markupString = [[NSString alloc] initWithData:[mainResource data] encoding:NSUTF8StringEncoding]; 261 255 // FIXME: seems poor form to do this as a side effect of getting a document fragment 262 [self _addToUnarchiveState:archive]; 256 if (DocumentLoader* loader = [self _documentLoader]) 257 loader->addAllArchiveResources([archive _coreLegacyWebArchive]); 258 263 259 DOMDocumentFragment *fragment = [[self webFrame] _documentFragmentWithMarkupString:markupString baseURLString:[[mainResource URL] _web_originalDataAsString]]; 264 260 [markupString release]; … … 307 303 } 308 304 309 - (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName310 {311 return [_private->unarchivingState popSubframeArchiveWithFrameName:frameName];312 }313 314 305 - (WebView *)_webView 315 306 { … … 335 326 336 327 [_private->representation setDataSource:self]; 337 }338 339 - (void)_addToUnarchiveState:(WebArchive *)archive340 {341 if (!_private->unarchivingState)342 _private->unarchivingState = [[WebUnarchivingState alloc] init];343 [_private->unarchivingState addArchive:archive];344 328 } 345 329 … … 504 488 NSData *data; 505 489 NSURLResponse *response; 506 if (![[self webFrame] _getData:&data andResponse:&response forURL:[URL _web_originalDataAsString]]) 507 return [self _archivedSubresourceForURL:URL]; 490 if (![[self webFrame] _getData:&data andResponse:&response forURL:[URL _web_originalDataAsString]]) { 491 DocumentLoader* loader = [self _documentLoader]; 492 ArchiveResource* coreResource = loader->archiveResourceForURL(URL); 493 return coreResource ? [[[WebResource alloc] _initWithCoreResource:coreResource] autorelease] : nil; 494 } 508 495 509 496 return [[[WebResource alloc] _initWithData:data URL:URL response:response] autorelease]; … … 511 498 512 499 - (void)addSubresource:(WebResource *)subresource 513 { 514 if (subresource) { 515 if (!_private->unarchivingState) 516 _private->unarchivingState = [[WebUnarchivingState alloc] init]; 517 [_private->unarchivingState addResource:subresource]; 518 } 519 } 520 521 @end 500 { 501 _private->loader->addArchiveResource([subresource _coreResource]); 502 } 503 504 @end -
trunk/WebKit/mac/WebView/WebDataSourceInternal.h
r31014 r31281 49 49 50 50 @interface WebDataSource (WebInternal) 51 - (void)_addToUnarchiveState:(WebArchive *)archive;52 51 - (void)_makeRepresentation; 53 52 - (BOOL)_isDocumentHTML; 54 53 - (WebView *)_webView; 55 - (WebArchive *)_popSubframeArchiveWithName:(NSString *)frameName;56 54 - (NSURL *)_URL; 57 55 - (DOMElement *)_imageElementWithImageResource:(WebResource *)resource; … … 60 58 + (NSMutableDictionary *)_repTypesAllowImageTypeOmission:(BOOL)allowImageTypeOmission; 61 59 - (void)_replaceSelectionWithArchive:(WebArchive *)archive selectReplacement:(BOOL)selectReplacement; 62 - (WebResource *)_archivedSubresourceForURL:(NSURL *)URL;63 60 - (id)_initWithDocumentLoader:(WebDocumentLoaderMac*)loader; 64 61 - (void)_finishedLoading; … … 66 63 - (void)_revertToProvisionalState; 67 64 - (void)_setMainDocumentError:(NSError *)error; 68 - (void)_clearUnarchivingState;69 65 - (WebCoreDocumentLoader*)_documentLoader; 70 66 @end -
trunk/WebKit/mac/WebView/WebFrame.mm
r31264 r31281 36 36 #import "DOMNodeInternal.h" 37 37 #import "DOMRangeInternal.h" 38 #import "WebArchiveInternal.h" 38 39 #import "WebChromeClient.h" 39 40 #import "WebDataSourceInternal.h" … … 60 61 #import <WebCore/HistoryItem.h> 61 62 #import <WebCore/HitTestResult.h> 63 #import <WebCore/LegacyWebArchive.h> 62 64 #import <WebCore/Page.h> 63 65 #import <WebCore/PluginData.h> … … 292 294 { 293 295 return [self _createFrameWithPage:ownerElement->document()->frame()->page() frameName:name frameView:frameView ownerElement:ownerElement]; 294 }295 296 /*297 In the case of saving state about a page with frames, we store a tree of items that mirrors the frame tree.298 The item that was the target of the user's navigation is designated as the "targetItem".299 When this method is called with doClip=YES we're able to create the whole tree except for the target's children,300 which will be loaded in the future. That part of the tree will be filled out as the child loads are committed.301 */302 303 - (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame304 {305 ASSERT(childFrame);306 HistoryItem* parentItem = _private->coreFrame->loader()->currentHistoryItem();307 FrameLoadType loadType = _private->coreFrame->loader()->loadType();308 FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;309 310 // If we're moving in the backforward list, we might want to replace the content311 // of this child frame with whatever was there at that point.312 // Reload will maintain the frame contents, LoadSame will not.313 if (parentItem && parentItem->children().size() &&314 (isBackForwardLoadType(loadType)315 || loadType == FrameLoadTypeReloadAllowingStaleData))316 {317 HistoryItem* childItem = parentItem->childItemWithName([childFrame name]);318 if (childItem) {319 // Use the original URL to ensure we get all the side-effects, such as320 // onLoad handlers, of any redirects that happened. An example of where321 // this is needed is Radar 3213556.322 URL = [NSURL _web_URLWithDataAsString:childItem->originalURLString()];323 // These behaviors implied by these loadTypes should apply to the child frames324 childLoadType = loadType;325 326 if (isBackForwardLoadType(loadType)) {327 // For back/forward, remember this item so we can traverse any child items as child frames load328 childFrame->_private->coreFrame->loader()->setProvisionalHistoryItem(childItem);329 } else {330 // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item331 childFrame->_private->coreFrame->loader()->setCurrentHistoryItem(childItem);332 }333 }334 }335 336 WebArchive *archive = [[self _dataSource] _popSubframeArchiveWithName:[childFrame name]];337 if (archive)338 [childFrame loadArchive:archive];339 else340 childFrame->_private->coreFrame->loader()->load([URL absoluteURL], referrer, childLoadType, String(), 0, 0);341 296 } 342 297 … … 1312 1267 - (void)loadArchive:(WebArchive *)archive 1313 1268 { 1314 WebResource *mainResource = [archive mainResource]; 1315 if (mainResource) { 1316 SubstituteData substituteData(WebCore::SharedBuffer::wrapNSData([mainResource data]), [mainResource MIMEType], [mainResource textEncodingName], KURL()); 1317 ResourceRequest request([mainResource URL]); 1318 1319 // hack because Mail checks for this property to detect data / archive loads 1320 [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)request.nsURLRequest()]; 1321 1322 RefPtr<DocumentLoader> documentLoader = _private->coreFrame->loader()->client()->createDocumentLoader(request, substituteData); 1323 1324 [dataSource(documentLoader.get()) _addToUnarchiveState:archive]; 1325 1326 _private->coreFrame->loader()->load(documentLoader.get()); 1327 } 1269 if (LegacyWebArchive* coreArchive = [archive _coreLegacyWebArchive]) 1270 _private->coreFrame->loader()->loadArchive(coreArchive); 1328 1271 } 1329 1272 -
trunk/WebKit/mac/WebView/WebFrameInternal.h
r31028 r31281 130 130 - (void)_clearSelectionInOtherFrames; 131 131 132 - (void)_loadURL:(NSURL *)URL referrer:(NSString *)referrer intoChild:(WebFrame *)childFrame;133 134 132 - (void)_attachScriptDebugger; 135 133 - (void)_detachScriptDebugger; -
trunk/WebKit/mac/WebView/WebHTMLRepresentation.mm
r31028 r31281 189 189 } 190 190 191 - (void)_loadDataSourceAsWebArchive192 {193 WebArchive *archive = [[WebArchive alloc] initWithData:[_private->dataSource data]];194 WebResource *mainResource = [archive mainResource];195 if (!mainResource) {196 [archive release];197 return;198 }199 200 NSData *data = [mainResource data];201 [data retain];202 [_private->parsedArchiveData release];203 _private->parsedArchiveData = data;204 205 [_private->dataSource _addToUnarchiveState:archive];206 [archive release];207 208 WebFrame *webFrame = [_private->dataSource webFrame];209 210 if (!webFrame)211 return;212 213 core(webFrame)->loader()->continueLoadWithData(SharedBuffer::wrapNSData(data).get(), [mainResource MIMEType], [mainResource textEncodingName], [mainResource URL]);214 }215 216 191 - (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource 217 192 { … … 224 199 225 200 if (frame) { 226 if ([self _isDisplayingWebArchive]) 227 [self _loadDataSourceAsWebArchive]; 228 else { 201 if (![self _isDisplayingWebArchive]) { 229 202 // Telling the frame we received some data and passing nil as the data is our 230 203 // way to get work done that is normally done when the first bit of data is -
trunk/WebKit/mac/WebView/WebResource.mm
r31028 r31281 32 32 #import "WebNSDictionaryExtras.h" 33 33 #import "WebNSURLExtras.h" 34 35 #import <WebCore/ArchiveResource.h> 36 #import <WebCore/LegacyWebArchive.h> 34 37 #import <WebCore/TextEncoding.h> 38 #import <WebCore/WebCoreObjCExtras.h> 35 39 #import <WebCore/WebCoreURLResponse.h> 40 41 #import <wtf/PassRefPtr.h> 36 42 37 43 using namespace WebCore; … … 49 55 { 50 56 @public 51 NSData *data; 52 NSURL *URL; 53 NSString *frameName; 54 NSString *MIMEType; 55 NSString *textEncodingName; 56 NSURLResponse *response; 57 BOOL shouldIgnoreWhenUnarchiving; 58 } 57 ArchiveResource* coreResource; 58 } 59 60 - (id)initWithCoreResource:(PassRefPtr<ArchiveResource>)coreResource; 59 61 @end 60 62 61 63 @implementation WebResourcePrivate 62 64 65 #ifndef BUILDING_ON_TIGER 66 + (void)initialize 67 { 68 WebCoreObjCFinalizeOnMainThread(self); 69 } 70 #endif 71 72 - (id)init 73 { 74 return [super init]; 75 } 76 77 - (id)initWithCoreResource:(PassRefPtr<ArchiveResource>)passedResource 78 { 79 self = [super init]; 80 if (!self) 81 return self; 82 83 // Acquire the PassRefPtr<>'s ref as our own manual ref 84 coreResource = passedResource.releaseRef(); 85 86 return self; 87 } 88 63 89 - (void)dealloc 64 90 { 65 [data release]; 66 [URL release]; 67 [frameName release]; 68 [MIMEType release]; 69 [textEncodingName release]; 70 [response release]; 91 if (coreResource) 92 coreResource->deref(); 71 93 [super dealloc]; 72 94 } 73 95 96 - (void)finalize 97 { 98 if (coreResource) 99 coreResource->deref(); 100 [super finalize]; 101 } 102 74 103 @end 75 104 … … 92 121 - (id)initWithCoder:(NSCoder *)decoder 93 122 { 94 self = [self init]; 95 if (!self) 96 return nil; 97 123 self = [super init]; 124 if (!self) 125 return nil; 126 127 NSData *data = nil; 128 NSURL *url = nil; 129 NSString *mimeType = nil, *textEncoding = nil, *frameName = nil; 130 NSURLResponse *response = nil; 131 98 132 @try { 99 133 id object = [decoder decodeObjectForKey:WebResourceDataKey]; 100 134 if ([object isKindOfClass:[NSData class]]) 101 _private->data = [object retain];135 data = object; 102 136 object = [decoder decodeObjectForKey:WebResourceURLKey]; 103 137 if ([object isKindOfClass:[NSURL class]]) 104 _private->URL = [object retain];138 url = object; 105 139 object = [decoder decodeObjectForKey:WebResourceMIMETypeKey]; 106 140 if ([object isKindOfClass:[NSString class]]) 107 _private->MIMEType = [object retain];141 mimeType = object; 108 142 object = [decoder decodeObjectForKey:WebResourceTextEncodingNameKey]; 109 143 if ([object isKindOfClass:[NSString class]]) 110 _private->textEncodingName = [object retain];144 textEncoding = object; 111 145 object = [decoder decodeObjectForKey:WebResourceFrameNameKey]; 112 146 if ([object isKindOfClass:[NSString class]]) 113 _private->frameName = [object retain];147 frameName = object; 114 148 object = [decoder decodeObjectForKey:WebResourceResponseKey]; 115 149 if ([object isKindOfClass:[NSURLResponse class]]) 116 _private->response = [object retain];150 response = object; 117 151 } @catch(id) { 118 152 [self release]; … … 120 154 } 121 155 156 _private = [[WebResourcePrivate alloc] initWithCoreResource:ArchiveResource::create(SharedBuffer::wrapNSData(data), url, mimeType, textEncoding, frameName, response)]; 157 122 158 return self; 123 159 } … … 125 161 - (void)encodeWithCoder:(NSCoder *)encoder 126 162 { 127 [encoder encodeObject:_private->data forKey:WebResourceDataKey]; 128 [encoder encodeObject:_private->URL forKey:WebResourceURLKey]; 129 [encoder encodeObject:_private->MIMEType forKey:WebResourceMIMETypeKey]; 130 [encoder encodeObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey]; 131 [encoder encodeObject:_private->frameName forKey:WebResourceFrameNameKey]; 132 [encoder encodeObject:_private->response forKey:WebResourceResponseKey]; 163 ArchiveResource *resource = _private->coreResource; 164 165 NSData *data = nil; 166 NSURL *url = nil; 167 NSString *mimeType = nil, *textEncoding = nil, *frameName = nil; 168 NSURLResponse *response = nil; 169 170 if (resource) { 171 if (resource->data()) 172 data = [resource->data()->createNSData() autorelease]; 173 url = resource->url(); 174 mimeType = resource->mimeType(); 175 textEncoding = resource->textEncoding(); 176 frameName = resource->frameName(); 177 response = resource->response().nsURLResponse(); 178 } 179 [encoder encodeObject:data forKey:WebResourceDataKey]; 180 [encoder encodeObject:url forKey:WebResourceURLKey]; 181 [encoder encodeObject:mimeType forKey:WebResourceMIMETypeKey]; 182 [encoder encodeObject:textEncoding forKey:WebResourceTextEncodingNameKey]; 183 [encoder encodeObject:frameName forKey:WebResourceFrameNameKey]; 184 [encoder encodeObject:response forKey:WebResourceResponseKey]; 133 185 } 134 186 … … 146 198 - (NSData *)data 147 199 { 148 return _private-> data;200 return _private->coreResource ? [_private->coreResource->data()->createNSData() autorelease] : 0; 149 201 } 150 202 151 203 - (NSURL *)URL 152 204 { 153 return _private-> URL;205 return _private->coreResource ? (NSURL *)_private->coreResource->url() : 0; 154 206 } 155 207 156 208 - (NSString *)MIMEType 157 209 { 158 return _private-> MIMEType;210 return _private->coreResource ? (NSString *)_private->coreResource->mimeType() : 0; 159 211 } 160 212 161 213 - (NSString *)textEncodingName 162 214 { 163 return _private-> textEncodingName;215 return _private->coreResource ? (NSString *)_private->coreResource->textEncoding() : 0; 164 216 } 165 217 166 218 - (NSString *)frameName 167 219 { 168 return _private-> frameName;220 return _private->coreResource ? (NSString *)_private->coreResource->frameName() : 0; 169 221 } 170 222 … … 176 228 @end 177 229 230 @implementation WebResource (WebResourceInternal) 231 232 - (id)_initWithCoreResource:(WebCore::ArchiveResource *)coreResource 233 { 234 self = [super init]; 235 if (!self) 236 return nil; 237 238 _private = [[WebResourcePrivate alloc] initWithCoreResource:coreResource]; 239 240 return self; 241 } 242 243 - (WebCore::ArchiveResource *)_coreResource 244 { 245 return _private->coreResource; 246 } 247 248 @end 249 178 250 @implementation WebResource (WebResourcePrivate) 179 251 180 252 // SPI for Mail (5066325) 253 // FIXME: This "ignoreWhenUnarchiving" concept is an ugly one - can we find a cleaner solution for those who need this SPI? 181 254 - (void)_ignoreWhenUnarchiving 182 255 { 183 _private->shouldIgnoreWhenUnarchiving = YES; 184 } 185 186 - (BOOL)_shouldIgnoreWhenUnarchiving 187 { 188 return _private->shouldIgnoreWhenUnarchiving; 189 } 190 191 + (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists 192 { 193 if (![propertyLists isKindOfClass:[NSArray class]]) { 194 return nil; 195 } 196 NSEnumerator *enumerator = [propertyLists objectEnumerator]; 197 NSMutableArray *resources = [NSMutableArray array]; 198 NSDictionary *propertyList; 199 while ((propertyList = [enumerator nextObject]) != nil) { 200 WebResource *resource = [[WebResource alloc] _initWithPropertyList:propertyList]; 201 if (resource) { 202 [resources addObject:resource]; 203 [resource release]; 204 } 205 } 206 return resources; 207 } 208 209 + (NSArray *)_propertyListsFromResources:(NSArray *)resources 210 { 211 NSEnumerator *enumerator = [resources objectEnumerator]; 212 NSMutableArray *propertyLists = [NSMutableArray array]; 213 WebResource *resource; 214 while ((resource = [enumerator nextObject]) != nil) { 215 [propertyLists addObject:[resource _propertyListRepresentation]]; 216 } 217 return propertyLists; 256 if (_private->coreResource) 257 _private->coreResource->ignoreWhenUnarchiving(); 218 258 } 219 259 … … 226 266 copyData:(BOOL)copyData 227 267 { 228 [self init]; 229 230 if (!data) { 268 self = [super init]; 269 if (!self) 270 return nil; 271 272 if (!data || !URL || !MIMEType) { 231 273 [self release]; 232 274 return nil; 233 275 } 234 _private->data = copyData ? [data copy] : [data retain]; 235 236 if (!URL) { 237 [self release]; 238 return nil; 239 } 240 _private->URL = [URL copy]; 241 242 if (!MIMEType) { 243 [self release]; 244 return nil; 245 } 246 _private->MIMEType = [MIMEType copy]; 247 248 _private->textEncodingName = [textEncodingName copy]; 249 _private->frameName = [frameName copy]; 250 _private->response = [response retain]; 251 276 277 _private = [[WebResourcePrivate alloc] initWithCoreResource:ArchiveResource::create(SharedBuffer::wrapNSData(copyData ? [[data copy] autorelease] : data), URL, MIMEType, textEncodingName, frameName, response)]; 278 252 279 return self; 253 280 } … … 266 293 } 267 294 268 - (id)_initWithPropertyList:(id)propertyList 269 { 270 if (![propertyList isKindOfClass:[NSDictionary class]]) { 271 [self release]; 272 return nil; 295 - (NSFileWrapper *)_fileWrapperRepresentation 296 { 297 SharedBuffer* coreData = _private->coreResource ? _private->coreResource->data() : 0; 298 NSData *data = coreData ? [coreData->createNSData() autorelease] : nil; 299 300 NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:data] autorelease]; 301 NSString *preferredFilename = _private->coreResource ? (NSString *)_private->coreResource->response().suggestedFilename() : nil; 302 if (!preferredFilename || ![preferredFilename length]) { 303 NSURL *url = _private->coreResource ? (NSURL *)_private->coreResource->url() : nil; 304 NSString *mimeType = _private->coreResource ? (NSString *)_private->coreResource->mimeType() : nil; 305 preferredFilename = [url _webkit_suggestedFilenameWithMIMEType:mimeType]; 273 306 } 274 307 275 NSURLResponse *response = nil;276 NSData *responseData = [propertyList objectForKey:WebResourceResponseKey];277 if ([responseData isKindOfClass:[NSData class]]) {278 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];279 @try {280 id responseObject = [unarchiver decodeObjectForKey:WebResourceResponseKey];281 if ([responseObject isKindOfClass:[NSURLResponse class]])282 response = responseObject;283 [unarchiver finishDecoding];284 } @catch(id) {285 response = nil;286 }287 [unarchiver release];288 }289 290 NSData *data = [propertyList objectForKey:WebResourceDataKey];291 NSString *URLString = [propertyList _webkit_stringForKey:WebResourceURLKey];292 return [self _initWithData:[data isKindOfClass:[NSData class]] ? data : nil293 URL:URLString ? [NSURL _web_URLWithDataAsString:URLString] : nil294 MIMEType:[propertyList _webkit_stringForKey:WebResourceMIMETypeKey]295 textEncodingName:[propertyList _webkit_stringForKey:WebResourceTextEncodingNameKey]296 frameName:[propertyList _webkit_stringForKey:WebResourceFrameNameKey]297 response:response298 copyData:NO];299 }300 301 - (NSFileWrapper *)_fileWrapperRepresentation302 {303 NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:_private->data] autorelease];304 NSString *preferredFilename = [_private->response suggestedFilename];305 if (!preferredFilename || ![preferredFilename length])306 preferredFilename = [_private->URL _webkit_suggestedFilenameWithMIMEType:_private->MIMEType];307 308 [wrapper setPreferredFilename:preferredFilename]; 308 309 return wrapper; 309 310 } 310 311 311 - (id)_propertyListRepresentation312 {313 NSMutableDictionary *propertyList = [NSMutableDictionary dictionary];314 [propertyList setObject:_private->data forKey:WebResourceDataKey];315 [propertyList setObject:[_private->URL _web_originalDataAsString] forKey:WebResourceURLKey];316 [propertyList setObject:_private->MIMEType forKey:WebResourceMIMETypeKey];317 if (_private->textEncodingName != nil) {318 [propertyList setObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];319 }320 if (_private->frameName != nil) {321 [propertyList setObject:_private->frameName forKey:WebResourceFrameNameKey];322 }323 if (_private->response != nil) {324 NSMutableData *responseData = [[NSMutableData alloc] init];325 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData];326 [archiver encodeObject:_private->response forKey:WebResourceResponseKey];327 [archiver finishEncoding];328 [archiver release];329 [propertyList setObject:responseData forKey:WebResourceResponseKey];330 [responseData release];331 }332 return propertyList;333 }334 335 312 - (NSURLResponse *)_response 336 313 { 337 if (_private->response != nil) { 338 return _private->response; 339 } 340 return [[[NSURLResponse alloc] initWithURL:_private->URL 341 MIMEType:_private->MIMEType 342 expectedContentLength:[_private->data length] 343 textEncodingName:_private->textEncodingName] autorelease]; 314 NSURLResponse *response = nil; 315 if (_private->coreResource) 316 response = _private->coreResource->response().nsURLResponse(); 317 318 return response ? response : [[[NSURLResponse alloc] init] autorelease]; 344 319 } 345 320 346 321 - (NSString *)_stringValue 347 322 { 348 WebCore::TextEncoding encoding(_private-> textEncodingName);323 WebCore::TextEncoding encoding(_private->coreResource ? (NSString *)_private->coreResource->textEncoding() : nil); 349 324 if (!encoding.isValid()) 350 325 encoding = WindowsLatin1Encoding(); 351 return encoding.decode(reinterpret_cast<const char*>([_private->data bytes]), [_private->data length]); 352 } 353 354 @end 326 327 SharedBuffer* coreData = _private->coreResource ? _private->coreResource->data() : 0; 328 329 return encoding.decode(reinterpret_cast<const char*>(coreData ? coreData->data() : 0), coreData ? coreData->size() : 0); 330 } 331 332 @end -
trunk/WebKit/mac/WebView/WebResourcePrivate.h
r30323 r31281 41 41 - (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response; 42 42 43 - (BOOL)_shouldIgnoreWhenUnarchiving;44 43 - (void)_ignoreWhenUnarchiving; 45 44 46 + (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists;47 + (NSArray *)_propertyListsFromResources:(NSArray *)resources;48 49 - (id)_initWithPropertyList:(id)propertyList;50 51 45 - (NSFileWrapper *)_fileWrapperRepresentation; 52 - (id)_propertyListRepresentation;53 46 - (NSURLResponse *)_response; 54 47 - (NSString *)_stringValue;
Note: See TracChangeset
for help on using the changeset viewer.