blob: 3e3cf1c47d3a0bd06ae8f0184cc770ade4e30cca [file] [log] [blame]
/*
* Copyright (C) 2005, 2006, 2007 Apple, Inc. All rights reserved.
* (C) 2007 Graham Dennis (graham.dennis@gmail.com)
* (C) 2007 Eric Seidel <eric@webkit.org>
*
* 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.
*/
//
// This file comes from WebKit:
// WebKit/Tools/DumpRenderTree/mac/DumpRenderTreePasteboard.m
// It is copied here since that location is the best for pulling into Chromium
// and has a few includes commented out. darin@chromium.org suggests in the
// future we see if there is a better place for it to live so it could be
// shared.
//
// #import "DumpRenderTreeMac.h"
#import "DumpRenderTreePasteboard.h"
// #import <WebKit/WebTypesInternal.h>
@interface LocalPasteboard : NSPasteboard
{
NSMutableArray *typesArray;
NSMutableSet *typesSet;
NSMutableDictionary *dataByType;
NSInteger changeCount;
}
@end
static NSMutableDictionary *localPasteboards;
@implementation DumpRenderTreePasteboard
// Return a local pasteboard so we don't disturb the real pasteboards when running tests.
+ (NSPasteboard *)_pasteboardWithName:(NSString *)name
{
static int number = 0;
if (!name)
name = [NSString stringWithFormat:@"LocalPasteboard%d", ++number];
if (!localPasteboards)
localPasteboards = [[NSMutableDictionary alloc] init];
LocalPasteboard *pasteboard = [localPasteboards objectForKey:name];
if (pasteboard)
return pasteboard;
pasteboard = [[LocalPasteboard alloc] init];
[localPasteboards setObject:pasteboard forKey:name];
[pasteboard release];
return pasteboard;
}
+ (void)releaseLocalPasteboards
{
[localPasteboards release];
localPasteboards = nil;
}
// Convenience method for JS so that it doesn't have to try and create a NSArray on the objc side instead
// of the usual WebScriptObject that is passed around
- (NSInteger)declareType:(NSString *)type owner:(id)newOwner
{
return [self declareTypes:[NSArray arrayWithObject:type] owner:newOwner];
}
@end
@implementation LocalPasteboard
+ (id)alloc
{
return NSAllocateObject(self, 0, 0);
}
- (id)init
{
typesArray = [[NSMutableArray alloc] init];
typesSet = [[NSMutableSet alloc] init];
dataByType = [[NSMutableDictionary alloc] init];
return self;
}
- (void)dealloc
{
[typesArray release];
[typesSet release];
[dataByType release];
[super dealloc];
}
- (NSString *)name
{
return nil;
}
- (void)releaseGlobally
{
}
- (NSInteger)declareTypes:(NSArray *)newTypes owner:(id)newOwner
{
[typesArray removeAllObjects];
[typesSet removeAllObjects];
[dataByType removeAllObjects];
return [self addTypes:newTypes owner:newOwner];
}
- (NSInteger)addTypes:(NSArray *)newTypes owner:(id)newOwner
{
unsigned count = [newTypes count];
unsigned i;
for (i = 0; i < count; ++i) {
NSString *type = [newTypes objectAtIndex:i];
NSString *setType = [typesSet member:type];
if (!setType) {
setType = [type copy];
[typesArray addObject:setType];
[typesSet addObject:setType];
[setType release];
}
if (newOwner && [newOwner respondsToSelector:@selector(pasteboard:provideDataForType:)])
[newOwner pasteboard:self provideDataForType:setType];
}
return ++changeCount;
}
- (NSInteger)changeCount
{
return changeCount;
}
- (NSArray *)types
{
return typesArray;
}
- (NSString *)availableTypeFromArray:(NSArray *)types
{
unsigned count = [types count];
unsigned i;
for (i = 0; i < count; ++i) {
NSString *type = [types objectAtIndex:i];
NSString *setType = [typesSet member:type];
if (setType)
return setType;
}
return nil;
}
- (BOOL)setData:(NSData *)data forType:(NSString *)dataType
{
if (data == nil)
data = [NSData data];
if (![typesSet containsObject:dataType])
return NO;
[dataByType setObject:data forKey:dataType];
++changeCount;
return YES;
}
- (NSData *)dataForType:(NSString *)dataType
{
return [dataByType objectForKey:dataType];
}
- (BOOL)setPropertyList:(id)propertyList forType:(NSString *)dataType
{
CFDataRef data = NULL;
if (propertyList)
data = CFPropertyListCreateXMLData(NULL, propertyList);
BOOL result = [self setData:(NSData *)data forType:dataType];
if (data)
CFRelease(data);
return result;
}
- (BOOL)setString:(NSString *)string forType:(NSString *)dataType
{
CFDataRef data = NULL;
if (string) {
if ([string length] == 0)
data = CFDataCreate(NULL, NULL, 0);
else
data = CFStringCreateExternalRepresentation(NULL, (CFStringRef)string, kCFStringEncodingUTF8, 0);
}
BOOL result = [self setData:(NSData *)data forType:dataType];
if (data)
CFRelease(data);
return result;
}
@end