diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/Misc/WebNSPasteboardExtras.mm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/Misc/WebNSPasteboardExtras.mm Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,282 @@ +/* + * 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 "WebArchive.h" +#import "WebFrameBridge.h" +#import "WebFrameInternal.h" +#import "WebHTMLViewInternal.h" +#import "WebNSURLExtras.h" +#import "WebResourcePrivate.h" +#import "WebURLsWithTitles.h" +#import "WebViewPrivate.h" +#import +#import +#import +#import +#import +#import +#import +#import + +@interface NSFilePromiseDragSource : NSObject +- 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 +{ + static RetainPtr types; + if (!types) { + types = [[NSArray alloc] initWithObjects: + WebURLsWithTitlesPboardType, + NSURLPboardType, + WebURLPboardType, + WebURLNamePboardType, + NSStringPboardType, + nil]; + } + return types.get(); +} + +static NSArray *_writableTypesForImageWithoutArchive (void) +{ + static RetainPtr types; + if (types == nil) { + types = [[NSMutableArray alloc] initWithObjects:NSTIFFPboardType, nil]; + [types.get() addObjectsFromArray:[NSPasteboard _web_writableTypesForURL]]; + } + return types.get(); +} + +static NSArray *_writableTypesForImageWithArchive (void) +{ + static RetainPtr types; + if (types == nil) { + types = [_writableTypesForImageWithoutArchive() mutableCopy]; + [types.get() addObject:NSRTFDPboardType]; + [types.get() addObject:WebArchivePboardType]; + } + 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]; + if ([files count] == 1) { + NSString *file = [files objectAtIndex:0]; + BOOL isDirectory; + if([[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory] && !isDirectory){ + 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]]; + +} + +CachedImage* imageFromElement(DOMElement *domElement) { + Element* element = core(domElement); + if (!element) + return 0; + + RenderObject* renderer = element->renderer(); + RenderImage* imageRenderer = static_cast(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]); + + 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]; + + NSString *extension = @""; + if (RenderObject* renderer = core(element)->renderer()) + if (renderer->isImage()) + if (CachedImage* image = static_cast(renderer)->cachedImage()) + extension = WKGetPreferredExtensionForMIMEType(image->response().mimeType()); + + NSArray *extensions = [[NSArray alloc] initWithObjects:extension, nil]; + [self setPropertyList:extensions forType:NSFilesPromisePboardType]; + [extensions release]; + + return source; +} + +@end