webengine/osswebengine/WebKit/WebView/WebHTMLRepresentation.mm
changeset 0 dd21522fd290
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKit/WebView/WebHTMLRepresentation.mm	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "WebHTMLRepresentation.h"
+
+#import "DOMNodeInternal.h"
+#import "DOMRangeInternal.h"
+#import "WebArchive.h"
+#import "WebBasePluginPackage.h"
+#import "WebDataSourceInternal.h"
+#import "WebDocumentPrivate.h"
+#import "WebFrameBridge.h"
+#import "WebFrameInternal.h"
+#import "WebKitNSStringExtras.h"
+#import "WebKitStatisticsPrivate.h"
+#import "WebNSAttributedStringExtras.h"
+#import "WebNSObjectExtras.h"
+#import "WebResourcePrivate.h"
+#import "WebView.h"
+#import <Foundation/NSURLResponse.h>
+#import <JavaScriptCore/Assertions.h>
+#import <WebCore/Document.h>
+#import <WebCore/DocumentLoader.h>
+#import <WebCore/Frame.h>
+#import <WebCore/FrameLoader.h>
+#import <WebCore/MIMETypeRegistry.h>
+#import <WebCore/Range.h>
+
+using namespace WebCore;
+
+@interface WebHTMLRepresentationPrivate : NSObject
+{
+@public
+    WebDataSource *dataSource;
+    WebFrameBridge *bridge;
+    NSData *parsedArchiveData;
+    
+    BOOL hasSentResponseToPlugin;
+    id <WebPluginManualLoader> manualLoader;
+    NSView *pluginView;
+}
+@end
+
+@implementation WebHTMLRepresentationPrivate
+
+- (void)dealloc
+{
+    [parsedArchiveData release];
+    [super dealloc];
+}
+
+@end
+
+@implementation WebHTMLRepresentation
+
+static NSArray *stringArray(const HashSet<String>& set)
+{
+    NSMutableArray *array = [NSMutableArray arrayWithCapacity:set.size()];
+    HashSet<String>::const_iterator end = set.end();
+    for (HashSet<String>::const_iterator it = set.begin(); it != end; ++it)
+        [array addObject:(NSString *)(*it)];
+    return array;
+}
+
+static NSArray *concatenateArrays(NSArray *first, NSArray *second)
+{
+    NSMutableArray *result = [[first mutableCopy] autorelease];
+    [result addObjectsFromArray:second];
+    return result;
+}
+
++ (NSArray *)supportedMIMETypes
+{
+    static RetainPtr<NSArray> staticSupportedMIMETypes =
+        concatenateArrays([self supportedNonImageMIMETypes], [self supportedImageMIMETypes]);
+    return staticSupportedMIMETypes.get();
+}
+
++ (NSArray *)supportedNonImageMIMETypes
+{
+    static RetainPtr<NSArray> staticSupportedNonImageMIMETypes =
+        stringArray(MIMETypeRegistry::getSupportedNonImageMIMETypes());
+    return staticSupportedNonImageMIMETypes.get();
+}
+
++ (NSArray *)supportedImageMIMETypes
+{
+    static RetainPtr<NSArray> staticSupportedImageMIMETypes =
+        stringArray(MIMETypeRegistry::getSupportedImageMIMETypes());
+    return staticSupportedImageMIMETypes.get();
+}
+
+- init
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    
+    _private = [[WebHTMLRepresentationPrivate alloc] init];
+    
+    ++WebHTMLRepresentationCount;
+    
+    return self;
+}
+
+- (void)dealloc
+{
+    --WebHTMLRepresentationCount;
+    
+    [_private release];
+
+    [super dealloc];
+}
+
+- (void)finalize
+{
+    --WebHTMLRepresentationCount;
+
+    [super finalize];
+}
+
+- (WebFrameBridge *)_bridge
+{
+    return _private->bridge;
+}
+
+- (void)_redirectDataToManualLoader:(id<WebPluginManualLoader>)manualLoader forPluginView:(NSView *)pluginView;
+{
+    _private->manualLoader = manualLoader;
+    _private->pluginView = pluginView;
+}
+
+- (void)setDataSource:(WebDataSource *)dataSource
+{
+    _private->dataSource = dataSource;
+    _private->bridge = [[dataSource webFrame] _bridge];
+}
+
+- (BOOL)_isDisplayingWebArchive
+{
+    return [[[_private->dataSource response] MIMEType] _webkit_isCaseInsensitiveEqualToString:@"application/x-webarchive"];
+}
+
+- (void)receivedData:(NSData *)data withDataSource:(WebDataSource *)dataSource
+{
+    if ([dataSource webFrame] && ![self _isDisplayingWebArchive]) {
+        if (!_private->pluginView)
+            [_private->bridge receivedData:data textEncodingName:[[_private->dataSource response] textEncodingName]];
+
+        if (_private->pluginView) {
+            if (!_private->hasSentResponseToPlugin) {
+                [_private->manualLoader pluginView:_private->pluginView receivedResponse:[dataSource response]];
+                _private->hasSentResponseToPlugin = YES;
+            }
+            
+            [_private->manualLoader pluginView:_private->pluginView receivedData:data];
+        }
+    }
+}
+
+- (void)receivedError:(NSError *)error withDataSource:(WebDataSource *)dataSource
+{
+    if (_private->pluginView) {
+        [_private->manualLoader pluginView:_private->pluginView receivedError:error];
+    }
+}
+
+- (void)_loadDataSourceAsWebArchive
+{
+    WebArchive *archive = [[WebArchive alloc] initWithData:[_private->dataSource data]];
+    WebResource *mainResource = [archive mainResource];
+    if (!mainResource) {
+        [archive release];
+        return;
+    }
+    
+    NSData *data = [mainResource data];
+    [data retain];
+    [_private->parsedArchiveData release];
+    _private->parsedArchiveData = data;
+    
+    [_private->dataSource _addToUnarchiveState:archive];
+    [archive release];
+    
+    WebFrame *webFrame = [_private->dataSource webFrame];
+    
+    if (!webFrame)
+        return;
+    
+    core(webFrame)->loader()->continueLoadWithData(SharedBuffer::wrapNSData(data).get(), [mainResource MIMEType], [mainResource textEncodingName], [mainResource URL]);
+}
+
+- (void)finishedLoadingWithDataSource:(WebDataSource *)dataSource
+{
+    WebFrame *frame = [dataSource webFrame];
+
+    if (_private->pluginView) {
+        [_private->manualLoader pluginViewFinishedLoading:_private->pluginView];
+        return;
+    }
+
+    if (frame) {
+        if ([self _isDisplayingWebArchive])
+            [self _loadDataSourceAsWebArchive];
+        else
+            // Telling the bridge we received some data and passing nil as the data is our
+            // way to get work done that is normally done when the first bit of data is
+            // received, even for the case of a document with no data (like about:blank).
+            [_private->bridge receivedData:nil textEncodingName:[[_private->dataSource response] textEncodingName]];
+        
+        WebView *webView = [frame webView];
+        if ([webView isEditable])
+            core(frame)->applyEditingStyleToBodyElement();
+    }
+}
+
+- (BOOL)canProvideDocumentSource
+{
+    return [_private->bridge canProvideDocumentSource];
+}
+
+- (BOOL)canSaveAsWebArchive
+{
+    return [_private->bridge canSaveAsWebArchive];
+}
+
+- (NSString *)documentSource
+{
+    if ([self _isDisplayingWebArchive])
+        return [[[NSString alloc] initWithData:_private->parsedArchiveData encoding:NSUTF8StringEncoding] autorelease]; 
+
+    return [_private->bridge stringWithData:[_private->dataSource data]];
+}
+
+- (NSString *)title
+{
+    return nsStringNilIfEmpty([_private->dataSource _documentLoader]->title());
+}
+
+- (DOMDocument *)DOMDocument
+{
+    return [[_private->bridge webFrame] DOMDocument];
+}
+
+- (NSAttributedString *)attributedText
+{
+    // FIXME: Implement
+    return nil;
+}
+
+- (NSAttributedString *)attributedStringFrom:(DOMNode *)startNode startOffset:(int)startOffset to:(DOMNode *)endNode endOffset:(int)endOffset
+{
+    Range range([startNode _node]->document(), [startNode _node], startOffset, [endNode _node], endOffset);
+    return [NSAttributedString _web_attributedStringFromRange:&range];
+}
+
+- (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form
+{
+    return [_private->bridge elementWithName:name inForm:form];
+}
+
+- (BOOL)elementDoesAutoComplete:(DOMElement *)element
+{
+    return [_private->bridge elementDoesAutoComplete:element];
+}
+
+- (BOOL)elementIsPassword:(DOMElement *)element
+{
+    return [_private->bridge elementIsPassword:element];
+}
+
+- (DOMElement *)formForElement:(DOMElement *)element
+{
+    return [_private->bridge formForElement:element];
+}
+
+- (DOMElement *)currentForm
+{
+    return [_private->bridge currentForm];
+}
+
+- (NSArray *)controlsInForm:(DOMElement *)form
+{
+    return [_private->bridge controlsInForm:form];
+}
+
+- (NSString *)searchForLabels:(NSArray *)labels beforeElement:(DOMElement *)element
+{
+    return [_private->bridge searchForLabels:labels beforeElement:element];
+}
+
+- (NSString *)matchLabels:(NSArray *)labels againstElement:(DOMElement *)element
+{
+    return [_private->bridge matchLabels:labels againstElement:element];
+}
+
+@end