--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/mac/Misc/WebNSPasteboardExtras.mm Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,298 @@
+/*
+ * 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 "WebNSPasteboardExtras.h"
+
+#import "DOMElementInternal.h"
+#import "WebArchive.h"
+#import "WebFrameInternal.h"
+#import "WebHTMLViewInternal.h"
+#import "WebNSURLExtras.h"
+#import "WebResourcePrivate.h"
+#import "WebURLsWithTitles.h"
+#import "WebViewPrivate.h"
+#import <WebCore/Element.h>
+#import <WebCore/Image.h>
+#import <WebCore/MIMETypeRegistry.h>
+#import <WebCore/RenderImage.h>
+#import <WebKit/DOMExtensions.h>
+#import <WebKit/DOMPrivate.h>
+#import <WebKitSystemInterface.h>
+#import <wtf/Assertions.h>
+#import <wtf/RetainPtr.h>
+#import <wtf/StdLibExtras.h>
+
+@interface NSFilePromiseDragSource : NSObject
+- (id)initWithSource:(id)draggingSource;
+- (void)setTypes:(NSArray *)types onPasteboard:(NSPasteboard *)pboard;
+@end
+
+using namespace WebCore;
+
+NSString *WebURLPboardType = @"public.url";
+NSString *WebURLNamePboardType = @"public.url-name";
+
+@implementation NSPasteboard (WebExtras)
+
++ (NSArray *)_web_writableTypesForURL
+{
+ DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, types, ([[NSArray alloc] initWithObjects:
+ WebURLsWithTitlesPboardType,
+ NSURLPboardType,
+ WebURLPboardType,
+ WebURLNamePboardType,
+ NSStringPboardType,
+ nil]));
+ return types.get();
+}
+
+static inline NSArray *_createWritableTypesForImageWithoutArchive()
+{
+ NSMutableArray *types = [[NSMutableArray alloc] initWithObjects:NSTIFFPboardType, nil];
+ [types addObjectsFromArray:[NSPasteboard _web_writableTypesForURL]];
+ return types;
+}
+
+static NSArray *_writableTypesForImageWithoutArchive (void)
+{
+ DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, types, (_createWritableTypesForImageWithoutArchive()));
+ return types.get();
+}
+
+static inline NSArray *_createWritableTypesForImageWithArchive()
+{
+ NSMutableArray *types = [_writableTypesForImageWithoutArchive() mutableCopy];
+ [types addObject:NSRTFDPboardType];
+ [types addObject:WebArchivePboardType];
+ return types;
+}
+
+static NSArray *_writableTypesForImageWithArchive (void)
+{
+ DEFINE_STATIC_LOCAL(RetainPtr<NSArray>, types, (_createWritableTypesForImageWithArchive()));
+ return types.get();
+}
+
++ (NSArray *)_web_writableTypesForImageIncludingArchive:(BOOL)hasArchive
+{
+ return hasArchive
+ ? _writableTypesForImageWithArchive()
+ : _writableTypesForImageWithoutArchive();
+}
+
++ (NSArray *)_web_dragTypesForURL
+{
+ return [NSArray arrayWithObjects:
+ WebURLsWithTitlesPboardType,
+ NSURLPboardType,
+ WebURLPboardType,
+ WebURLNamePboardType,
+ NSStringPboardType,
+ NSFilenamesPboardType,
+ nil];
+}
+
+- (NSURL *)_web_bestURL
+{
+ NSArray *types = [self types];
+
+ if ([types containsObject:NSURLPboardType]) {
+ NSURL *URLFromPasteboard = [NSURL URLFromPasteboard:self];
+ NSString *scheme = [URLFromPasteboard scheme];
+ if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) {
+ return [URLFromPasteboard _webkit_canonicalize];
+ }
+ }
+
+ if ([types containsObject:NSStringPboardType]) {
+ NSString *URLString = [self stringForType:NSStringPboardType];
+ if ([URLString _webkit_looksLikeAbsoluteURL]) {
+ NSURL *URL = [[NSURL _web_URLWithUserTypedString:URLString] _webkit_canonicalize];
+ if (URL) {
+ return URL;
+ }
+ }
+ }
+
+ if ([types containsObject:NSFilenamesPboardType]) {
+ NSArray *files = [self propertyListForType:NSFilenamesPboardType];
+ // FIXME: Maybe it makes more sense to allow multiple files and only use the first one?
+ if ([files count] == 1) {
+ NSString *file = [files objectAtIndex:0];
+ // FIXME: We are filtering out directories because that's what the original code used to
+ // do. Without this check, if the URL points to a local directory, Safari will open the
+ // parent directory of the directory in Finder. This check should go away as soon as
+ // possible.
+ BOOL isDirectory;
+ if ([[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory] && isDirectory)
+ return nil;
+ return [[NSURL fileURLWithPath:file] _webkit_canonicalize];
+ }
+ }
+
+ return nil;
+}
+
+- (void)_web_writeURL:(NSURL *)URL andTitle:(NSString *)title types:(NSArray *)types
+{
+ ASSERT(URL);
+
+ if ([title length] == 0) {
+ title = [[URL path] lastPathComponent];
+ if ([title length] == 0)
+ title = [URL _web_userVisibleString];
+ }
+
+ if ([types containsObject:NSURLPboardType])
+ [URL writeToPasteboard:self];
+ if ([types containsObject:WebURLPboardType])
+ [self setString:[URL _web_originalDataAsString] forType:WebURLPboardType];
+ if ([types containsObject:WebURLNamePboardType])
+ [self setString:title forType:WebURLNamePboardType];
+ if ([types containsObject:NSStringPboardType])
+ [self setString:[URL _web_userVisibleString] forType:NSStringPboardType];
+ if ([types containsObject:WebURLsWithTitlesPboardType])
+ [WebURLsWithTitles writeURLs:[NSArray arrayWithObject:URL] andTitles:[NSArray arrayWithObject:title] toPasteboard:self];
+}
+
++ (int)_web_setFindPasteboardString:(NSString *)string withOwner:(id)owner
+{
+ NSPasteboard *findPasteboard = [NSPasteboard pasteboardWithName:NSFindPboard];
+ [findPasteboard declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:owner];
+ [findPasteboard setString:string forType:NSStringPboardType];
+ return [findPasteboard changeCount];
+}
+
+- (void)_web_writeFileWrapperAsRTFDAttachment:(NSFileWrapper *)wrapper
+{
+ NSTextAttachment *attachment = [[NSTextAttachment alloc] initWithFileWrapper:wrapper];
+
+ NSAttributedString *string = [NSAttributedString attributedStringWithAttachment:attachment];
+ [attachment release];
+
+ NSData *RTFDData = [string RTFDFromRange:NSMakeRange(0, [string length]) documentAttributes:nil];
+ [self setData:RTFDData forType:NSRTFDPboardType];
+}
+
+
+- (void)_web_writePromisedRTFDFromArchive:(WebArchive*)archive containsImage:(BOOL)containsImage
+{
+ ASSERT(archive);
+ // This image data is either the only subresource of an archive (HTML image case)
+ // or the main resource (standalone image case).
+ NSArray *subresources = [archive subresources];
+ WebResource *resource = [archive mainResource];
+ if (containsImage && [subresources count] > 0
+ && MIMETypeRegistry::isSupportedImageResourceMIMEType([[subresources objectAtIndex:0] MIMEType]))
+ resource = (WebResource *)[subresources objectAtIndex:0];
+ ASSERT(resource != nil);
+
+ ASSERT(!containsImage || MIMETypeRegistry::isSupportedImageResourceMIMEType([resource MIMEType]));
+ if (!containsImage || MIMETypeRegistry::isSupportedImageResourceMIMEType([resource MIMEType]))
+ [self _web_writeFileWrapperAsRTFDAttachment:[resource _fileWrapperRepresentation]];
+
+}
+
+static CachedImage* imageFromElement(DOMElement *domElement)
+{
+ Element* element = core(domElement);
+ if (!element)
+ return 0;
+
+ RenderObject* renderer = element->renderer();
+ RenderImage* imageRenderer = toRenderImage(renderer);
+ if (!imageRenderer->cachedImage() || imageRenderer->cachedImage()->errorOccurred())
+ return 0;
+ return imageRenderer->cachedImage();
+}
+
+- (void)_web_writeImage:(NSImage *)image
+ element:(DOMElement *)element
+ URL:(NSURL *)URL
+ title:(NSString *)title
+ archive:(WebArchive *)archive
+ types:(NSArray *)types
+ source:(WebHTMLView *)source
+{
+ ASSERT(image || element);
+ ASSERT(URL);
+
+ [self _web_writeURL:URL andTitle:title types:types];
+
+ if ([types containsObject:NSTIFFPboardType]) {
+ if (image)
+ [self setData:[image TIFFRepresentation] forType:NSTIFFPboardType];
+ else if (source && element)
+ [source setPromisedDragTIFFDataSource:imageFromElement(element)];
+ else if (element)
+ [self setData:[element _imageTIFFRepresentation] forType:NSTIFFPboardType];
+ }
+
+ if (archive)
+ if ([types containsObject:WebArchivePboardType])
+ [self setData:[archive data] forType:WebArchivePboardType];
+ else {
+ // We should not have declared types that we aren't going to write (4031826).
+ ASSERT(![types containsObject:NSRTFDPboardType]);
+ ASSERT(![types containsObject:WebArchivePboardType]);
+ }
+}
+
+- (id)_web_declareAndWriteDragImageForElement:(DOMElement *)element
+ URL:(NSURL *)URL
+ title:(NSString *)title
+ archive:(WebArchive *)archive
+ source:(WebHTMLView *)source
+{
+ ASSERT(self == [NSPasteboard pasteboardWithName:NSDragPboard]);
+
+ NSString *extension = @"";
+ if (RenderObject* renderer = core(element)->renderer()) {
+ if (renderer->isImage()) {
+ if (CachedImage* image = toRenderImage(renderer)->cachedImage()) {
+ extension = image->image()->filenameExtension();
+ if (![extension length])
+ return 0;
+ }
+ }
+ }
+
+ NSMutableArray *types = [[NSMutableArray alloc] initWithObjects:NSFilesPromisePboardType, nil];
+ [types addObjectsFromArray:[NSPasteboard _web_writableTypesForImageIncludingArchive:(archive != nil)]];
+ [self declareTypes:types owner:source];
+ [self _web_writeImage:nil element:element URL:URL title:title archive:archive types:types source:source];
+ [types release];
+
+ NSArray *extensions = [[NSArray alloc] initWithObjects:extension, nil];
+ [self setPropertyList:extensions forType:NSFilesPromisePboardType];
+ [extensions release];
+
+ return source;
+}
+
+@end