webengine/osswebengine/WebKit/WebView/WebArchiver.mm
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  * 1.  Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer. 
       
    10  * 2.  Redistributions in binary form must reproduce the above copyright
       
    11  *     notice, this list of conditions and the following disclaimer in the
       
    12  *     documentation and/or other materials provided with the distribution. 
       
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    14  *     its contributors may be used to endorse or promote products derived
       
    15  *     from this software without specific prior written permission. 
       
    16  *
       
    17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27  */
       
    28 
       
    29 #import "WebArchiver.h"
       
    30 
       
    31 #import "WebArchive.h"
       
    32 #import "WebDOMOperationsPrivate.h"
       
    33 #import "WebDataSource.h"
       
    34 #import "WebDocument.h"
       
    35 #import "WebFrame.h"
       
    36 #import "WebFrameBridge.h"
       
    37 #import "WebFrameInternal.h"
       
    38 #import "WebResource.h"
       
    39 #import <JavaScriptCore/Assertions.h>
       
    40 #import <WebCore/Frame.h>
       
    41 #import <WebCore/SelectionController.h>
       
    42 #import <WebKit/DOM.h>
       
    43 
       
    44 using namespace WebCore;
       
    45 
       
    46 @implementation WebArchiver
       
    47 
       
    48 + (NSArray *)_subframeArchivesForFrame:(WebFrame *)frame
       
    49 {
       
    50     NSEnumerator *enumerator = [[frame childFrames] objectEnumerator];
       
    51     NSMutableArray *subframeArchives = [NSMutableArray array];
       
    52     WebFrame *childFrame;
       
    53     while ((childFrame = [enumerator nextObject])) {
       
    54         WebArchive *childFrameArchive = [self archiveFrame:childFrame];
       
    55         if (childFrameArchive)
       
    56             [subframeArchives addObject:childFrameArchive];
       
    57     }
       
    58 
       
    59     return subframeArchives;
       
    60 }
       
    61 
       
    62 + (WebArchive *)archiveFrame:(WebFrame *)frame;
       
    63 {
       
    64     return [[[WebArchive alloc] initWithMainResource:[[frame _dataSource] mainResource]
       
    65                                         subresources:[[frame _dataSource] subresources]
       
    66                                     subframeArchives:[self _subframeArchivesForFrame:frame]] autorelease];
       
    67 }
       
    68 
       
    69 + (WebArchive *)archiveMainResourceForFrame:(WebFrame *)frame;
       
    70 {
       
    71     return [[[WebArchive alloc] initWithMainResource:[[frame _dataSource] mainResource]
       
    72                                         subresources:nil
       
    73                                     subframeArchives:nil] autorelease];
       
    74 }
       
    75 
       
    76 + (WebArchive *)_archiveCurrentStateForFrame:(WebFrame *)frame
       
    77 {
       
    78     if ([frame DOMDocument])
       
    79         return [self archiveNode:[frame DOMDocument]];
       
    80 
       
    81     return [self archiveFrame:frame];
       
    82 }
       
    83 
       
    84 + (WebArchive *)_archiveWithMarkupString:(NSString *)markupString fromFrame:(WebFrame *)frame nodes:(NSArray *)nodes
       
    85 { 
       
    86     NSURLResponse *response = [[frame _dataSource] response];
       
    87     NSURL *responseURL = [response URL];
       
    88     
       
    89     // it's possible to have a response without a URL here
       
    90     // <rdar://problem/5454935>
       
    91     if (!responseURL)
       
    92         responseURL = [NSURL URLWithString:@""];
       
    93     
       
    94     WebResource *mainResource = [[WebResource alloc] initWithData:[markupString dataUsingEncoding:NSUTF8StringEncoding]
       
    95                                                               URL:responseURL
       
    96                                                          MIMEType:[response MIMEType]
       
    97                                                  textEncodingName:@"UTF-8"
       
    98                                                         frameName:[frame name]];
       
    99     
       
   100     NSMutableArray *subframeArchives = [[NSMutableArray alloc] init];
       
   101     NSMutableArray *subresources = [[NSMutableArray alloc] init];
       
   102     NSMutableSet *uniqueSubresources = [[NSMutableSet alloc] init];
       
   103     NSEnumerator *enumerator = [nodes objectEnumerator];
       
   104     DOMNode *node;
       
   105     while ((node = [enumerator nextObject]) != nil) {
       
   106         WebFrame *childFrame;
       
   107         if (([node isKindOfClass:[DOMHTMLFrameElement class]] || 
       
   108              [node isKindOfClass:[DOMHTMLIFrameElement class]] || 
       
   109              [node isKindOfClass:[DOMHTMLObjectElement class]]) &&
       
   110             ((childFrame = [(DOMHTMLFrameElement *)node contentFrame]) != nil)) {
       
   111             [subframeArchives addObject:[self _archiveCurrentStateForFrame:childFrame]];
       
   112         } else {
       
   113             NSEnumerator *enumerator = [[node _subresourceURLs] objectEnumerator];
       
   114             NSURL *URL;
       
   115             while ((URL = [enumerator nextObject]) != nil) {
       
   116                 if ([uniqueSubresources containsObject:URL])
       
   117                     continue;
       
   118                 [uniqueSubresources addObject:URL];
       
   119                 WebResource *subresource = [[frame _dataSource] subresourceForURL:URL];
       
   120                 if (subresource)
       
   121                     [subresources addObject:subresource];
       
   122                 else
       
   123                     // FIXME: should do something better than spew to console here
       
   124                     LOG_ERROR("Failed to archive subresource for %@", URL);
       
   125             }
       
   126         }
       
   127     }
       
   128     
       
   129     WebArchive *archive = [[[WebArchive alloc] initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives] autorelease];
       
   130     [mainResource release];
       
   131     [uniqueSubresources release];
       
   132     [subresources release];
       
   133     [subframeArchives release];
       
   134     
       
   135     return archive;
       
   136 }
       
   137 
       
   138 + (WebArchive *)archiveRange:(DOMRange *)range
       
   139 {
       
   140     WebFrameBridge *bridge = [range _bridge];
       
   141     WebFrame *frame = [bridge webFrame];
       
   142     NSArray *nodes;
       
   143     NSString *markupString = [bridge markupStringFromRange:range nodes:&nodes];
       
   144     return [self _archiveWithMarkupString:markupString fromFrame:frame nodes:nodes];
       
   145 }
       
   146 
       
   147 + (WebArchive *)archiveNode:(DOMNode *)node
       
   148 {
       
   149     WebFrame *frame = [[node ownerDocument] webFrame];
       
   150     WebFrameBridge *bridge = [frame _bridge];
       
   151     NSArray *nodes;
       
   152     NSString *markupString = [bridge markupStringFromNode:node nodes:&nodes];
       
   153     return [self _archiveWithMarkupString:markupString fromFrame:frame nodes:nodes];
       
   154 }
       
   155 
       
   156 + (WebArchive *)archiveSelectionInFrame:(WebFrame *)frame
       
   157 {
       
   158     Frame* coreFrame = core(frame);
       
   159     if (!coreFrame)
       
   160         return nil;
       
   161 
       
   162     WebFrameBridge *bridge = [frame _bridge];
       
   163     NSArray *nodes;
       
   164     NSString *markupString = [bridge markupStringFromRange:kit(coreFrame->selectionController()->toRange().get()) nodes:&nodes];
       
   165     WebArchive *archive = [self _archiveWithMarkupString:markupString fromFrame:frame nodes:nodes];
       
   166 
       
   167     if (coreFrame->isFrameSet()) {
       
   168         // Wrap the frameset document in an iframe so it can be pasted into
       
   169         // another document (which will have a body or frameset of its own). 
       
   170 
       
   171         NSString *iframeMarkup = [[NSString alloc] initWithFormat:@"<iframe frameborder=\"no\" marginwidth=\"0\" marginheight=\"0\" width=\"98%%\" height=\"98%%\" src=\"%@\"></iframe>", [[[frame _dataSource] response] URL]];
       
   172         WebResource *iframeResource = [[WebResource alloc] initWithData:[iframeMarkup dataUsingEncoding:NSUTF8StringEncoding]
       
   173                                                                   URL:[NSURL URLWithString:@"about:blank"]
       
   174                                                              MIMEType:@"text/html"
       
   175                                                      textEncodingName:@"UTF-8"
       
   176                                                             frameName:nil];
       
   177         
       
   178         NSArray *subframeArchives = [NSArray arrayWithObject:archive];
       
   179         archive = [[[WebArchive alloc] initWithMainResource:iframeResource subresources:nil subframeArchives:subframeArchives] autorelease];
       
   180         
       
   181         [iframeResource release];
       
   182         [iframeMarkup release];
       
   183     }
       
   184 
       
   185     return archive;
       
   186 }
       
   187 
       
   188 @end
       
   189